1 /*
2 * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include "internal/endian.h"
13
14 #ifndef OPENSSL_NO_CHACHA
15
16 # include <openssl/evp.h>
17 # include <openssl/objects.h>
18 # include "crypto/evp.h"
19 # include "evp_local.h"
20 # include "crypto/chacha.h"
21
22 typedef struct {
23 union {
24 OSSL_UNION_ALIGN; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
25 unsigned int d[CHACHA_KEY_SIZE / 4];
26 } key;
27 unsigned int counter[CHACHA_CTR_SIZE / 4];
28 unsigned char buf[CHACHA_BLK_SIZE];
29 unsigned int partial_len;
30 } EVP_CHACHA_KEY;
31
32 #define data(ctx) ((EVP_CHACHA_KEY *)(ctx)->cipher_data)
33
34 #define CHACHA20_POLY1305_MAX_IVLEN 12
35
chacha_init_key(EVP_CIPHER_CTX * ctx,const unsigned char user_key[CHACHA_KEY_SIZE],const unsigned char iv[CHACHA_CTR_SIZE],int enc)36 static int chacha_init_key(EVP_CIPHER_CTX *ctx,
37 const unsigned char user_key[CHACHA_KEY_SIZE],
38 const unsigned char iv[CHACHA_CTR_SIZE], int enc)
39 {
40 EVP_CHACHA_KEY *key = data(ctx);
41 unsigned int i;
42
43 if (user_key)
44 for (i = 0; i < CHACHA_KEY_SIZE; i+=4) {
45 key->key.d[i/4] = CHACHA_U8TOU32(user_key+i);
46 }
47
48 if (iv)
49 for (i = 0; i < CHACHA_CTR_SIZE; i+=4) {
50 key->counter[i/4] = CHACHA_U8TOU32(iv+i);
51 }
52
53 key->partial_len = 0;
54
55 return 1;
56 }
57
chacha_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * inp,size_t len)58 static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
59 const unsigned char *inp, size_t len)
60 {
61 EVP_CHACHA_KEY *key = data(ctx);
62 unsigned int n, rem, ctr32;
63
64 if ((n = key->partial_len)) {
65 while (len && n < CHACHA_BLK_SIZE) {
66 *out++ = *inp++ ^ key->buf[n++];
67 len--;
68 }
69 key->partial_len = n;
70
71 if (len == 0)
72 return 1;
73
74 if (n == CHACHA_BLK_SIZE) {
75 key->partial_len = 0;
76 key->counter[0]++;
77 if (key->counter[0] == 0)
78 key->counter[1]++;
79 }
80 }
81
82 rem = (unsigned int)(len % CHACHA_BLK_SIZE);
83 len -= rem;
84 ctr32 = key->counter[0];
85 while (len >= CHACHA_BLK_SIZE) {
86 size_t blocks = len / CHACHA_BLK_SIZE;
87 /*
88 * 1<<28 is just a not-so-small yet not-so-large number...
89 * Below condition is practically never met, but it has to
90 * be checked for code correctness.
91 */
92 if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
93 blocks = (1U<<28);
94
95 /*
96 * As ChaCha20_ctr32 operates on 32-bit counter, caller
97 * has to handle overflow. 'if' below detects the
98 * overflow, which is then handled by limiting the
99 * amount of blocks to the exact overflow point...
100 */
101 ctr32 += (unsigned int)blocks;
102 if (ctr32 < blocks) {
103 blocks -= ctr32;
104 ctr32 = 0;
105 }
106 blocks *= CHACHA_BLK_SIZE;
107 ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter);
108 len -= blocks;
109 inp += blocks;
110 out += blocks;
111
112 key->counter[0] = ctr32;
113 if (ctr32 == 0) key->counter[1]++;
114 }
115
116 if (rem) {
117 memset(key->buf, 0, sizeof(key->buf));
118 ChaCha20_ctr32(key->buf, key->buf, CHACHA_BLK_SIZE,
119 key->key.d, key->counter);
120 for (n = 0; n < rem; n++)
121 out[n] = inp[n] ^ key->buf[n];
122 key->partial_len = rem;
123 }
124
125 return 1;
126 }
127
128 static const EVP_CIPHER chacha20 = {
129 NID_chacha20,
130 1, /* block_size */
131 CHACHA_KEY_SIZE, /* key_len */
132 CHACHA_CTR_SIZE, /* iv_len, 128-bit counter in the context */
133 EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT,
134 EVP_ORIG_GLOBAL,
135 chacha_init_key,
136 chacha_cipher,
137 NULL,
138 sizeof(EVP_CHACHA_KEY),
139 NULL,
140 NULL,
141 NULL,
142 NULL
143 };
144
EVP_chacha20(void)145 const EVP_CIPHER *EVP_chacha20(void)
146 {
147 return &chacha20;
148 }
149
150 # ifndef OPENSSL_NO_POLY1305
151 # include "crypto/poly1305.h"
152
153 typedef struct {
154 EVP_CHACHA_KEY key;
155 unsigned int nonce[12/4];
156 unsigned char tag[POLY1305_BLOCK_SIZE];
157 unsigned char tls_aad[POLY1305_BLOCK_SIZE];
158 struct { uint64_t aad, text; } len;
159 int aad, mac_inited, tag_len, nonce_len;
160 size_t tls_payload_length;
161 } EVP_CHACHA_AEAD_CTX;
162
163 # define NO_TLS_PAYLOAD_LENGTH ((size_t)-1)
164 # define aead_data(ctx) ((EVP_CHACHA_AEAD_CTX *)(ctx)->cipher_data)
165 # define POLY1305_ctx(actx) ((POLY1305 *)(actx + 1))
166
chacha20_poly1305_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * inkey,const unsigned char * iv,int enc)167 static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
168 const unsigned char *inkey,
169 const unsigned char *iv, int enc)
170 {
171 EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
172
173 if (!inkey && !iv)
174 return 1;
175
176 actx->len.aad = 0;
177 actx->len.text = 0;
178 actx->aad = 0;
179 actx->mac_inited = 0;
180 actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
181
182 if (iv != NULL) {
183 unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
184
185 /* pad on the left */
186 if (actx->nonce_len <= CHACHA_CTR_SIZE)
187 memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv,
188 actx->nonce_len);
189
190 chacha_init_key(ctx, inkey, temp, enc);
191
192 actx->nonce[0] = actx->key.counter[1];
193 actx->nonce[1] = actx->key.counter[2];
194 actx->nonce[2] = actx->key.counter[3];
195 } else {
196 chacha_init_key(ctx, inkey, NULL, enc);
197 }
198
199 return 1;
200 }
201
202 # if !defined(OPENSSL_SMALL_FOOTPRINT)
203
204 # if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
205 defined(_M_AMD64) || defined(_M_X64))
206 # define XOR128_HELPERS
207 void *xor128_encrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
208 void *xor128_decrypt_n_pad(void *out, const void *inp, void *otp, size_t len);
209 static const unsigned char zero[4 * CHACHA_BLK_SIZE] = { 0 };
210 # else
211 static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 };
212 # endif
213
chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)214 static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
215 const unsigned char *in, size_t len)
216 {
217 EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
218 size_t tail, tohash_len, buf_len, plen = actx->tls_payload_length;
219 unsigned char *buf, *tohash, *ctr, storage[sizeof(zero) + 32];
220
221 if (len != plen + POLY1305_BLOCK_SIZE)
222 return -1;
223
224 buf = storage + ((0 - (size_t)storage) & 15); /* align */
225 ctr = buf + CHACHA_BLK_SIZE;
226 tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_SIZE;
227
228 # ifdef XOR128_HELPERS
229 if (plen <= 3 * CHACHA_BLK_SIZE) {
230 actx->key.counter[0] = 0;
231 buf_len = (plen + 2 * CHACHA_BLK_SIZE - 1) & (0 - CHACHA_BLK_SIZE);
232 ChaCha20_ctr32(buf, zero, buf_len, actx->key.key.d,
233 actx->key.counter);
234 Poly1305_Init(POLY1305_ctx(actx), buf);
235 actx->key.partial_len = 0;
236 memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
237 tohash_len = POLY1305_BLOCK_SIZE;
238 actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
239 actx->len.text = plen;
240
241 if (plen) {
242 if (ctx->encrypt)
243 ctr = xor128_encrypt_n_pad(out, in, ctr, plen);
244 else
245 ctr = xor128_decrypt_n_pad(out, in, ctr, plen);
246
247 in += plen;
248 out += plen;
249 tohash_len = (size_t)(ctr - tohash);
250 }
251 }
252 # else
253 if (plen <= CHACHA_BLK_SIZE) {
254 size_t i;
255
256 actx->key.counter[0] = 0;
257 ChaCha20_ctr32(buf, zero, (buf_len = 2 * CHACHA_BLK_SIZE),
258 actx->key.key.d, actx->key.counter);
259 Poly1305_Init(POLY1305_ctx(actx), buf);
260 actx->key.partial_len = 0;
261 memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
262 tohash_len = POLY1305_BLOCK_SIZE;
263 actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
264 actx->len.text = plen;
265
266 if (ctx->encrypt) {
267 for (i = 0; i < plen; i++) {
268 out[i] = ctr[i] ^= in[i];
269 }
270 } else {
271 for (i = 0; i < plen; i++) {
272 unsigned char c = in[i];
273 out[i] = ctr[i] ^ c;
274 ctr[i] = c;
275 }
276 }
277
278 in += i;
279 out += i;
280
281 tail = (0 - i) & (POLY1305_BLOCK_SIZE - 1);
282 memset(ctr + i, 0, tail);
283 ctr += i + tail;
284 tohash_len += i + tail;
285 }
286 # endif
287 else {
288 actx->key.counter[0] = 0;
289 ChaCha20_ctr32(buf, zero, (buf_len = CHACHA_BLK_SIZE),
290 actx->key.key.d, actx->key.counter);
291 Poly1305_Init(POLY1305_ctx(actx), buf);
292 actx->key.counter[0] = 1;
293 actx->key.partial_len = 0;
294 Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad, POLY1305_BLOCK_SIZE);
295 tohash = ctr;
296 tohash_len = 0;
297 actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
298 actx->len.text = plen;
299
300 if (ctx->encrypt) {
301 ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
302 Poly1305_Update(POLY1305_ctx(actx), out, plen);
303 } else {
304 Poly1305_Update(POLY1305_ctx(actx), in, plen);
305 ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
306 }
307
308 in += plen;
309 out += plen;
310 tail = (0 - plen) & (POLY1305_BLOCK_SIZE - 1);
311 Poly1305_Update(POLY1305_ctx(actx), zero, tail);
312 }
313
314 {
315 DECLARE_IS_ENDIAN;
316
317 if (IS_LITTLE_ENDIAN) {
318 memcpy(ctr, (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
319 } else {
320 ctr[0] = (unsigned char)(actx->len.aad);
321 ctr[1] = (unsigned char)(actx->len.aad>>8);
322 ctr[2] = (unsigned char)(actx->len.aad>>16);
323 ctr[3] = (unsigned char)(actx->len.aad>>24);
324 ctr[4] = (unsigned char)(actx->len.aad>>32);
325 ctr[5] = (unsigned char)(actx->len.aad>>40);
326 ctr[6] = (unsigned char)(actx->len.aad>>48);
327 ctr[7] = (unsigned char)(actx->len.aad>>56);
328
329 ctr[8] = (unsigned char)(actx->len.text);
330 ctr[9] = (unsigned char)(actx->len.text>>8);
331 ctr[10] = (unsigned char)(actx->len.text>>16);
332 ctr[11] = (unsigned char)(actx->len.text>>24);
333 ctr[12] = (unsigned char)(actx->len.text>>32);
334 ctr[13] = (unsigned char)(actx->len.text>>40);
335 ctr[14] = (unsigned char)(actx->len.text>>48);
336 ctr[15] = (unsigned char)(actx->len.text>>56);
337 }
338 tohash_len += POLY1305_BLOCK_SIZE;
339 }
340
341 Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len);
342 OPENSSL_cleanse(buf, buf_len);
343 Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
344 : tohash);
345
346 actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
347
348 if (ctx->encrypt) {
349 memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
350 } else {
351 if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) {
352 memset(out - (len - POLY1305_BLOCK_SIZE), 0,
353 len - POLY1305_BLOCK_SIZE);
354 return -1;
355 }
356 }
357
358 return len;
359 }
360 # else
361 static const unsigned char zero[CHACHA_BLK_SIZE] = { 0 };
362 # endif
363
chacha20_poly1305_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t len)364 static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
365 const unsigned char *in, size_t len)
366 {
367 EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
368 size_t rem, plen = actx->tls_payload_length;
369
370 if (!actx->mac_inited) {
371 # if !defined(OPENSSL_SMALL_FOOTPRINT)
372 if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL)
373 return chacha20_poly1305_tls_cipher(ctx, out, in, len);
374 # endif
375 actx->key.counter[0] = 0;
376 ChaCha20_ctr32(actx->key.buf, zero, CHACHA_BLK_SIZE,
377 actx->key.key.d, actx->key.counter);
378 Poly1305_Init(POLY1305_ctx(actx), actx->key.buf);
379 actx->key.counter[0] = 1;
380 actx->key.partial_len = 0;
381 actx->len.aad = actx->len.text = 0;
382 actx->mac_inited = 1;
383 if (plen != NO_TLS_PAYLOAD_LENGTH) {
384 Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad,
385 EVP_AEAD_TLS1_AAD_LEN);
386 actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
387 actx->aad = 1;
388 }
389 }
390
391 if (in) { /* aad or text */
392 if (out == NULL) { /* aad */
393 Poly1305_Update(POLY1305_ctx(actx), in, len);
394 actx->len.aad += len;
395 actx->aad = 1;
396 return len;
397 } else { /* plain- or ciphertext */
398 if (actx->aad) { /* wrap up aad */
399 if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
400 Poly1305_Update(POLY1305_ctx(actx), zero,
401 POLY1305_BLOCK_SIZE - rem);
402 actx->aad = 0;
403 }
404
405 actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
406 if (plen == NO_TLS_PAYLOAD_LENGTH)
407 plen = len;
408 else if (len != plen + POLY1305_BLOCK_SIZE)
409 return -1;
410
411 if (ctx->encrypt) { /* plaintext */
412 chacha_cipher(ctx, out, in, plen);
413 Poly1305_Update(POLY1305_ctx(actx), out, plen);
414 in += plen;
415 out += plen;
416 actx->len.text += plen;
417 } else { /* ciphertext */
418 Poly1305_Update(POLY1305_ctx(actx), in, plen);
419 chacha_cipher(ctx, out, in, plen);
420 in += plen;
421 out += plen;
422 actx->len.text += plen;
423 }
424 }
425 }
426 if (in == NULL /* explicit final */
427 || plen != len) { /* or tls mode */
428 DECLARE_IS_ENDIAN;
429 unsigned char temp[POLY1305_BLOCK_SIZE];
430
431 if (actx->aad) { /* wrap up aad */
432 if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
433 Poly1305_Update(POLY1305_ctx(actx), zero,
434 POLY1305_BLOCK_SIZE - rem);
435 actx->aad = 0;
436 }
437
438 if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
439 Poly1305_Update(POLY1305_ctx(actx), zero,
440 POLY1305_BLOCK_SIZE - rem);
441
442 if (IS_LITTLE_ENDIAN) {
443 Poly1305_Update(POLY1305_ctx(actx),
444 (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
445 } else {
446 temp[0] = (unsigned char)(actx->len.aad);
447 temp[1] = (unsigned char)(actx->len.aad>>8);
448 temp[2] = (unsigned char)(actx->len.aad>>16);
449 temp[3] = (unsigned char)(actx->len.aad>>24);
450 temp[4] = (unsigned char)(actx->len.aad>>32);
451 temp[5] = (unsigned char)(actx->len.aad>>40);
452 temp[6] = (unsigned char)(actx->len.aad>>48);
453 temp[7] = (unsigned char)(actx->len.aad>>56);
454
455 temp[8] = (unsigned char)(actx->len.text);
456 temp[9] = (unsigned char)(actx->len.text>>8);
457 temp[10] = (unsigned char)(actx->len.text>>16);
458 temp[11] = (unsigned char)(actx->len.text>>24);
459 temp[12] = (unsigned char)(actx->len.text>>32);
460 temp[13] = (unsigned char)(actx->len.text>>40);
461 temp[14] = (unsigned char)(actx->len.text>>48);
462 temp[15] = (unsigned char)(actx->len.text>>56);
463
464 Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
465 }
466 Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
467 : temp);
468 actx->mac_inited = 0;
469
470 if (in != NULL && len != plen) { /* tls mode */
471 if (ctx->encrypt) {
472 memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
473 } else {
474 if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) {
475 memset(out - plen, 0, plen);
476 return -1;
477 }
478 }
479 }
480 else if (!ctx->encrypt) {
481 if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len))
482 return -1;
483 }
484 }
485 return len;
486 }
487
chacha20_poly1305_cleanup(EVP_CIPHER_CTX * ctx)488 static int chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
489 {
490 EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
491 if (actx)
492 OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size());
493 return 1;
494 }
495
chacha20_poly1305_ctrl(EVP_CIPHER_CTX * ctx,int type,int arg,void * ptr)496 static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
497 void *ptr)
498 {
499 EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
500
501 switch(type) {
502 case EVP_CTRL_INIT:
503 if (actx == NULL)
504 actx = ctx->cipher_data
505 = OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size());
506 if (actx == NULL) {
507 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
508 return 0;
509 }
510 actx->len.aad = 0;
511 actx->len.text = 0;
512 actx->aad = 0;
513 actx->mac_inited = 0;
514 actx->tag_len = 0;
515 actx->nonce_len = 12;
516 actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
517 memset(actx->tls_aad, 0, POLY1305_BLOCK_SIZE);
518 return 1;
519
520 case EVP_CTRL_COPY:
521 if (actx) {
522 EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr;
523
524 dst->cipher_data =
525 OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size());
526 if (dst->cipher_data == NULL) {
527 ERR_raise(ERR_LIB_EVP, EVP_R_COPY_ERROR);
528 return 0;
529 }
530 }
531 return 1;
532
533 case EVP_CTRL_GET_IVLEN:
534 *(int *)ptr = actx->nonce_len;
535 return 1;
536
537 case EVP_CTRL_AEAD_SET_IVLEN:
538 if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN)
539 return 0;
540 actx->nonce_len = arg;
541 return 1;
542
543 case EVP_CTRL_AEAD_SET_IV_FIXED:
544 if (arg != 12)
545 return 0;
546 actx->nonce[0] = actx->key.counter[1]
547 = CHACHA_U8TOU32((unsigned char *)ptr);
548 actx->nonce[1] = actx->key.counter[2]
549 = CHACHA_U8TOU32((unsigned char *)ptr+4);
550 actx->nonce[2] = actx->key.counter[3]
551 = CHACHA_U8TOU32((unsigned char *)ptr+8);
552 return 1;
553
554 case EVP_CTRL_AEAD_SET_TAG:
555 if (arg <= 0 || arg > POLY1305_BLOCK_SIZE)
556 return 0;
557 if (ptr != NULL) {
558 memcpy(actx->tag, ptr, arg);
559 actx->tag_len = arg;
560 }
561 return 1;
562
563 case EVP_CTRL_AEAD_GET_TAG:
564 if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !ctx->encrypt)
565 return 0;
566 memcpy(ptr, actx->tag, arg);
567 return 1;
568
569 case EVP_CTRL_AEAD_TLS1_AAD:
570 if (arg != EVP_AEAD_TLS1_AAD_LEN)
571 return 0;
572 {
573 unsigned int len;
574 unsigned char *aad = ptr;
575
576 memcpy(actx->tls_aad, ptr, EVP_AEAD_TLS1_AAD_LEN);
577 len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 |
578 aad[EVP_AEAD_TLS1_AAD_LEN - 1];
579 aad = actx->tls_aad;
580 if (!ctx->encrypt) {
581 if (len < POLY1305_BLOCK_SIZE)
582 return 0;
583 len -= POLY1305_BLOCK_SIZE; /* discount attached tag */
584 aad[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
585 aad[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
586 }
587 actx->tls_payload_length = len;
588
589 /*
590 * merge record sequence number as per RFC7905
591 */
592 actx->key.counter[1] = actx->nonce[0];
593 actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);
594 actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad+4);
595 actx->mac_inited = 0;
596
597 return POLY1305_BLOCK_SIZE; /* tag length */
598 }
599
600 case EVP_CTRL_AEAD_SET_MAC_KEY:
601 /* no-op */
602 return 1;
603
604 default:
605 return -1;
606 }
607 }
608
609 static EVP_CIPHER chacha20_poly1305 = {
610 NID_chacha20_poly1305,
611 1, /* block_size */
612 CHACHA_KEY_SIZE, /* key_len */
613 12, /* iv_len, 96-bit nonce in the context */
614 EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
615 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
616 EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER |
617 EVP_CIPH_CUSTOM_IV_LENGTH,
618 EVP_ORIG_GLOBAL,
619 chacha20_poly1305_init_key,
620 chacha20_poly1305_cipher,
621 chacha20_poly1305_cleanup,
622 0, /* 0 moves context-specific structure allocation to ctrl */
623 NULL, /* set_asn1_parameters */
624 NULL, /* get_asn1_parameters */
625 chacha20_poly1305_ctrl,
626 NULL /* app_data */
627 };
628
EVP_chacha20_poly1305(void)629 const EVP_CIPHER *EVP_chacha20_poly1305(void)
630 {
631 return(&chacha20_poly1305);
632 }
633 # endif
634 #endif
635