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