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