summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordlg <>2019-01-22 00:59:21 +0000
committerdlg <>2019-01-22 00:59:21 +0000
commit314b0e719f69f4ef7811d81c9346e1b71bdef302 (patch)
tree87d28e1c4d3807293ec30dc5c24e43dccbe80302
parent6b5710cca200592904a2f0474264ab1e06d1d1dc (diff)
downloadopenbsd-314b0e719f69f4ef7811d81c9346e1b71bdef302.tar.gz
openbsd-314b0e719f69f4ef7811d81c9346e1b71bdef302.tar.bz2
openbsd-314b0e719f69f4ef7811d81c9346e1b71bdef302.zip
add support for xchacha20 and xchacha20-poly1305
xchacha is a chacha stream that allows for an extended nonce, which in turn makes it feasible to use random nonces. ok tb@
-rw-r--r--src/lib/libcrypto/Symbols.list3
-rw-r--r--src/lib/libcrypto/chacha/chacha-merged.c48
-rw-r--r--src/lib/libcrypto/chacha/chacha.c12
-rw-r--r--src/lib/libcrypto/chacha/chacha.h6
-rw-r--r--src/lib/libcrypto/evp/e_chacha20poly1305.c123
-rw-r--r--src/lib/libcrypto/evp/evp.h4
-rw-r--r--src/lib/libcrypto/man/EVP_AEAD_CTX_init.320
-rw-r--r--src/regress/lib/libcrypto/aead/aeadtest.c11
-rw-r--r--src/regress/lib/libcrypto/aead/aeadtests.txt11
-rw-r--r--src/regress/lib/libcrypto/chacha/chachatest.c172
10 files changed, 399 insertions, 11 deletions
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 4836a3ff9f..d367b93cd4 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -667,6 +667,7 @@ CRYPTO_get_mem_ex_functions
667CRYPTO_get_mem_functions 667CRYPTO_get_mem_functions
668CRYPTO_get_new_dynlockid 668CRYPTO_get_new_dynlockid
669CRYPTO_get_new_lockid 669CRYPTO_get_new_lockid
670CRYPTO_hchacha_20
670CRYPTO_is_mem_check_on 671CRYPTO_is_mem_check_on
671CRYPTO_lock 672CRYPTO_lock
672CRYPTO_malloc 673CRYPTO_malloc
@@ -708,6 +709,7 @@ CRYPTO_set_mem_ex_functions
708CRYPTO_set_mem_functions 709CRYPTO_set_mem_functions
709CRYPTO_strdup 710CRYPTO_strdup
710CRYPTO_thread_id 711CRYPTO_thread_id
712CRYPTO_xchacha_20
711CRYPTO_xts128_encrypt 713CRYPTO_xts128_encrypt
712Camellia_cbc_encrypt 714Camellia_cbc_encrypt
713Camellia_cfb128_encrypt 715Camellia_cfb128_encrypt
@@ -1493,6 +1495,7 @@ EVP_add_digest
1493EVP_aead_aes_128_gcm 1495EVP_aead_aes_128_gcm
1494EVP_aead_aes_256_gcm 1496EVP_aead_aes_256_gcm
1495EVP_aead_chacha20_poly1305 1497EVP_aead_chacha20_poly1305
1498EVP_aead_xchacha20_poly1305
1496EVP_aes_128_cbc 1499EVP_aes_128_cbc
1497EVP_aes_128_cbc_hmac_sha1 1500EVP_aes_128_cbc_hmac_sha1
1498EVP_aes_128_ccm 1501EVP_aes_128_ccm
diff --git a/src/lib/libcrypto/chacha/chacha-merged.c b/src/lib/libcrypto/chacha/chacha-merged.c
index 08511ed273..67508f208d 100644
--- a/src/lib/libcrypto/chacha/chacha-merged.c
+++ b/src/lib/libcrypto/chacha/chacha-merged.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: chacha-merged.c,v 1.8 2017/08/13 16:55:31 jsing Exp $ */ 1/* $OpenBSD: chacha-merged.c,v 1.9 2019/01/22 00:59:21 dlg Exp $ */
2/* 2/*
3chacha-merged.c version 20080118 3chacha-merged.c version 20080118
4D. J. Bernstein 4D. J. Bernstein
@@ -277,3 +277,49 @@ chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
277 m += 64; 277 m += 64;
278 } 278 }
279} 279}
280
281void
282CRYPTO_hchacha_20(unsigned char subkey[32], const unsigned char key[32],
283 const unsigned char nonce[16])
284{
285 uint32_t x[16];
286 int i;
287
288 x[0] = U8TO32_LITTLE(sigma + 0);
289 x[1] = U8TO32_LITTLE(sigma + 4);
290 x[2] = U8TO32_LITTLE(sigma + 8);
291 x[3] = U8TO32_LITTLE(sigma + 12);
292 x[4] = U8TO32_LITTLE(key + 0);
293 x[5] = U8TO32_LITTLE(key + 4);
294 x[6] = U8TO32_LITTLE(key + 8);
295 x[7] = U8TO32_LITTLE(key + 12);
296 x[8] = U8TO32_LITTLE(key + 16);
297 x[9] = U8TO32_LITTLE(key + 20);
298 x[10] = U8TO32_LITTLE(key + 24);
299 x[11] = U8TO32_LITTLE(key + 28);
300 x[12] = U8TO32_LITTLE(nonce + 0);
301 x[13] = U8TO32_LITTLE(nonce + 4);
302 x[14] = U8TO32_LITTLE(nonce + 8);
303 x[15] = U8TO32_LITTLE(nonce + 12);
304
305 for (i = 20; i > 0; i -= 2) {
306 QUARTERROUND(x[0], x[4], x[8], x[12])
307 QUARTERROUND(x[1], x[5], x[9], x[13])
308 QUARTERROUND(x[2], x[6], x[10], x[14])
309 QUARTERROUND(x[3], x[7], x[11], x[15])
310 QUARTERROUND(x[0], x[5], x[10], x[15])
311 QUARTERROUND(x[1], x[6], x[11], x[12])
312 QUARTERROUND(x[2], x[7], x[8], x[13])
313 QUARTERROUND(x[3], x[4], x[9], x[14])
314 }
315
316 U32TO8_LITTLE(subkey + 0, x[0]);
317 U32TO8_LITTLE(subkey + 4, x[1]);
318 U32TO8_LITTLE(subkey + 8, x[2]);
319 U32TO8_LITTLE(subkey + 12, x[3]);
320
321 U32TO8_LITTLE(subkey + 16, x[12]);
322 U32TO8_LITTLE(subkey + 20, x[13]);
323 U32TO8_LITTLE(subkey + 24, x[14]);
324 U32TO8_LITTLE(subkey + 28, x[15]);
325}
diff --git a/src/lib/libcrypto/chacha/chacha.c b/src/lib/libcrypto/chacha/chacha.c
index 0c384ab88a..6a2dddf055 100644
--- a/src/lib/libcrypto/chacha/chacha.c
+++ b/src/lib/libcrypto/chacha/chacha.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: chacha.c,v 1.7 2015/12/09 14:07:55 bcook Exp $ */ 1/* $OpenBSD: chacha.c,v 1.8 2019/01/22 00:59:21 dlg Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -75,3 +75,13 @@ CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
75 75
76 chacha_encrypt_bytes(&ctx, in, out, (uint32_t)len); 76 chacha_encrypt_bytes(&ctx, in, out, (uint32_t)len);
77} 77}
78
79void
80CRYPTO_xchacha_20(unsigned char *out, const unsigned char *in, size_t len,
81 const unsigned char key[32], const unsigned char iv[24])
82{
83 uint8_t subkey[32];
84
85 CRYPTO_hchacha_20(subkey, key, iv);
86 CRYPTO_chacha_20(out, in, len, subkey, iv + 16, 0);
87}
diff --git a/src/lib/libcrypto/chacha/chacha.h b/src/lib/libcrypto/chacha/chacha.h
index 8d94e626f8..e2345b2199 100644
--- a/src/lib/libcrypto/chacha/chacha.h
+++ b/src/lib/libcrypto/chacha/chacha.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: chacha.h,v 1.7 2015/12/09 14:07:55 bcook Exp $ */ 1/* $OpenBSD: chacha.h,v 1.8 2019/01/22 00:59:21 dlg Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -46,6 +46,10 @@ void ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in,
46 46
47void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len, 47void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
48 const unsigned char key[32], const unsigned char iv[8], uint64_t counter); 48 const unsigned char key[32], const unsigned char iv[8], uint64_t counter);
49void CRYPTO_xchacha_20(unsigned char *out, const unsigned char *in, size_t len,
50 const unsigned char key[32], const unsigned char iv[24]);
51void CRYPTO_hchacha_20(unsigned char out[32],
52 const unsigned char key[32], const unsigned char iv[16]);
49 53
50#ifdef __cplusplus 54#ifdef __cplusplus
51} 55}
diff --git a/src/lib/libcrypto/evp/e_chacha20poly1305.c b/src/lib/libcrypto/evp/e_chacha20poly1305.c
index 089ef12fb3..a5cf8a19f2 100644
--- a/src/lib/libcrypto/evp/e_chacha20poly1305.c
+++ b/src/lib/libcrypto/evp/e_chacha20poly1305.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: e_chacha20poly1305.c,v 1.18 2017/08/28 17:48:02 jsing Exp $ */ 1/* $OpenBSD: e_chacha20poly1305.c,v 1.19 2019/01/22 00:59:21 dlg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org> 4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
@@ -36,6 +36,7 @@
36#define CHACHA20_CONSTANT_LEN 4 36#define CHACHA20_CONSTANT_LEN 4
37#define CHACHA20_IV_LEN 8 37#define CHACHA20_IV_LEN 8
38#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN) 38#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
39#define XCHACHA20_NONCE_LEN 24
39 40
40struct aead_chacha20_poly1305_ctx { 41struct aead_chacha20_poly1305_ctx {
41 unsigned char key[32]; 42 unsigned char key[32];
@@ -246,6 +247,108 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
246 return 1; 247 return 1;
247} 248}
248 249
250static int
251aead_xchacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
252 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
253 size_t nonce_len, const unsigned char *in, size_t in_len,
254 const unsigned char *ad, size_t ad_len)
255{
256 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
257 unsigned char poly1305_key[32];
258 unsigned char subkey[32];
259 poly1305_state poly1305;
260
261 if (max_out_len < in_len + c20_ctx->tag_len) {
262 EVPerror(EVP_R_BUFFER_TOO_SMALL);
263 return 0;
264 }
265
266 if (nonce_len != ctx->aead->nonce_len) {
267 EVPerror(EVP_R_IV_TOO_LARGE);
268 return 0;
269 }
270
271 CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
272
273 CRYPTO_chacha_20(out, in, in_len, subkey, nonce + 16, 1);
274
275 memset(poly1305_key, 0, sizeof(poly1305_key));
276 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
277 subkey, nonce + 16, 0);
278
279 CRYPTO_poly1305_init(&poly1305, poly1305_key);
280 poly1305_update_with_pad16(&poly1305, ad, ad_len);
281 poly1305_update_with_pad16(&poly1305, out, in_len);
282 poly1305_update_with_length(&poly1305, NULL, ad_len);
283 poly1305_update_with_length(&poly1305, NULL, in_len);
284
285 if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
286 unsigned char tag[POLY1305_TAG_LEN];
287 CRYPTO_poly1305_finish(&poly1305, tag);
288 memcpy(out + in_len, tag, c20_ctx->tag_len);
289 *out_len = in_len + c20_ctx->tag_len;
290 return 1;
291 }
292
293 CRYPTO_poly1305_finish(&poly1305, out + in_len);
294 *out_len = in_len + POLY1305_TAG_LEN;
295 return 1;
296}
297
298static int
299aead_xchacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
300 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
301 size_t nonce_len, const unsigned char *in, size_t in_len,
302 const unsigned char *ad, size_t ad_len)
303{
304 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
305 unsigned char mac[POLY1305_TAG_LEN];
306 unsigned char poly1305_key[32];
307 unsigned char subkey[32];
308 poly1305_state poly1305;
309 size_t plaintext_len;
310
311 if (in_len < c20_ctx->tag_len) {
312 EVPerror(EVP_R_BAD_DECRYPT);
313 return 0;
314 }
315
316 if (nonce_len != ctx->aead->nonce_len) {
317 EVPerror(EVP_R_IV_TOO_LARGE);
318 return 0;
319 }
320
321 plaintext_len = in_len - c20_ctx->tag_len;
322
323 if (max_out_len < plaintext_len) {
324 EVPerror(EVP_R_BUFFER_TOO_SMALL);
325 return 0;
326 }
327
328 CRYPTO_hchacha_20(subkey, c20_ctx->key, nonce);
329
330 memset(poly1305_key, 0, sizeof(poly1305_key));
331 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
332 subkey, nonce + 16, 0);
333
334 CRYPTO_poly1305_init(&poly1305, poly1305_key);
335 poly1305_update_with_pad16(&poly1305, ad, ad_len);
336 poly1305_update_with_pad16(&poly1305, in, plaintext_len);
337 poly1305_update_with_length(&poly1305, NULL, ad_len);
338 poly1305_update_with_length(&poly1305, NULL, plaintext_len);
339
340 CRYPTO_poly1305_finish(&poly1305, mac);
341 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
342 EVPerror(EVP_R_BAD_DECRYPT);
343 return 0;
344 }
345
346 CRYPTO_chacha_20(out, in, plaintext_len, subkey, nonce + 16, 1);
347
348 *out_len = plaintext_len;
349 return 1;
350}
351
249/* RFC 7539 */ 352/* RFC 7539 */
250static const EVP_AEAD aead_chacha20_poly1305 = { 353static const EVP_AEAD aead_chacha20_poly1305 = {
251 .key_len = 32, 354 .key_len = 32,
@@ -265,4 +368,22 @@ EVP_aead_chacha20_poly1305()
265 return &aead_chacha20_poly1305; 368 return &aead_chacha20_poly1305;
266} 369}
267 370
371static const EVP_AEAD aead_xchacha20_poly1305 = {
372 .key_len = 32,
373 .nonce_len = XCHACHA20_NONCE_LEN,
374 .overhead = POLY1305_TAG_LEN,
375 .max_tag_len = POLY1305_TAG_LEN,
376
377 .init = aead_chacha20_poly1305_init,
378 .cleanup = aead_chacha20_poly1305_cleanup,
379 .seal = aead_xchacha20_poly1305_seal,
380 .open = aead_xchacha20_poly1305_open,
381};
382
383const EVP_AEAD *
384EVP_aead_xchacha20_poly1305()
385{
386 return &aead_xchacha20_poly1305;
387}
388
268#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ 389#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 35f2b3281b..0645303686 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp.h,v 1.71 2019/01/19 01:24:18 tb Exp $ */ 1/* $OpenBSD: evp.h,v 1.72 2019/01/22 00:59:21 dlg Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -1243,6 +1243,8 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void);
1243#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 1243#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1244/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ 1244/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */
1245const EVP_AEAD *EVP_aead_chacha20_poly1305(void); 1245const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
1246/* EVP_aead_xchacha20_poly1305 is XChaCha20 with a Poly1305 authenticator. */
1247const EVP_AEAD *EVP_aead_xchacha20_poly1305(void);
1246#endif 1248#endif
1247 1249
1248/* EVP_AEAD_key_length returns the length of the keys used. */ 1250/* EVP_AEAD_key_length returns the length of the keys used. */
diff --git a/src/lib/libcrypto/man/EVP_AEAD_CTX_init.3 b/src/lib/libcrypto/man/EVP_AEAD_CTX_init.3
index debcc773c4..a4d759a2ed 100644
--- a/src/lib/libcrypto/man/EVP_AEAD_CTX_init.3
+++ b/src/lib/libcrypto/man/EVP_AEAD_CTX_init.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.6 2017/08/28 17:43:43 jsing Exp $ 1.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.7 2019/01/22 00:59:21 dlg Exp $
2.\" 2.\"
3.\" Copyright (c) 2014, Google Inc. 3.\" Copyright (c) 2014, Google Inc.
4.\" Parts of the text were written by Adam Langley and David Benjamin. 4.\" Parts of the text were written by Adam Langley and David Benjamin.
@@ -16,7 +16,7 @@
16.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18.\" 18.\"
19.Dd $Mdocdate: August 28 2017 $ 19.Dd $Mdocdate: January 22 2019 $
20.Dt EVP_AEAD_CTX_INIT 3 20.Dt EVP_AEAD_CTX_INIT 3
21.Os 21.Os
22.Sh NAME 22.Sh NAME
@@ -30,7 +30,8 @@
30.Nm EVP_AEAD_nonce_length , 30.Nm EVP_AEAD_nonce_length ,
31.Nm EVP_aead_aes_128_gcm , 31.Nm EVP_aead_aes_128_gcm ,
32.Nm EVP_aead_aes_256_gcm , 32.Nm EVP_aead_aes_256_gcm ,
33.Nm EVP_aead_chacha20_poly1305 33.Nm EVP_aead_chacha20_poly1305,
34.Nm EVP_aead_xchacha20_poly1305
34.Nd authenticated encryption with additional data 35.Nd authenticated encryption with additional data
35.Sh SYNOPSIS 36.Sh SYNOPSIS
36.In openssl/evp.h 37.In openssl/evp.h
@@ -101,6 +102,10 @@
101.Fo EVP_aead_chacha20_poly1305 102.Fo EVP_aead_chacha20_poly1305
102.Fa void 103.Fa void
103.Fc 104.Fc
105.Ft const EVP_AEAD *
106.Fo EVP_aead_xchacha20_poly1305
107.Fa void
108.Fc
104.Sh DESCRIPTION 109.Sh DESCRIPTION
105AEAD (Authenticated Encryption with Additional Data) couples 110AEAD (Authenticated Encryption with Additional Data) couples
106confidentiality and integrity in a single primitive. 111confidentiality and integrity in a single primitive.
@@ -219,6 +224,8 @@ AES-128 in Galois Counter Mode.
219AES-256 in Galois Counter Mode. 224AES-256 in Galois Counter Mode.
220.It Fn EVP_aead_chacha20_poly1305 225.It Fn EVP_aead_chacha20_poly1305
221ChaCha20 with a Poly1305 authenticator. 226ChaCha20 with a Poly1305 authenticator.
227.It Fn EVP_aead_xchacha20_poly1305
228XChaCha20 with a Poly1305 authenticator.
222.El 229.El
223.Pp 230.Pp
224Where possible the 231Where possible the
@@ -285,6 +292,13 @@ EVP_AEAD_CTX_cleanup(&ctx);
285.%R RFC 7539 292.%R RFC 7539
286.%T ChaCha20 and Poly1305 for IETF Protocols 293.%T ChaCha20 and Poly1305 for IETF Protocols
287.Re 294.Re
295.Pp
296.Rs
297.%A S. Arciszewski
298.%D October 2018
299.%R draft-arciszewski-xchacha-02
300.%T XChaCha: eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305
301.Re
288.Sh HISTORY 302.Sh HISTORY
289AEAD is based on the implementation by 303AEAD is based on the implementation by
290.An Adam Langley 304.An Adam Langley
diff --git a/src/regress/lib/libcrypto/aead/aeadtest.c b/src/regress/lib/libcrypto/aead/aeadtest.c
index 4f0ab9fa3a..1b144c2615 100644
--- a/src/regress/lib/libcrypto/aead/aeadtest.c
+++ b/src/regress/lib/libcrypto/aead/aeadtest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: aeadtest.c,v 1.11 2018/07/17 17:06:49 tb Exp $ */ 1/* $OpenBSD: aeadtest.c,v 1.12 2019/01/22 00:59:21 dlg Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -52,8 +52,11 @@
52#include <stdlib.h> 52#include <stdlib.h>
53#include <string.h> 53#include <string.h>
54#include <stdint.h> 54#include <stdint.h>
55#include <unistd.h>
56#include <ctype.h>
55 57
56#include <openssl/evp.h> 58#include <openssl/evp.h>
59#include <openssl/err.h>
57 60
58/* This program tests an AEAD against a series of test vectors from a file. The 61/* This program tests an AEAD against a series of test vectors from a file. The
59 * test vector file consists of key-value lines where the key and value are 62 * test vector file consists of key-value lines where the key and value are
@@ -135,6 +138,12 @@ aead_from_name(const EVP_AEAD **aead, const char *name)
135#else 138#else
136 fprintf(stderr, "No chacha20-poly1305 support.\n"); 139 fprintf(stderr, "No chacha20-poly1305 support.\n");
137#endif 140#endif
141 } else if (strcmp(name, "xchacha20-poly1305") == 0) {
142#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
143 *aead = EVP_aead_xchacha20_poly1305();
144#else
145 fprintf(stderr, "No xchacha20-poly1305 support.\n");
146#endif
138 } else { 147 } else {
139 fprintf(stderr, "Unknown AEAD: %s\n", name); 148 fprintf(stderr, "Unknown AEAD: %s\n", name);
140 return -1; 149 return -1;
diff --git a/src/regress/lib/libcrypto/aead/aeadtests.txt b/src/regress/lib/libcrypto/aead/aeadtests.txt
index 18cee7e579..4ca47303b2 100644
--- a/src/regress/lib/libcrypto/aead/aeadtests.txt
+++ b/src/regress/lib/libcrypto/aead/aeadtests.txt
@@ -1,4 +1,4 @@
1# $OpenBSD: aeadtests.txt,v 1.7 2018/07/17 17:06:49 tb Exp $ 1# $OpenBSD: aeadtests.txt,v 1.8 2019/01/22 00:59:21 dlg Exp $
2# 2#
3# MACsec GCM-AES Test Vectors (bn-randall-test-vectors-0511-v1.pdf) 3# MACsec GCM-AES Test Vectors (bn-randall-test-vectors-0511-v1.pdf)
4# 4#
@@ -75,3 +75,12 @@ AD: c0c1c2c3c4c5c6c7d0d1d2d3d4d5d6d72e202500000000090000004529000029
75CT: 610394701f8d017f7c12924889 75CT: 610394701f8d017f7c12924889
76TAG: 6b71bfe25236efd7cdc67066906315b2 76TAG: 6b71bfe25236efd7cdc67066906315b2
77 77
78# Test vector from draft-arciszewski-xchacha-02
79AEAD: xchacha20-poly1305
80KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
81NONCE: 404142434445464748494a4b4c4d4e4f5051525354555657
82IN: 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e
83AD: 50515253c0c1c2c3c4c5c6c7
84CT: bd6d179d3e83d43b9576579493c0e939572a1700252bfaccbed2902c21396cbb731c7f1b0b4aa6440bf3a82f4eda7e39ae64c6708c54c216cb96b72e1213b4522f8c9ba40db5d945b11b69b982c1bb9e3f3fac2bc369488f76b2383565d3fff921f9664c97637da9768812f615c68b13b52e
85TAG: c0875924c1c7987947deafd8780acf49
86
diff --git a/src/regress/lib/libcrypto/chacha/chachatest.c b/src/regress/lib/libcrypto/chacha/chachatest.c
index fe4cc40952..4e15974617 100644
--- a/src/regress/lib/libcrypto/chacha/chachatest.c
+++ b/src/regress/lib/libcrypto/chacha/chachatest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: chachatest.c,v 1.5 2018/07/17 17:06:49 tb Exp $ */ 1/* $OpenBSD: chachatest.c,v 1.6 2019/01/22 00:59:21 dlg Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -292,6 +292,170 @@ struct chacha_test_function chacha_test_functions[] = {
292 292
293#define N_FUNCS (sizeof(chacha_test_functions) / sizeof(*chacha_test_functions)) 293#define N_FUNCS (sizeof(chacha_test_functions) / sizeof(*chacha_test_functions))
294 294
295/* draft-arciszewski-xchacha-02 test vectors */
296static int
297crypto_hchacha_20_test(void)
298{
299 static const unsigned char key[32] = {
300 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
301 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
302 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
303 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
304 };
305 static const unsigned char nonce[16] = {
306 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a,
307 0x00, 0x00, 0x00, 0x00, 0x31, 0x41, 0x59, 0x27,
308 };
309 static const unsigned char result[32] = {
310 0x82, 0x41, 0x3b, 0x42, 0x27, 0xb2, 0x7b, 0xfe,
311 0xd3, 0x0e, 0x42, 0x50, 0x8a, 0x87, 0x7d, 0x73,
312 0xa0, 0xf9, 0xe4, 0xd5, 0x8a, 0x74, 0xa8, 0x53,
313 0xc1, 0x2e, 0xc4, 0x13, 0x26, 0xd3, 0xec, 0xdc,
314 };
315 unsigned char out[32];
316 int failed = 0;
317 size_t k;
318
319 CRYPTO_hchacha_20(out, key, nonce);
320
321 if (memcmp(out, result, sizeof(out)) != 0) {
322 printf("HChaCha20 failed!\n");
323
324 printf("Got:\t");
325 for (k = 0; k < sizeof(out); k++)
326 printf("%2.2x", out[k]);
327 printf("\n");
328
329 printf("Want:\t");
330 for (k = 0; k < sizeof(result); k++)
331 printf("%2.2x", result[k]);
332 printf("\n");
333
334 failed = 1;
335 }
336
337 return (failed);
338}
339
340static int
341crypto_xchacha_20_test(void)
342{
343 static const unsigned char key[32] = {
344 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
345 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
346 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
347 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
348 };
349 static const unsigned char iv[24] = {
350 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
351 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
352 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58
353 };
354 static const unsigned char plain[] = {
355 0x54, 0x68, 0x65, 0x20, 0x64, 0x68, 0x6f, 0x6c,
356 0x65, 0x20, 0x28, 0x70, 0x72, 0x6f, 0x6e, 0x6f,
357 0x75, 0x6e, 0x63, 0x65, 0x64, 0x20, 0x22, 0x64,
358 0x6f, 0x6c, 0x65, 0x22, 0x29, 0x20, 0x69, 0x73,
359 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x6b, 0x6e,
360 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x74,
361 0x68, 0x65, 0x20, 0x41, 0x73, 0x69, 0x61, 0x74,
362 0x69, 0x63, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x20,
363 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x72, 0x65, 0x64,
364 0x20, 0x64, 0x6f, 0x67, 0x2c, 0x20, 0x61, 0x6e,
365 0x64, 0x20, 0x77, 0x68, 0x69, 0x73, 0x74, 0x6c,
366 0x69, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x67, 0x2e,
367 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61,
368 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65,
369 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66,
370 0x20, 0x61, 0x20, 0x47, 0x65, 0x72, 0x6d, 0x61,
371 0x6e, 0x20, 0x73, 0x68, 0x65, 0x70, 0x68, 0x65,
372 0x72, 0x64, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6c,
373 0x6f, 0x6f, 0x6b, 0x73, 0x20, 0x6d, 0x6f, 0x72,
374 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61,
375 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x6c, 0x65,
376 0x67, 0x67, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x78,
377 0x2e, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x68,
378 0x69, 0x67, 0x68, 0x6c, 0x79, 0x20, 0x65, 0x6c,
379 0x75, 0x73, 0x69, 0x76, 0x65, 0x20, 0x61, 0x6e,
380 0x64, 0x20, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65,
381 0x64, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x65, 0x72,
382 0x20, 0x69, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x73,
383 0x73, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x77,
384 0x69, 0x74, 0x68, 0x20, 0x77, 0x6f, 0x6c, 0x76,
385 0x65, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x79, 0x6f,
386 0x74, 0x65, 0x73, 0x2c, 0x20, 0x6a, 0x61, 0x63,
387 0x6b, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x61, 0x6e,
388 0x64, 0x20, 0x66, 0x6f, 0x78, 0x65, 0x73, 0x20,
389 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
390 0x61, 0x78, 0x6f, 0x6e, 0x6f, 0x6d, 0x69, 0x63,
391 0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x20,
392 0x43, 0x61, 0x6e, 0x69, 0x64, 0x61, 0x65, 0x2e,
393 };
394 static const unsigned char cipher[] = {
395 0x45, 0x59, 0xab, 0xba, 0x4e, 0x48, 0xc1, 0x61,
396 0x02, 0xe8, 0xbb, 0x2c, 0x05, 0xe6, 0x94, 0x7f,
397 0x50, 0xa7, 0x86, 0xde, 0x16, 0x2f, 0x9b, 0x0b,
398 0x7e, 0x59, 0x2a, 0x9b, 0x53, 0xd0, 0xd4, 0xe9,
399 0x8d, 0x8d, 0x64, 0x10, 0xd5, 0x40, 0xa1, 0xa6,
400 0x37, 0x5b, 0x26, 0xd8, 0x0d, 0xac, 0xe4, 0xfa,
401 0xb5, 0x23, 0x84, 0xc7, 0x31, 0xac, 0xbf, 0x16,
402 0xa5, 0x92, 0x3c, 0x0c, 0x48, 0xd3, 0x57, 0x5d,
403 0x4d, 0x0d, 0x2c, 0x67, 0x3b, 0x66, 0x6f, 0xaa,
404 0x73, 0x10, 0x61, 0x27, 0x77, 0x01, 0x09, 0x3a,
405 0x6b, 0xf7, 0xa1, 0x58, 0xa8, 0x86, 0x42, 0x92,
406 0xa4, 0x1c, 0x48, 0xe3, 0xa9, 0xb4, 0xc0, 0xda,
407 0xec, 0xe0, 0xf8, 0xd9, 0x8d, 0x0d, 0x7e, 0x05,
408 0xb3, 0x7a, 0x30, 0x7b, 0xbb, 0x66, 0x33, 0x31,
409 0x64, 0xec, 0x9e, 0x1b, 0x24, 0xea, 0x0d, 0x6c,
410 0x3f, 0xfd, 0xdc, 0xec, 0x4f, 0x68, 0xe7, 0x44,
411 0x30, 0x56, 0x19, 0x3a, 0x03, 0xc8, 0x10, 0xe1,
412 0x13, 0x44, 0xca, 0x06, 0xd8, 0xed, 0x8a, 0x2b,
413 0xfb, 0x1e, 0x8d, 0x48, 0xcf, 0xa6, 0xbc, 0x0e,
414 0xb4, 0xe2, 0x46, 0x4b, 0x74, 0x81, 0x42, 0x40,
415 0x7c, 0x9f, 0x43, 0x1a, 0xee, 0x76, 0x99, 0x60,
416 0xe1, 0x5b, 0xa8, 0xb9, 0x68, 0x90, 0x46, 0x6e,
417 0xf2, 0x45, 0x75, 0x99, 0x85, 0x23, 0x85, 0xc6,
418 0x61, 0xf7, 0x52, 0xce, 0x20, 0xf9, 0xda, 0x0c,
419 0x09, 0xab, 0x6b, 0x19, 0xdf, 0x74, 0xe7, 0x6a,
420 0x95, 0x96, 0x74, 0x46, 0xf8, 0xd0, 0xfd, 0x41,
421 0x5e, 0x7b, 0xee, 0x2a, 0x12, 0xa1, 0x14, 0xc2,
422 0x0e, 0xb5, 0x29, 0x2a, 0xe7, 0xa3, 0x49, 0xae,
423 0x57, 0x78, 0x20, 0xd5, 0x52, 0x0a, 0x1f, 0x3f,
424 0xb6, 0x2a, 0x17, 0xce, 0x6a, 0x7e, 0x68, 0xfa,
425 0x7c, 0x79, 0x11, 0x1d, 0x88, 0x60, 0x92, 0x0b,
426 0xc0, 0x48, 0xef, 0x43, 0xfe, 0x84, 0x48, 0x6c,
427 0xcb, 0x87, 0xc2, 0x5f, 0x0a, 0xe0, 0x45, 0xf0,
428 0xcc, 0xe1, 0xe7, 0x98, 0x9a, 0x9a, 0xa2, 0x20,
429 0xa2, 0x8b, 0xdd, 0x48, 0x27, 0xe7, 0x51, 0xa2,
430 0x4a, 0x6d, 0x5c, 0x62, 0xd7, 0x90, 0xa6, 0x63,
431 0x93, 0xb9, 0x31, 0x11, 0xc1, 0xa5, 0x5d, 0xd7,
432 0x42, 0x1a, 0x10, 0x18, 0x49, 0x74, 0xc7, 0xc5,
433 };
434 unsigned char out[sizeof(cipher)];
435 int failed = 0;
436 size_t k;
437
438 CRYPTO_xchacha_20(out, plain, sizeof(out), key, iv);
439
440 if (memcmp(out, cipher, sizeof(out)) != 0) {
441 printf("XChaCha20 failed!\n");
442
443 printf("Got:\t");
444 for (k = 0; k < sizeof(out); k++)
445 printf("%2.2x", out[k]);
446 printf("\n");
447
448 printf("Want:\t");
449 for (k = 0; k < sizeof(cipher); k++)
450 printf("%2.2x", cipher[k]);
451 printf("\n");
452
453 failed = 1;
454 }
455
456 return (failed);
457}
458
295int 459int
296main(int argc, char **argv) 460main(int argc, char **argv)
297{ 461{
@@ -335,5 +499,11 @@ main(int argc, char **argv)
335 } 499 }
336 } 500 }
337 501
502 if (crypto_hchacha_20_test() != 0)
503 failed = 1;
504
505 if (crypto_xchacha_20_test() != 0)
506 failed = 1;
507
338 return failed; 508 return failed;
339} 509}