summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/Symbols.list1
-rw-r--r--src/lib/libcrypto/evp/e_chacha20poly1305.c107
-rw-r--r--src/lib/libcrypto/evp/evp.h3
3 files changed, 28 insertions, 83 deletions
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index 53aa96939a..d8e38c8f04 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1401,7 +1401,6 @@ EVP_add_digest
1401EVP_aead_aes_128_gcm 1401EVP_aead_aes_128_gcm
1402EVP_aead_aes_256_gcm 1402EVP_aead_aes_256_gcm
1403EVP_aead_chacha20_poly1305 1403EVP_aead_chacha20_poly1305
1404EVP_aead_chacha20_poly1305_old
1405EVP_aes_128_cbc 1404EVP_aes_128_cbc
1406EVP_aes_128_cbc_hmac_sha1 1405EVP_aes_128_cbc_hmac_sha1
1407EVP_aes_128_ccm 1406EVP_aes_128_ccm
diff --git a/src/lib/libcrypto/evp/e_chacha20poly1305.c b/src/lib/libcrypto/evp/e_chacha20poly1305.c
index b709c24270..089ef12fb3 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.17 2017/05/11 02:26:39 jsg Exp $ */ 1/* $OpenBSD: e_chacha20poly1305.c,v 1.18 2017/08/28 17:48:02 jsing Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org> 4 * Copyright (c) 2015 Reyk Floter <reyk@openbsd.org>
@@ -32,14 +32,7 @@
32#include "evp_locl.h" 32#include "evp_locl.h"
33 33
34#define POLY1305_TAG_LEN 16 34#define POLY1305_TAG_LEN 16
35#define CHACHA20_NONCE_LEN_OLD 8
36 35
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 has been already used in TLS. The IETF version also
41 * adds a constant (salt) that is prepended to the nonce.
42 */
43#define CHACHA20_CONSTANT_LEN 4 36#define CHACHA20_CONSTANT_LEN 4
44#define CHACHA20_IV_LEN 8 37#define CHACHA20_IV_LEN 8
45#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN) 38#define CHACHA20_NONCE_LEN (CHACHA20_CONSTANT_LEN + CHACHA20_IV_LEN)
@@ -155,35 +148,20 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
155 return 0; 148 return 0;
156 } 149 }
157 150
158 if (nonce_len == CHACHA20_NONCE_LEN_OLD) { 151 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
159 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ 152 nonce[2] << 16 | nonce[3] << 24) << 32;
160 153 iv = nonce + CHACHA20_CONSTANT_LEN;
161 memset(poly1305_key, 0, sizeof(poly1305_key)); 154
162 CRYPTO_chacha_20(poly1305_key, poly1305_key, 155 memset(poly1305_key, 0, sizeof(poly1305_key));
163 sizeof(poly1305_key), c20_ctx->key, nonce, 0); 156 CRYPTO_chacha_20(poly1305_key, poly1305_key,
164 157 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
165 CRYPTO_poly1305_init(&poly1305, poly1305_key); 158
166 poly1305_update_with_length(&poly1305, ad, ad_len); 159 CRYPTO_poly1305_init(&poly1305, poly1305_key);
167 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); 160 poly1305_update_with_pad16(&poly1305, ad, ad_len);
168 poly1305_update_with_length(&poly1305, out, in_len); 161 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
169 } else if (nonce_len == CHACHA20_NONCE_LEN) { 162 poly1305_update_with_pad16(&poly1305, out, in_len);
170 /* RFC 7539, May 2015 */ 163 poly1305_update_with_length(&poly1305, NULL, ad_len);
171 164 poly1305_update_with_length(&poly1305, NULL, in_len);
172 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
173 nonce[2] << 16 | nonce[3] << 24) << 32;
174 iv = nonce + CHACHA20_CONSTANT_LEN;
175
176 memset(poly1305_key, 0, sizeof(poly1305_key));
177 CRYPTO_chacha_20(poly1305_key, poly1305_key,
178 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
179
180 CRYPTO_poly1305_init(&poly1305, poly1305_key);
181 poly1305_update_with_pad16(&poly1305, ad, ad_len);
182 CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, iv, ctr + 1);
183 poly1305_update_with_pad16(&poly1305, out, in_len);
184 poly1305_update_with_length(&poly1305, NULL, ad_len);
185 poly1305_update_with_length(&poly1305, NULL, in_len);
186 }
187 165
188 if (c20_ctx->tag_len != POLY1305_TAG_LEN) { 166 if (c20_ctx->tag_len != POLY1305_TAG_LEN) {
189 unsigned char tag[POLY1305_TAG_LEN]; 167 unsigned char tag[POLY1305_TAG_LEN];
@@ -242,33 +220,19 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
242 return 0; 220 return 0;
243 } 221 }
244 222
245 if (nonce_len == CHACHA20_NONCE_LEN_OLD) { 223 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 |
246 /* Google's draft-agl-tls-chacha20poly1305-04, Nov 2013 */ 224 nonce[2] << 16 | nonce[3] << 24) << 32;
247 225 iv = nonce + CHACHA20_CONSTANT_LEN;
248 memset(poly1305_key, 0, sizeof(poly1305_key));
249 CRYPTO_chacha_20(poly1305_key, poly1305_key,
250 sizeof(poly1305_key), c20_ctx->key, nonce, 0);
251 226
252 CRYPTO_poly1305_init(&poly1305, poly1305_key); 227 memset(poly1305_key, 0, sizeof(poly1305_key));
253 poly1305_update_with_length(&poly1305, ad, ad_len); 228 CRYPTO_chacha_20(poly1305_key, poly1305_key,
254 poly1305_update_with_length(&poly1305, in, plaintext_len); 229 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
255 } else if (nonce_len == CHACHA20_NONCE_LEN) {
256 /* RFC 7539, May 2015 */
257 230
258 ctr = (uint64_t)(nonce[0] | nonce[1] << 8 | 231 CRYPTO_poly1305_init(&poly1305, poly1305_key);
259 nonce[2] << 16 | nonce[3] << 24) << 32; 232 poly1305_update_with_pad16(&poly1305, ad, ad_len);
260 iv = nonce + CHACHA20_CONSTANT_LEN; 233 poly1305_update_with_pad16(&poly1305, in, plaintext_len);
261 234 poly1305_update_with_length(&poly1305, NULL, ad_len);
262 memset(poly1305_key, 0, sizeof(poly1305_key)); 235 poly1305_update_with_length(&poly1305, NULL, plaintext_len);
263 CRYPTO_chacha_20(poly1305_key, poly1305_key,
264 sizeof(poly1305_key), c20_ctx->key, iv, ctr);
265
266 CRYPTO_poly1305_init(&poly1305, poly1305_key);
267 poly1305_update_with_pad16(&poly1305, ad, ad_len);
268 poly1305_update_with_pad16(&poly1305, in, plaintext_len);
269 poly1305_update_with_length(&poly1305, NULL, ad_len);
270 poly1305_update_with_length(&poly1305, NULL, plaintext_len);
271 }
272 236
273 CRYPTO_poly1305_finish(&poly1305, mac); 237 CRYPTO_poly1305_finish(&poly1305, mac);
274 238
@@ -282,6 +246,7 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
282 return 1; 246 return 1;
283} 247}
284 248
249/* RFC 7539 */
285static const EVP_AEAD aead_chacha20_poly1305 = { 250static const EVP_AEAD aead_chacha20_poly1305 = {
286 .key_len = 32, 251 .key_len = 32,
287 .nonce_len = CHACHA20_NONCE_LEN, 252 .nonce_len = CHACHA20_NONCE_LEN,
@@ -294,28 +259,10 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
294 .open = aead_chacha20_poly1305_open, 259 .open = aead_chacha20_poly1305_open,
295}; 260};
296 261
297static const EVP_AEAD aead_chacha20_poly1305_old = {
298 .key_len = 32,
299 .nonce_len = CHACHA20_NONCE_LEN_OLD,
300 .overhead = POLY1305_TAG_LEN,
301 .max_tag_len = POLY1305_TAG_LEN,
302
303 .init = aead_chacha20_poly1305_init,
304 .cleanup = aead_chacha20_poly1305_cleanup,
305 .seal = aead_chacha20_poly1305_seal,
306 .open = aead_chacha20_poly1305_open,
307};
308
309const EVP_AEAD * 262const EVP_AEAD *
310EVP_aead_chacha20_poly1305() 263EVP_aead_chacha20_poly1305()
311{ 264{
312 return &aead_chacha20_poly1305; 265 return &aead_chacha20_poly1305;
313} 266}
314 267
315const EVP_AEAD *
316EVP_aead_chacha20_poly1305_old()
317{
318 return &aead_chacha20_poly1305_old;
319}
320
321#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */ 268#endif /* !OPENSSL_NO_CHACHA && !OPENSSL_NO_POLY1305 */
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 68e1049587..853abe6b8e 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.52 2017/02/28 14:15:37 jsing Exp $ */ 1/* $OpenBSD: evp.h,v 1.53 2017/08/28 17:48:02 jsing 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 *
@@ -1222,7 +1222,6 @@ const EVP_AEAD *EVP_aead_aes_256_gcm(void);
1222#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 1222#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
1223/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */ 1223/* EVP_aead_chacha20_poly1305 is ChaCha20 with a Poly1305 authenticator. */
1224const EVP_AEAD *EVP_aead_chacha20_poly1305(void); 1224const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
1225const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void);
1226#endif 1225#endif
1227 1226
1228/* EVP_AEAD_key_length returns the length of the keys used. */ 1227/* EVP_AEAD_key_length returns the length of the keys used. */