summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authordlg <>2019-01-22 00:59:21 +0000
committerdlg <>2019-01-22 00:59:21 +0000
commit314b0e719f69f4ef7811d81c9346e1b71bdef302 (patch)
tree87d28e1c4d3807293ec30dc5c24e43dccbe80302 /src/lib
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@
Diffstat (limited to 'src/lib')
-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
7 files changed, 208 insertions, 8 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