summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreyk <>2015-11-02 15:40:53 +0000
committerreyk <>2015-11-02 15:40:53 +0000
commitb743c75edf0dc70962a2ed0c5221ecb8841d7525 (patch)
tree40446be7b959dce9252457817e67737c7606706c
parent3b76990c68663b08d77297a05a8104c2f1528064 (diff)
downloadopenbsd-b743c75edf0dc70962a2ed0c5221ecb8841d7525.tar.gz
openbsd-b743c75edf0dc70962a2ed0c5221ecb8841d7525.tar.bz2
openbsd-b743c75edf0dc70962a2ed0c5221ecb8841d7525.zip
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@
-rw-r--r--src/lib/libcrypto/evp/e_chacha20poly1305.c129
-rw-r--r--src/lib/libcrypto/evp/evp.h3
-rw-r--r--src/lib/libcrypto/man/EVP_AEAD_CTX_init.333
-rw-r--r--src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c129
-rw-r--r--src/lib/libssl/src/crypto/evp/evp.h3
-rw-r--r--src/regress/lib/libcrypto/aead/aeadtest.c6
-rw-r--r--src/regress/lib/libcrypto/aead/aeadtests.txt36
7 files changed, 298 insertions, 41 deletions
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 @@
1/* $OpenBSD: e_chacha20poly1305.c,v 1.10 2015/09/10 15:56:25 jsing Exp $ */ 1/* $OpenBSD: e_chacha20poly1305.c,v 1.11 2015/11/02 15:40:53 reyk Exp $ */
2
2/* 3/*
4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
3 * Copyright (c) 2014, Google Inc. 5 * Copyright (c) 2014, Google Inc.
4 * 6 *
5 * Permission to use, copy, modify, and/or distribute this software for any 7 * Permission to use, copy, modify, and/or distribute this software for any
@@ -32,6 +34,16 @@
32#define POLY1305_TAG_LEN 16 34#define POLY1305_TAG_LEN 16
33#define CHACHA20_NONCE_LEN 8 35#define CHACHA20_NONCE_LEN 8
34 36
37/*
38 * The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols",
39 * introduced a modified AEAD construction that is incompatible with the
40 * common style that that has been already used in TLS. The IETF version
41 * also adds a constant (salt) that is prepended to the nonce.
42 */
43#define CHACHA20_CONSTANT_LEN 4
44#define CHACHA20_IV_LEN 8
45#define CHACHA20_NONCE_LEN_IETF (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
46
35struct aead_chacha20_poly1305_ctx { 47struct aead_chacha20_poly1305_ctx {
36 unsigned char key[32]; 48 unsigned char key[32];
37 unsigned char tag_len; 49 unsigned char tag_len;
@@ -88,10 +100,27 @@ poly1305_update_with_length(poly1305_state *poly1305,
88 j >>= 8; 100 j >>= 8;
89 } 101 }
90 102
91 CRYPTO_poly1305_update(poly1305, data, data_len); 103 if (data != NULL)
104 CRYPTO_poly1305_update(poly1305, data, data_len);
92 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); 105 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
93} 106}
94 107
108static void
109poly1305_update_with_pad16(poly1305_state *poly1305,
110 const unsigned char *data, size_t data_len)
111{
112 static const unsigned char zero_pad16[16];
113 size_t pad_len;
114
115 CRYPTO_poly1305_update(poly1305, data, data_len);
116
117 /* pad16() is defined in RFC 7539 2.8.1. */
118 if ((pad_len = data_len % 16) == 0)
119 return;
120
121 CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
122}
123
95static int 124static int
96aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 125aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
97 size_t *out_len, size_t max_out_len, const unsigned char *nonce, 126 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,
101 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 130 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
102 unsigned char poly1305_key[32]; 131 unsigned char poly1305_key[32];
103 poly1305_state poly1305; 132 poly1305_state poly1305;
133 const unsigned char *iv;
104 const uint64_t in_len_64 = in_len; 134 const uint64_t in_len_64 = in_len;
135 uint64_t ctr;
105 136
106 /* The underlying ChaCha implementation may not overflow the block 137 /* The underlying ChaCha implementation may not overflow the block
107 * counter into the second counter word. Therefore we disallow 138 * 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,
121 return 0; 152 return 0;
122 } 153 }
123 154
124 if (nonce_len != CHACHA20_NONCE_LEN) { 155 if (nonce_len != ctx->aead->nonce_len) {
125 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); 156 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE);
126 return 0; 157 return 0;
127 } 158 }
128 159
129 memset(poly1305_key, 0, sizeof(poly1305_key)); 160 if (nonce_len == CHACHA20_NONCE_LEN) {
130 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), 161 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
131 c20_ctx->key, nonce, 0); 162
132 163 memset(poly1305_key, 0, sizeof(poly1305_key));
133 CRYPTO_poly1305_init(&poly1305, poly1305_key); 164 CRYPTO_chacha_20(poly1305_key, poly1305_key,
134 poly1305_update_with_length(&poly1305, ad, ad_len); 165 sizeof(poly1305_key), c20_ctx->key, nonce, 0);
135 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); 166
136 poly1305_update_with_length(&poly1305, out, in_len); 167 CRYPTO_poly1305_init(&poly1305, poly1305_key);
168 poly1305_update_with_length(&poly1305, ad, ad_len);
169 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
170 poly1305_update_with_length(&poly1305, out, in_len);
171 } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) {
172 /* RFC 7539, May 2015 */
173
174 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
175 nonce[2] << 16 | nonce[3] << 24) << 32;
176 iv = nonce + CHACHA20_CONSTANT_LEN;
177
178 memset(poly1305_key, 0, sizeof(poly1305_key));
179 CRYPTO_chacha_20(poly1305_key, poly1305_key,
180 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
181
182 CRYPTO_poly1305_init(&poly1305, poly1305_key);
183 poly1305_update_with_pad16(&poly1305, ad, ad_len);
184 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
185 poly1305_update_with_pad16(&poly1305, out, in_len);
186 poly1305_update_with_length(&poly1305, NULL, ad_len);
187 poly1305_update_with_length(&poly1305, NULL, in_len);
188 }
137 189
138 if (c20_ctx->tag_len != POLY1305_TAG_LEN) { 190 if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
139 unsigned char tag[POLY1305_TAG_LEN]; 191 unsigned char tag[POLY1305_TAG_LEN];
@@ -157,9 +209,11 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
157 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 209 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
158 unsigned char mac[POLY1305_TAG_LEN]; 210 unsigned char mac[POLY1305_TAG_LEN];
159 unsigned char poly1305_key[32]; 211 unsigned char poly1305_key[32];
212 const unsigned char *iv;
160 poly1305_state poly1305; 213 poly1305_state poly1305;
161 const uint64_t in_len_64 = in_len; 214 const uint64_t in_len_64 = in_len;
162 size_t plaintext_len; 215 size_t plaintext_len;
216 uint64_t ctr;
163 217
164 if (in_len < c20_ctx->tag_len) { 218 if (in_len < c20_ctx->tag_len) {
165 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 219 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,
178 return 0; 232 return 0;
179 } 233 }
180 234
181 if (nonce_len != CHACHA20_NONCE_LEN) { 235 if (nonce_len != ctx->aead->nonce_len) {
182 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); 236 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE);
183 return 0; 237 return 0;
184 } 238 }
@@ -191,13 +245,34 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
191 return 0; 245 return 0;
192 } 246 }
193 247
194 memset(poly1305_key, 0, sizeof(poly1305_key)); 248 if (nonce_len == CHACHA20_NONCE_LEN) {
195 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), 249 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
196 c20_ctx->key, nonce, 0); 250
251 memset(poly1305_key, 0, sizeof(poly1305_key));
252 CRYPTO_chacha_20(poly1305_key, poly1305_key,
253 sizeof(poly1305_key), c20_ctx->key, nonce, 0);
254
255 CRYPTO_poly1305_init(&poly1305, poly1305_key);
256 poly1305_update_with_length(&poly1305, ad, ad_len);
257 poly1305_update_with_length(&poly1305, in, plaintext_len);
258 } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) {
259 /* RFC 7539, May 2015 */
260
261 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
262 nonce[2] << 16 | nonce[3] << 24) << 32;
263 iv = nonce + CHACHA20_CONSTANT_LEN;
264
265 memset(poly1305_key, 0, sizeof(poly1305_key));
266 CRYPTO_chacha_20(poly1305_key, poly1305_key,
267 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
268
269 CRYPTO_poly1305_init(&poly1305, poly1305_key);
270 poly1305_update_with_pad16(&poly1305, ad, ad_len);
271 poly1305_update_with_pad16(&poly1305, in, plaintext_len);
272 poly1305_update_with_length(&poly1305, NULL, ad_len);
273 poly1305_update_with_length(&poly1305, NULL, plaintext_len);
274 }
197 275
198 CRYPTO_poly1305_init(&poly1305, poly1305_key);
199 poly1305_update_with_length(&poly1305, ad, ad_len);
200 poly1305_update_with_length(&poly1305, in, plaintext_len);
201 CRYPTO_poly1305_finish(&poly1305, mac); 276 CRYPTO_poly1305_finish(&poly1305, mac);
202 277
203 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { 278 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
@@ -222,10 +297,28 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
222 .open = aead_chacha20_poly1305_open, 297 .open = aead_chacha20_poly1305_open,
223}; 298};
224 299
300static const EVP_AEAD aead_chacha20_poly1305_ietf = {
301 .key_len = 32,
302 .nonce_len = CHACHA20_NONCE_LEN_IETF,
303 .overhead = POLY1305_TAG_LEN,
304 .max_tag_len = POLY1305_TAG_LEN,
305
306 .init = aead_chacha20_poly1305_init,
307 .cleanup = aead_chacha20_poly1305_cleanup,
308 .seal = aead_chacha20_poly1305_seal,
309 .open = aead_chacha20_poly1305_open,
310};
311
225const EVP_AEAD * 312const EVP_AEAD *
226EVP_aead_chacha20_poly1305() 313EVP_aead_chacha20_poly1305()
227{ 314{
228 return &aead_chacha20_poly1305; 315 return &aead_chacha20_poly1305;
229} 316}
230 317
318const EVP_AEAD *
319EVP_aead_chacha20_poly1305_ietf()
320{
321 return &aead_chacha20_poly1305_ietf;
322}
323
231#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ 324#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 @@
1/* $OpenBSD: evp.h,v 1.48 2015/09/14 01:45:03 doug Exp $ */ 1/* $OpenBSD: evp.h,v 1.49 2015/11/02 15:40:53 reyk 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 *
@@ -1215,6 +1215,7 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void);
1215#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 1215#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1216/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ 1216/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */
1217const EVP_AEAD *EVP_aead_chacha20_poly1305(void); 1217const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
1218const EVP_AEAD *EVP_aead_chacha20_poly1305_ietf(void);
1218#endif 1219#endif
1219 1220
1220/* EVP_AEAD_key_length returns the length of the keys used. */ 1221/* 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 @@
1.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.2 2015/10/14 09:11:25 schwarze Exp $ 1.\" $OpenBSD: EVP_AEAD_CTX_init.3,v 1.3 2015/11/02 15:40:53 reyk 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: October 14 2015 $ 19.Dd $Mdocdate: November 2 2015 $
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_chacha20_poly1305_ietf
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_chacha20_poly1305_ietf
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,11 @@ 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_chacha20_poly1305_ietf
228ChaCha20 with a Poly1305 authenticator for IETF Protocols.
229The IETF standardised variant of the AEAD is incompatible with the
230original version.
231It uses a constant salt that is prepended to the nonce.
222.El 232.El
223.Pp 233.Pp
224Where possible the 234Where possible the
@@ -270,6 +280,23 @@ EVP_AEAD_CTX_cleanup(&ctx);
270.Ed 280.Ed
271.Sh SEE ALSO 281.Sh SEE ALSO
272.Xr evp 3 282.Xr evp 3
283.Sh STANDARDS
284.Rs
285.%A A. Langley
286.%A W. Chang
287.%D November 2013
288.%R draft-agl-tls-chacha20poly1305-04
289.%T ChaCha20 and Poly1305 based Cipher Suites for TLS
290.Re
291.Pp
292.Rs
293.%A Y. Nir
294.%A A. Langley
295.%D May 2015
296.%R RFC 7539
297.%T ChaCha20 and Poly1305 for IETF Protocols
298.Re
299.Pp
273.Sh HISTORY 300.Sh HISTORY
274AEAD is based on the implementation by 301AEAD is based on the implementation by
275.An Adam Langley 302.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 @@
1/* $OpenBSD: e_chacha20poly1305.c,v 1.10 2015/09/10 15:56:25 jsing Exp $ */ 1/* $OpenBSD: e_chacha20poly1305.c,v 1.11 2015/11/02 15:40:53 reyk Exp $ */
2
2/* 3/*
4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
3 * Copyright (c) 2014, Google Inc. 5 * Copyright (c) 2014, Google Inc.
4 * 6 *
5 * Permission to use, copy, modify, and/or distribute this software for any 7 * Permission to use, copy, modify, and/or distribute this software for any
@@ -32,6 +34,16 @@
32#define POLY1305_TAG_LEN 16 34#define POLY1305_TAG_LEN 16
33#define CHACHA20_NONCE_LEN 8 35#define CHACHA20_NONCE_LEN 8
34 36
37/*
38 * The informational RFC 7539, "ChaCha20 and Poly1305 for IETF Protocols",
39 * introduced a modified AEAD construction that is incompatible with the
40 * common style that that has been already used in TLS. The IETF version
41 * also adds a constant (salt) that is prepended to the nonce.
42 */
43#define CHACHA20_CONSTANT_LEN 4
44#define CHACHA20_IV_LEN 8
45#define CHACHA20_NONCE_LEN_IETF (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
46
35struct aead_chacha20_poly1305_ctx { 47struct aead_chacha20_poly1305_ctx {
36 unsigned char key[32]; 48 unsigned char key[32];
37 unsigned char tag_len; 49 unsigned char tag_len;
@@ -88,10 +100,27 @@ poly1305_update_with_length(poly1305_state *poly1305,
88 j >>= 8; 100 j >>= 8;
89 } 101 }
90 102
91 CRYPTO_poly1305_update(poly1305, data, data_len); 103 if (data != NULL)
104 CRYPTO_poly1305_update(poly1305, data, data_len);
92 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); 105 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
93} 106}
94 107
108static void
109poly1305_update_with_pad16(poly1305_state *poly1305,
110 const unsigned char *data, size_t data_len)
111{
112 static const unsigned char zero_pad16[16];
113 size_t pad_len;
114
115 CRYPTO_poly1305_update(poly1305, data, data_len);
116
117 /* pad16() is defined in RFC 7539 2.8.1. */
118 if ((pad_len = data_len % 16) == 0)
119 return;
120
121 CRYPTO_poly1305_update(poly1305, zero_pad16, 16 - pad_len);
122}
123
95static int 124static int
96aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 125aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
97 size_t *out_len, size_t max_out_len, const unsigned char *nonce, 126 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,
101 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 130 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
102 unsigned char poly1305_key[32]; 131 unsigned char poly1305_key[32];
103 poly1305_state poly1305; 132 poly1305_state poly1305;
133 const unsigned char *iv;
104 const uint64_t in_len_64 = in_len; 134 const uint64_t in_len_64 = in_len;
135 uint64_t ctr;
105 136
106 /* The underlying ChaCha implementation may not overflow the block 137 /* The underlying ChaCha implementation may not overflow the block
107 * counter into the second counter word. Therefore we disallow 138 * 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,
121 return 0; 152 return 0;
122 } 153 }
123 154
124 if (nonce_len != CHACHA20_NONCE_LEN) { 155 if (nonce_len != ctx->aead->nonce_len) {
125 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); 156 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE);
126 return 0; 157 return 0;
127 } 158 }
128 159
129 memset(poly1305_key, 0, sizeof(poly1305_key)); 160 if (nonce_len == CHACHA20_NONCE_LEN) {
130 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), 161 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
131 c20_ctx->key, nonce, 0); 162
132 163 memset(poly1305_key, 0, sizeof(poly1305_key));
133 CRYPTO_poly1305_init(&poly1305, poly1305_key); 164 CRYPTO_chacha_20(poly1305_key, poly1305_key,
134 poly1305_update_with_length(&poly1305, ad, ad_len); 165 sizeof(poly1305_key), c20_ctx->key, nonce, 0);
135 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); 166
136 poly1305_update_with_length(&poly1305, out, in_len); 167 CRYPTO_poly1305_init(&poly1305, poly1305_key);
168 poly1305_update_with_length(&poly1305, ad, ad_len);
169 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
170 poly1305_update_with_length(&poly1305, out, in_len);
171 } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) {
172 /* RFC 7539, May 2015 */
173
174 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
175 nonce[2] << 16 | nonce[3] << 24) << 32;
176 iv = nonce + CHACHA20_CONSTANT_LEN;
177
178 memset(poly1305_key, 0, sizeof(poly1305_key));
179 CRYPTO_chacha_20(poly1305_key, poly1305_key,
180 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
181
182 CRYPTO_poly1305_init(&poly1305, poly1305_key);
183 poly1305_update_with_pad16(&poly1305, ad, ad_len);
184 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
185 poly1305_update_with_pad16(&poly1305, out, in_len);
186 poly1305_update_with_length(&poly1305, NULL, ad_len);
187 poly1305_update_with_length(&poly1305, NULL, in_len);
188 }
137 189
138 if (c20_ctx->tag_len != POLY1305_TAG_LEN) { 190 if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
139 unsigned char tag[POLY1305_TAG_LEN]; 191 unsigned char tag[POLY1305_TAG_LEN];
@@ -157,9 +209,11 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
157 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 209 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
158 unsigned char mac[POLY1305_TAG_LEN]; 210 unsigned char mac[POLY1305_TAG_LEN];
159 unsigned char poly1305_key[32]; 211 unsigned char poly1305_key[32];
212 const unsigned char *iv;
160 poly1305_state poly1305; 213 poly1305_state poly1305;
161 const uint64_t in_len_64 = in_len; 214 const uint64_t in_len_64 = in_len;
162 size_t plaintext_len; 215 size_t plaintext_len;
216 uint64_t ctr;
163 217
164 if (in_len < c20_ctx->tag_len) { 218 if (in_len < c20_ctx->tag_len) {
165 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 219 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,
178 return 0; 232 return 0;
179 } 233 }
180 234
181 if (nonce_len != CHACHA20_NONCE_LEN) { 235 if (nonce_len != ctx->aead->nonce_len) {
182 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); 236 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE);
183 return 0; 237 return 0;
184 } 238 }
@@ -191,13 +245,34 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
191 return 0; 245 return 0;
192 } 246 }
193 247
194 memset(poly1305_key, 0, sizeof(poly1305_key)); 248 if (nonce_len == CHACHA20_NONCE_LEN) {
195 CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), 249 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */
196 c20_ctx->key, nonce, 0); 250
251 memset(poly1305_key, 0, sizeof(poly1305_key));
252 CRYPTO_chacha_20(poly1305_key, poly1305_key,
253 sizeof(poly1305_key), c20_ctx->key, nonce, 0);
254
255 CRYPTO_poly1305_init(&poly1305, poly1305_key);
256 poly1305_update_with_length(&poly1305, ad, ad_len);
257 poly1305_update_with_length(&poly1305, in, plaintext_len);
258 } else if (nonce_len == CHACHA20_NONCE_LEN_IETF) {
259 /* RFC 7539, May 2015 */
260
261 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
262 nonce[2] << 16 | nonce[3] << 24) << 32;
263 iv = nonce + CHACHA20_CONSTANT_LEN;
264
265 memset(poly1305_key, 0, sizeof(poly1305_key));
266 CRYPTO_chacha_20(poly1305_key, poly1305_key,
267 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
268
269 CRYPTO_poly1305_init(&poly1305, poly1305_key);
270 poly1305_update_with_pad16(&poly1305, ad, ad_len);
271 poly1305_update_with_pad16(&poly1305, in, plaintext_len);
272 poly1305_update_with_length(&poly1305, NULL, ad_len);
273 poly1305_update_with_length(&poly1305, NULL, plaintext_len);
274 }
197 275
198 CRYPTO_poly1305_init(&poly1305, poly1305_key);
199 poly1305_update_with_length(&poly1305, ad, ad_len);
200 poly1305_update_with_length(&poly1305, in, plaintext_len);
201 CRYPTO_poly1305_finish(&poly1305, mac); 276 CRYPTO_poly1305_finish(&poly1305, mac);
202 277
203 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { 278 if (timingsafe_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
@@ -222,10 +297,28 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
222 .open = aead_chacha20_poly1305_open, 297 .open = aead_chacha20_poly1305_open,
223}; 298};
224 299
300static const EVP_AEAD aead_chacha20_poly1305_ietf = {
301 .key_len = 32,
302 .nonce_len = CHACHA20_NONCE_LEN_IETF,
303 .overhead = POLY1305_TAG_LEN,
304 .max_tag_len = POLY1305_TAG_LEN,
305
306 .init = aead_chacha20_poly1305_init,
307 .cleanup = aead_chacha20_poly1305_cleanup,
308 .seal = aead_chacha20_poly1305_seal,
309 .open = aead_chacha20_poly1305_open,
310};
311
225const EVP_AEAD * 312const EVP_AEAD *
226EVP_aead_chacha20_poly1305() 313EVP_aead_chacha20_poly1305()
227{ 314{
228 return &aead_chacha20_poly1305; 315 return &aead_chacha20_poly1305;
229} 316}
230 317
318const EVP_AEAD *
319EVP_aead_chacha20_poly1305_ietf()
320{
321 return &aead_chacha20_poly1305_ietf;
322}
323
231#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ 324#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 @@
1/* $OpenBSD: evp.h,v 1.48 2015/09/14 01:45:03 doug Exp $ */ 1/* $OpenBSD: evp.h,v 1.49 2015/11/02 15:40:53 reyk 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 *
@@ -1215,6 +1215,7 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void);
1215#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 1215#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1216/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ 1216/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */
1217const EVP_AEAD *EVP_aead_chacha20_poly1305(void); 1217const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
1218const EVP_AEAD *EVP_aead_chacha20_poly1305_ietf(void);
1218#endif 1219#endif
1219 1220
1220/* EVP_AEAD_key_length returns the length of the keys used. */ 1221/* 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
@@ -134,6 +134,12 @@ aead_from_name(const EVP_AEAD **aead, const char *name)
134#else 134#else
135 fprintf(stderr, "No chacha20-poly1305 support.\n"); 135 fprintf(stderr, "No chacha20-poly1305 support.\n");
136#endif 136#endif
137 } else if (strcmp(name, "chacha20-poly1305-ietf") == 0) {
138#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
139 *aead = EVP_aead_chacha20_poly1305_ietf();
140#else
141 fprintf(stderr, "No chacha20-poly1305-ietf support.\n");
142#endif
137 } else { 143 } else {
138 fprintf(stderr, "Unknown AEAD: %s\n", name); 144 fprintf(stderr, "Unknown AEAD: %s\n", name);
139 return -1; 145 return -1;
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
659CT: d62561a166e0319d21dc9fd813b00343602fa8ac58cd0b6077dcc786af12c532478b14b5524f5f38feb24f05688d569ecdca190d330a7843ddd75928c67653c0e6742182ec214fc7b84e892c26a3aa9caea181c90b1c0e5f89e57151daeb6309b231dca9c3396b25b5c6d1cae376164aac5b392a4421f56d2fe6c7c109a562a533900c4d998127824b7b2066af5b2ab287f3a3751395d96bb0a81b2745543ccee1a806e5a623c8a088ec27f0346b9d01accf8192556c56fd3bee85d6fcef7f09383637f2e8d7fd3adf3d2d9f1c1eccde05b3b17eb6c99b1ca8be260ae1154e5658a5cd1e9e27d61915db081c2888fc37faa4a75294236b51c449f78881198c3bb702d4d3797b3cd958911060d606280f9ef74b7eef47517f1485291bfec5587d3dbae51fa26ea6f119e24ee72fc2e4e9db5c65aa20209492f504ad657333a7b29cb5ec6ff975ed7cbff20938bb02382276de32b8a21966946b8dcf297c3aacd25cf8903d3060aafd00ad19043e24cf17b404898d3f4aac02727d436a1e5bad07e6c07c88eb12664c1e38dfdf6e280347554629c8903ceb7703ad72eda21354bd963b9bdf05b4c126dc0e5f8d74dd2c45036fd0219e7f32124f27ab26e1d66d87a3c6e873a9c78505a5209265aa90b4a5f4acafe1443dcd3810c0455fa5c471e22a4d9623d34902abf310d414036b7773c8725534b4e03b6261d92346509a70b08e94eac0906d8e26e669a7dea38dfe2532af1167a133b75b4193acbef193dead0c08d65f2cfe7012afd9ee5452d714c6f1a2f810cd13ac2f36b6a1a4580154831a1098aa7ed3c506bebc24de46d7a03f6e 659CT: d62561a166e0319d21dc9fd813b00343602fa8ac58cd0b6077dcc786af12c532478b14b5524f5f38feb24f05688d569ecdca190d330a7843ddd75928c67653c0e6742182ec214fc7b84e892c26a3aa9caea181c90b1c0e5f89e57151daeb6309b231dca9c3396b25b5c6d1cae376164aac5b392a4421f56d2fe6c7c109a562a533900c4d998127824b7b2066af5b2ab287f3a3751395d96bb0a81b2745543ccee1a806e5a623c8a088ec27f0346b9d01accf8192556c56fd3bee85d6fcef7f09383637f2e8d7fd3adf3d2d9f1c1eccde05b3b17eb6c99b1ca8be260ae1154e5658a5cd1e9e27d61915db081c2888fc37faa4a75294236b51c449f78881198c3bb702d4d3797b3cd958911060d606280f9ef74b7eef47517f1485291bfec5587d3dbae51fa26ea6f119e24ee72fc2e4e9db5c65aa20209492f504ad657333a7b29cb5ec6ff975ed7cbff20938bb02382276de32b8a21966946b8dcf297c3aacd25cf8903d3060aafd00ad19043e24cf17b404898d3f4aac02727d436a1e5bad07e6c07c88eb12664c1e38dfdf6e280347554629c8903ceb7703ad72eda21354bd963b9bdf05b4c126dc0e5f8d74dd2c45036fd0219e7f32124f27ab26e1d66d87a3c6e873a9c78505a5209265aa90b4a5f4acafe1443dcd3810c0455fa5c471e22a4d9623d34902abf310d414036b7773c8725534b4e03b6261d92346509a70b08e94eac0906d8e26e669a7dea38dfe2532af1167a133b75b4193acbef193dead0c08d65f2cfe7012afd9ee5452d714c6f1a2f810cd13ac2f36b6a1a4580154831a1098aa7ed3c506bebc24de46d7a03f6e
660TAG: 1df6f94253edb794e81221d3bc838599 660TAG: 1df6f94253edb794e81221d3bc838599
661 661
662# Test vector from RFC7539 2.8.2
663AEAD: chacha20-poly1305-ietf
664KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
665NONCE: 070000004041424344454647
666IN: 4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e
667AD: 50515253c0c1c2c3c4c5c6c7
668CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116
669TAG: 1ae10b594f09e26a7e902ecbd0600691
670
671# Test vector from RFC7539 Appendix A.5
672AEAD: chacha20-poly1305-ietf
673KEY: 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
674NONCE: 000000000102030405060708
675IN: 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d
676AD: f33388860000000000004e91
677CT: 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b
678TAG: eead9d67890cbb22392336fea1851f38
679
680# Test vector from RFC7634 Appendix A
681AEAD: chacha20-poly1305-ietf
682KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
683NONCE: a0a1a2a31011121314151617
684IN: 45000054a6f200004001e778c6336405c000020508005b7a3a080000553bec100007362708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363701020204
685AD: 0102030400000005
686CT: 24039428b97f417e3c13753a4f05087b67c352e6a7fab1b982d466ef407ae5c614ee8099d52844eb61aa95dfab4c02f72aa71e7c4c4f64c9befe2facc638e8f3cbec163fac469b502773f6fb94e664da9165b82829f641e0
687TAG: 76aaa8266b7fb0f7b11b369907e1ad43
688
689# Test vector from RFC7634 Appendix B
690AEAD: chacha20-poly1305-ietf
691KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
692NONCE: a0a1a2a31011121314151617
693IN: 0000000c000040010000000a00
694AD: c0c1c2c3c4c5c6c7d0d1d2d3d4d5d6d72e202500000000090000004529000029
695CT: 610394701f8d017f7c12924889
696TAG: 6b71bfe25236efd7cdc67066906315b2
697