From 3e2680fbd9dc7657b729f24a677f5ec057643aa6 Mon Sep 17 00:00:00 2001 From: reyk <> Date: Mon, 2 Nov 2015 15:40:53 +0000 Subject: Add EVP_aead_chacha20_poly1305_ietf() - The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols", introduced a modified AEAD construction that is incompatible with the common style that has been already used in TLS with EVP_aead_chacha20_poly1305(). The IETF version also adds a constant (salt) that is prepended to the nonce. OK mikeb@ jsing@ --- src/lib/libcrypto/evp/e_chacha20poly1305.c | 129 ++++++++++++++++++--- src/lib/libcrypto/evp/evp.h | 3 +- src/lib/libcrypto/man/EVP_AEAD_CTX_init.3 | 33 +++++- src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c | 129 ++++++++++++++++++--- src/lib/libssl/src/crypto/evp/evp.h | 3 +- src/regress/lib/libcrypto/aead/aeadtest.c | 6 + src/regress/lib/libcrypto/aead/aeadtests.txt | 36 ++++++ 7 files changed, 298 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/lib/libcrypto/evp/e_chacha20poly1305.c b/src/lib/libcrypto/evp/e_chacha20poly1305.c index 9deb40b72a..47551c4578 100644 --- a/src/lib/libcrypto/evp/e_chacha20poly1305.c +++ b/src/lib/libcrypto/evp/e_chacha20poly1305.c @@ -1,5 +1,7 @@ -/* $OpenBSD: e_chacha20poly1305.c,v 1.10 2015/09/10 15:56:25 jsing Exp $ */ +/* $OpenBSD: e_chacha20poly1305.c,v 1.11 2015/11/02 15:40:53 reyk Exp $ */ + /* + * Copyright (c) 2015 Reyk Floter * Copyright (c) 2014, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +34,16 @@ #define POLY1305_TAG_LEN 16 #define CHACHA20_NONCE_LEN 8 +/* + * The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols", + * introduced a modified AEAD construction that is incompatible with the + * common style that that has been already used in TLS. The IETF version + * also adds a constant (salt) that is prepended to the nonce. + */ +#define CHACHA20_CONSTANT_LEN 4 +#define CHACHA20_IV_LEN 8 +#define CHACHA20_NONCE_LEN_IETF (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN) + struct aead_chacha20_poly1305_ctx { unsigned char key[32]; unsigned char tag_len; @@ -88,10 +100,27 @@ poly1305_update_with_length(poly1305_state *poly1305, j >>= 8; } - CRYPTO_poly1305_update(poly1305, data, data_len); + if (data != NULL) + CRYPTO_poly1305_update(poly1305, data, data_len); CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); } +static void +poly1305_update_with_pad16(poly1305_state *poly1305, + const unsigned char *data, size_t data_len) +{ + static const unsigned char zero_pad16[16]; + size_t pad_len; + + CRYPTO_poly1305_update(poly1305, data, data_len); + + /* pad16() is defined in RFC 7539 2.8.1. */ + if ((pad_len = data_len % 16) == 0) + return; + + CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len); +} + static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, size_t max_out_len, const unsigned char *nonce, @@ -101,7 +130,9 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; unsigned char poly1305_key[32]; poly1305_state poly1305; + const unsigned char *iv; const uint64_t in_len_64 = in_len; + uint64_t ctr; /* The underlying ChaCha implementation may not overflow the block * counter into the second counter word. Therefore we disallow @@ -121,19 +152,40 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - if (nonce_len != CHACHA20_NONCE_LEN) { + if (nonce_len != ctx->aead->nonce_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); return 0; } - memset(poly1305_key, 0, sizeof(poly1305_key)); - CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), - c20_ctx->key, nonce, 0); - - CRYPTO_poly1305_init(&poly1305, poly1305_key); - poly1305_update_with_length(&poly1305, ad, ad_len); - CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); - poly1305_update_with_length(&poly1305, out, in_len); + if (nonce_len == CHACHA20_NONCE_LEN) { + /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, nonce, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_length(&poly1305, ad, ad_len); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + poly1305_update_with_length(&poly1305, out, in_len); + } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) { + /* RFC 7539, May 2015 */ + + ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | + nonce[2] << 16 | nonce[3] << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1); + poly1305_update_with_pad16(&poly1305, out, in_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, in_len); + } if (c20_ctx->tag_len != POLY1305_TAG_LEN) { unsigned char tag[POLY1305_TAG_LEN]; @@ -157,9 +209,11 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; unsigned char mac[POLY1305_TAG_LEN]; unsigned char poly1305_key[32]; + const unsigned char *iv; poly1305_state poly1305; const uint64_t in_len_64 = in_len; size_t plaintext_len; + uint64_t ctr; if (in_len < c20_ctx->tag_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); @@ -178,7 +232,7 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - if (nonce_len != CHACHA20_NONCE_LEN) { + if (nonce_len != ctx->aead->nonce_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); return 0; } @@ -191,13 +245,34 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - memset(poly1305_key, 0, sizeof(poly1305_key)); - CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), - c20_ctx->key, nonce, 0); + if (nonce_len == CHACHA20_NONCE_LEN) { + /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, nonce, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_length(&poly1305, ad, ad_len); + poly1305_update_with_length(&poly1305, in, plaintext_len); + } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) { + /* RFC 7539, May 2015 */ + + ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | + nonce[2] << 16 | nonce[3] << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + poly1305_update_with_pad16(&poly1305, in, plaintext_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, plaintext_len); + } - CRYPTO_poly1305_init(&poly1305, poly1305_key); - poly1305_update_with_length(&poly1305, ad, ad_len); - poly1305_update_with_length(&poly1305, in, plaintext_len); CRYPTO_poly1305_finish(&poly1305, mac); if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { @@ -222,10 +297,28 @@ static const EVP_AEAD aead_chacha20_poly1305 = { .open = aead_chacha20_poly1305_open, }; +static const EVP_AEAD aead_chacha20_poly1305_ietf = { + .key_len = 32, + .nonce_len = CHACHA20_NONCE_LEN_IETF, + .overhead = POLY1305_TAG_LEN, + .max_tag_len = POLY1305_TAG_LEN, + + .init = aead_chacha20_poly1305_init, + .cleanup = aead_chacha20_poly1305_cleanup, + .seal = aead_chacha20_poly1305_seal, + .open = aead_chacha20_poly1305_open, +}; + const EVP_AEAD * EVP_aead_chacha20_poly1305() { return &aead_chacha20_poly1305; } +const EVP_AEAD * +EVP_aead_chacha20_poly1305_ietf() +{ + return &aead_chacha20_poly1305_ietf; +} + #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h index 2ddbf6142e..1ec24879c0 100644 --- a/src/lib/libcrypto/evp/evp.h +++ b/src/lib/libcrypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.48 2015/09/14 01:45:03 doug Exp $ */ +/* $OpenBSD: evp.h,v 1.49 2015/11/02 15:40:53 reyk Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1215,6 +1215,7 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void); #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) /* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ const EVP_AEAD *EVP_aead_chacha20_poly1305(void); +const EVP_AEAD *EVP_aead_chacha20_poly1305_ietf(void); #endif /* 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 a2b4efea54..e6abc282d3 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 @@ -.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.2 2015/10/14 09:11:25 schwarze Exp $ +.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.3 2015/11/02 15:40:53 reyk Exp $ .\" .\" Copyright (c) 2014, Google Inc. .\" Parts of the text were written by Adam Langley and David Benjamin. @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 14 2015 $ +.Dd $Mdocdate: November 2 2015 $ .Dt EVP_AEAD_CTX_INIT 3 .Os .Sh NAME @@ -30,7 +30,8 @@ .Nm EVP_AEAD_nonce_length , .Nm EVP_aead_aes_128_gcm , .Nm EVP_aead_aes_256_gcm , -.Nm EVP_aead_chacha20_poly1305 +.Nm EVP_aead_chacha20_poly1305 , +.Nm EVP_aead_chacha20_poly1305_ietf .Nd authenticated encryption with additional data .Sh SYNOPSIS .In openssl/evp.h @@ -101,6 +102,10 @@ .Fo EVP_aead_chacha20_poly1305 .Fa void .Fc +.Ft const EVP_AEAD * +.Fo EVP_aead_chacha20_poly1305_ietf +.Fa void +.Fc .Sh DESCRIPTION AEAD (Authenticated Encryption with Additional Data) couples confidentiality and integrity in a single primitive. @@ -219,6 +224,11 @@ AES-128 in Galois Counter Mode. AES-256 in Galois Counter Mode. .It Fn EVP_aead_chacha20_poly1305 ChaCha20 with a Poly1305 authenticator. +.It Fn EVP_aead_chacha20_poly1305_ietf +ChaCha20 with a Poly1305 authenticator for IETF Protocols. +The IETF standardised variant of the AEAD is incompatible with the +original version. +It uses a constant salt that is prepended to the nonce. .El .Pp Where possible the @@ -270,6 +280,23 @@ EVP_AEAD_CTX_cleanup(&ctx); .Ed .Sh SEE ALSO .Xr evp 3 +.Sh STANDARDS +.Rs +.%A A. Langley +.%A W. Chang +.%D November 2013 +.%R draft-agl-tls-chacha20poly1305-04 +.%T ChaCha20 and Poly1305 based Cipher Suites for TLS +.Re +.Pp +.Rs +.%A Y. Nir +.%A A. Langley +.%D May 2015 +.%R RFC 7539 +.%T ChaCha20 and Poly1305 for IETF Protocols +.Re +.Pp .Sh HISTORY AEAD is based on the implementation by .An Adam Langley diff --git a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c index 9deb40b72a..47551c4578 100644 --- a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c +++ b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c @@ -1,5 +1,7 @@ -/* $OpenBSD: e_chacha20poly1305.c,v 1.10 2015/09/10 15:56:25 jsing Exp $ */ +/* $OpenBSD: e_chacha20poly1305.c,v 1.11 2015/11/02 15:40:53 reyk Exp $ */ + /* + * Copyright (c) 2015 Reyk Floter * Copyright (c) 2014, Google Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +34,16 @@ #define POLY1305_TAG_LEN 16 #define CHACHA20_NONCE_LEN 8 +/* + * The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols", + * introduced a modified AEAD construction that is incompatible with the + * common style that that has been already used in TLS. The IETF version + * also adds a constant (salt) that is prepended to the nonce. + */ +#define CHACHA20_CONSTANT_LEN 4 +#define CHACHA20_IV_LEN 8 +#define CHACHA20_NONCE_LEN_IETF (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN) + struct aead_chacha20_poly1305_ctx { unsigned char key[32]; unsigned char tag_len; @@ -88,10 +100,27 @@ poly1305_update_with_length(poly1305_state *poly1305, j >>= 8; } - CRYPTO_poly1305_update(poly1305, data, data_len); + if (data != NULL) + CRYPTO_poly1305_update(poly1305, data, data_len); CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); } +static void +poly1305_update_with_pad16(poly1305_state *poly1305, + const unsigned char *data, size_t data_len) +{ + static const unsigned char zero_pad16[16]; + size_t pad_len; + + CRYPTO_poly1305_update(poly1305, data, data_len); + + /* pad16() is defined in RFC 7539 2.8.1. */ + if ((pad_len = data_len % 16) == 0) + return; + + CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len); +} + static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, size_t max_out_len, const unsigned char *nonce, @@ -101,7 +130,9 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; unsigned char poly1305_key[32]; poly1305_state poly1305; + const unsigned char *iv; const uint64_t in_len_64 = in_len; + uint64_t ctr; /* The underlying ChaCha implementation may not overflow the block * counter into the second counter word. Therefore we disallow @@ -121,19 +152,40 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - if (nonce_len != CHACHA20_NONCE_LEN) { + if (nonce_len != ctx->aead->nonce_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); return 0; } - memset(poly1305_key, 0, sizeof(poly1305_key)); - CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), - c20_ctx->key, nonce, 0); - - CRYPTO_poly1305_init(&poly1305, poly1305_key); - poly1305_update_with_length(&poly1305, ad, ad_len); - CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); - poly1305_update_with_length(&poly1305, out, in_len); + if (nonce_len == CHACHA20_NONCE_LEN) { + /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, nonce, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_length(&poly1305, ad, ad_len); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + poly1305_update_with_length(&poly1305, out, in_len); + } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) { + /* RFC 7539, May 2015 */ + + ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | + nonce[2] << 16 | nonce[3] << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1); + poly1305_update_with_pad16(&poly1305, out, in_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, in_len); + } if (c20_ctx->tag_len != POLY1305_TAG_LEN) { unsigned char tag[POLY1305_TAG_LEN]; @@ -157,9 +209,11 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; unsigned char mac[POLY1305_TAG_LEN]; unsigned char poly1305_key[32]; + const unsigned char *iv; poly1305_state poly1305; const uint64_t in_len_64 = in_len; size_t plaintext_len; + uint64_t ctr; if (in_len < c20_ctx->tag_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); @@ -178,7 +232,7 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - if (nonce_len != CHACHA20_NONCE_LEN) { + if (nonce_len != ctx->aead->nonce_len) { EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); return 0; } @@ -191,13 +245,34 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, return 0; } - memset(poly1305_key, 0, sizeof(poly1305_key)); - CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), - c20_ctx->key, nonce, 0); + if (nonce_len == CHACHA20_NONCE_LEN) { + /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, nonce, 0); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_length(&poly1305, ad, ad_len); + poly1305_update_with_length(&poly1305, in, plaintext_len); + } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) { + /* RFC 7539, May 2015 */ + + ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | + nonce[2] << 16 | nonce[3] << 24) << 32; + iv = nonce + CHACHA20_CONSTANT_LEN; + + memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, + sizeof(poly1305_key), c20_ctx->key, iv, ctr); + + CRYPTO_poly1305_init(&poly1305, poly1305_key); + poly1305_update_with_pad16(&poly1305, ad, ad_len); + poly1305_update_with_pad16(&poly1305, in, plaintext_len); + poly1305_update_with_length(&poly1305, NULL, ad_len); + poly1305_update_with_length(&poly1305, NULL, plaintext_len); + } - CRYPTO_poly1305_init(&poly1305, poly1305_key); - poly1305_update_with_length(&poly1305, ad, ad_len); - poly1305_update_with_length(&poly1305, in, plaintext_len); CRYPTO_poly1305_finish(&poly1305, mac); if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { @@ -222,10 +297,28 @@ static const EVP_AEAD aead_chacha20_poly1305 = { .open = aead_chacha20_poly1305_open, }; +static const EVP_AEAD aead_chacha20_poly1305_ietf = { + .key_len = 32, + .nonce_len = CHACHA20_NONCE_LEN_IETF, + .overhead = POLY1305_TAG_LEN, + .max_tag_len = POLY1305_TAG_LEN, + + .init = aead_chacha20_poly1305_init, + .cleanup = aead_chacha20_poly1305_cleanup, + .seal = aead_chacha20_poly1305_seal, + .open = aead_chacha20_poly1305_open, +}; + const EVP_AEAD * EVP_aead_chacha20_poly1305() { return &aead_chacha20_poly1305; } +const EVP_AEAD * +EVP_aead_chacha20_poly1305_ietf() +{ + return &aead_chacha20_poly1305_ietf; +} + #endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ diff --git a/src/lib/libssl/src/crypto/evp/evp.h b/src/lib/libssl/src/crypto/evp/evp.h index 2ddbf6142e..1ec24879c0 100644 --- a/src/lib/libssl/src/crypto/evp/evp.h +++ b/src/lib/libssl/src/crypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.48 2015/09/14 01:45:03 doug Exp $ */ +/* $OpenBSD: evp.h,v 1.49 2015/11/02 15:40:53 reyk Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1215,6 +1215,7 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void); #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) /* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ const EVP_AEAD *EVP_aead_chacha20_poly1305(void); +const EVP_AEAD *EVP_aead_chacha20_poly1305_ietf(void); #endif /* EVP_AEAD_key_length returns the length of the keys used. */ diff --git a/src/regress/lib/libcrypto/aead/aeadtest.c b/src/regress/lib/libcrypto/aead/aeadtest.c index 6b1ad206c4..72209f5caa 100644 --- a/src/regress/lib/libcrypto/aead/aeadtest.c +++ b/src/regress/lib/libcrypto/aead/aeadtest.c @@ -133,6 +133,12 @@ aead_from_name(const EVP_AEAD **aead, const char *name) *aead = EVP_aead_chacha20_poly1305(); #else fprintf(stderr, "No chacha20-poly1305 support.\n"); +#endif + } else if (strcmp(name, "chacha20-poly1305-ietf") == 0) { +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + *aead = EVP_aead_chacha20_poly1305_ietf(); +#else + fprintf(stderr, "No chacha20-poly1305-ietf support.\n"); #endif } else { fprintf(stderr, "Unknown AEAD: %s\n", name); diff --git a/src/regress/lib/libcrypto/aead/aeadtests.txt b/src/regress/lib/libcrypto/aead/aeadtests.txt index dc881911e4..6c4002c1cc 100644 --- a/src/regress/lib/libcrypto/aead/aeadtests.txt +++ b/src/regress/lib/libcrypto/aead/aeadtests.txt @@ -659,3 +659,39 @@ AD: 00000000000000061703030251 CT: d62561a166e0319d21dc9fd813b00343602fa8ac58cd0b6077dcc786af12c532478b14b5524f5f38feb24f05688d569ecdca190d330a7843ddd75928c67653c0e6742182ec214fc7b84e892c26a3aa9caea181c90b1c0e5f89e57151daeb6309b231dca9c3396b25b5c6d1cae376164aac5b392a4421f56d2fe6c7c109a562a533900c4d998127824b7b2066af5b2ab287f3a3751395d96bb0a81b2745543ccee1a806e5a623c8a088ec27f0346b9d01accf8192556c56fd3bee85d6fcef7f09383637f2e8d7fd3adf3d2d9f1c1eccde05b3b17eb6c99b1ca8be260ae1154e5658a5cd1e9e27d61915db081c2888fc37faa4a75294236b51c449f78881198c3bb702d4d3797b3cd958911060d606280f9ef74b7eef47517f1485291bfec5587d3dbae51fa26ea6f119e24ee72fc2e4e9db5c65aa20209492f504ad657333a7b29cb5ec6ff975ed7cbff20938bb02382276de32b8a21966946b8dcf297c3aacd25cf8903d3060aafd00ad19043e24cf17b404898d3f4aac02727d436a1e5bad07e6c07c88eb12664c1e38dfdf6e280347554629c8903ceb7703ad72eda21354bd963b9bdf05b4c126dc0e5f8d74dd2c45036fd0219e7f32124f27ab26e1d66d87a3c6e873a9c78505a5209265aa90b4a5f4acafe1443dcd3810c0455fa5c471e22a4d9623d34902abf310d414036b7773c8725534b4e03b6261d92346509a70b08e94eac0906d8e26e669a7dea38dfe2532af1167a133b75b4193acbef193dead0c08d65f2cfe7012afd9ee5452d714c6f1a2f810cd13ac2f36b6a1a4580154831a1098aa7ed3c506bebc24de46d7a03f6e TAG: 1df6f94253edb794e81221d3bc838599 +# Test vector from RFC7539 2.8.2 +AEAD: chacha20-poly1305-ietf +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: 070000004041424344454647 +IN: 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e +AD: 50515253c0c1c2c3c4c5c6c7 +CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116 +TAG: 1ae10b594f09e26a7e902ecbd0600691 + +# Test vector from RFC7539 Appendix A.5 +AEAD: chacha20-poly1305-ietf +KEY: 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 +NONCE: 000000000102030405060708 +IN: 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d +AD: f33388860000000000004e91 +CT: 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b +TAG: eead9d67890cbb22392336fea1851f38 + +# Test vector from RFC7634 Appendix A +AEAD: chacha20-poly1305-ietf +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: a0a1a2a31011121314151617 +IN: 45000054a6f200004001e778c6336405c000020508005b7a3a080000553bec100007362708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363701020204 +AD: 0102030400000005 +CT: 24039428b97f417e3c13753a4f05087b67c352e6a7fab1b982d466ef407ae5c614ee8099d52844eb61aa95dfab4c02f72aa71e7c4c4f64c9befe2facc638e8f3cbec163fac469b502773f6fb94e664da9165b82829f641e0 +TAG: 76aaa8266b7fb0f7b11b369907e1ad43 + +# Test vector from RFC7634 Appendix B +AEAD: chacha20-poly1305-ietf +KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f +NONCE: a0a1a2a31011121314151617 +IN: 0000000c000040010000000a00 +AD: c0c1c2c3c4c5c6c7d0d1d2d3d4d5d6d72e202500000000090000004529000029 +CT: 610394701f8d017f7c12924889 +TAG: 6b71bfe25236efd7cdc67066906315b2 + -- cgit v1.2.3-55-g6feb