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 22typedef 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 36static 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 58static 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 128static 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 145const EVP_CIPHER *EVP_chacha20(void) 146{ 147 return &chacha20; 148} 149 150# ifndef OPENSSL_NO_POLY1305 151# include "crypto/poly1305.h" 152 153typedef 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 167static 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 207void *xor128_encrypt_n_pad(void *out, const void *inp, void *otp, size_t len); 208void *xor128_decrypt_n_pad(void *out, const void *inp, void *otp, size_t len); 209static const unsigned char zero[4 * CHACHA_BLK_SIZE] = { 0 }; 210# else 211static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 }; 212# endif 213 214static 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 361static const unsigned char zero[CHACHA_BLK_SIZE] = { 0 }; 362# endif 363 364static 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 488static 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 496static 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 609static 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 629const EVP_CIPHER *EVP_chacha20_poly1305(void) 630{ 631 return(&chacha20_poly1305); 632} 633# endif 634#endif 635