1/* 2 * Copyright 2011-2025 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{- 10use OpenSSL::paramnames qw(produce_param_decoder); 11-} 12 13#include <stdlib.h> 14#include <string.h> 15#include <openssl/crypto.h> 16#include <openssl/err.h> 17#include <openssl/rand.h> 18#include <openssl/aes.h> 19#include <openssl/proverr.h> 20#include "crypto/modes.h" 21#include "internal/thread_once.h" 22#include "prov/implementations.h" 23#include "prov/providercommon.h" 24#include "prov/provider_ctx.h" 25#include "prov/drbg.h" 26#include "crypto/evp.h" 27#include "crypto/evp/evp_local.h" 28#include "internal/provider.h" 29#include "internal/common.h" 30 31static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper; 32static OSSL_FUNC_rand_freectx_fn drbg_ctr_free; 33static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper; 34static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper; 35static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper; 36static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper; 37static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params; 38static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params; 39static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params; 40static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params; 41static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization; 42 43static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *drbg, 44 const struct drbg_set_ctx_params_st *p); 45static int drbg_ctr_set_ctx_params_decoder(const OSSL_PARAM params[], 46 struct drbg_set_ctx_params_st *p); 47 48/* 49 * The state of a DRBG AES-CTR. 50 */ 51typedef struct rand_drbg_ctr_st { 52 EVP_CIPHER_CTX *ctx_ecb; 53 EVP_CIPHER_CTX *ctx_ctr; 54 EVP_CIPHER_CTX *ctx_df; 55 EVP_CIPHER *cipher_ecb; 56 EVP_CIPHER *cipher_ctr; 57 size_t keylen; 58 int use_df; 59 unsigned char K[32]; 60 unsigned char V[16]; 61 /* Temporary block storage used by ctr_df */ 62 unsigned char bltmp[16]; 63 size_t bltmp_pos; 64 unsigned char KX[48]; 65} PROV_DRBG_CTR; 66 67/* 68 * Implementation of NIST SP 800-90A CTR DRBG. 69 */ 70static void inc_128(PROV_DRBG_CTR *ctr) 71{ 72 unsigned char *p = &ctr->V[0]; 73 u32 n = 16, c = 1; 74 75 do { 76 --n; 77 c += p[n]; 78 p[n] = (u8)c; 79 c >>= 8; 80 } while (n); 81} 82 83static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen) 84{ 85 size_t i, n; 86 87 if (in == NULL || inlen == 0) 88 return; 89 90 /* 91 * Any zero padding will have no effect on the result as we 92 * are XORing. So just process however much input we have. 93 */ 94 n = inlen < ctr->keylen ? inlen : ctr->keylen; 95 if (!ossl_assert(n <= sizeof(ctr->K))) 96 return; 97 for (i = 0; i < n; i++) 98 ctr->K[i] ^= in[i]; 99 if (inlen <= ctr->keylen) 100 return; 101 102 n = inlen - ctr->keylen; 103 if (n > 16) { 104 /* Should never happen */ 105 n = 16; 106 } 107 for (i = 0; i < n; i++) 108 ctr->V[i] ^= in[i + ctr->keylen]; 109} 110 111/* 112 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3 113 */ 114__owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out, 115 const unsigned char *in, int len) 116{ 117 int i, outlen = AES_BLOCK_SIZE; 118 119 for (i = 0; i < len; i++) 120 out[i] ^= in[i]; 121 122 if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len) 123 || outlen != len) 124 return 0; 125 return 1; 126} 127 128 129/* 130 * Handle several BCC operations for as much data as we need for K and X 131 */ 132__owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in) 133{ 134 unsigned char in_tmp[48]; 135 unsigned char num_of_blk = 2; 136 137 memcpy(in_tmp, in, 16); 138 memcpy(in_tmp + 16, in, 16); 139 if (ctr->keylen != 16) { 140 memcpy(in_tmp + 32, in, 16); 141 num_of_blk = 3; 142 } 143 return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk); 144} 145 146/* 147 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions: 148 * see 10.3.1 stage 7. 149 */ 150__owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr) 151{ 152 unsigned char bltmp[48] = {0}; 153 unsigned char num_of_blk; 154 155 memset(ctr->KX, 0, 48); 156 num_of_blk = ctr->keylen == 16 ? 2 : 3; 157 bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1; 158 bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2; 159 return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE); 160} 161 162/* 163 * Process several blocks into BCC algorithm, some possibly partial 164 */ 165__owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr, 166 const unsigned char *in, size_t inlen) 167{ 168 if (in == NULL || inlen == 0) 169 return 1; 170 171 /* If we have partial block handle it first */ 172 if (ctr->bltmp_pos) { 173 size_t left = 16 - ctr->bltmp_pos; 174 175 /* If we now have a complete block process it */ 176 if (inlen >= left) { 177 memcpy(ctr->bltmp + ctr->bltmp_pos, in, left); 178 if (!ctr_BCC_blocks(ctr, ctr->bltmp)) 179 return 0; 180 ctr->bltmp_pos = 0; 181 inlen -= left; 182 in += left; 183 } 184 } 185 186 /* Process zero or more complete blocks */ 187 for (; inlen >= 16; in += 16, inlen -= 16) { 188 if (!ctr_BCC_blocks(ctr, in)) 189 return 0; 190 } 191 192 /* Copy any remaining partial block to the temporary buffer */ 193 if (inlen > 0) { 194 memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen); 195 ctr->bltmp_pos += inlen; 196 } 197 return 1; 198} 199 200__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr) 201{ 202 if (ctr->bltmp_pos) { 203 memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos); 204 if (!ctr_BCC_blocks(ctr, ctr->bltmp)) 205 return 0; 206 } 207 return 1; 208} 209 210__owur static int ctr_df(PROV_DRBG_CTR *ctr, 211 const unsigned char *in1, size_t in1len, 212 const unsigned char *in2, size_t in2len, 213 const unsigned char *in3, size_t in3len) 214{ 215 static unsigned char c80 = 0x80; 216 size_t inlen; 217 unsigned char *p = ctr->bltmp; 218 int outlen = AES_BLOCK_SIZE; 219 220 if (!ctr_BCC_init(ctr)) 221 return 0; 222 if (in1 == NULL) 223 in1len = 0; 224 if (in2 == NULL) 225 in2len = 0; 226 if (in3 == NULL) 227 in3len = 0; 228 inlen = in1len + in2len + in3len; 229 /* Initialise L||N in temporary block */ 230 *p++ = (inlen >> 24) & 0xff; 231 *p++ = (inlen >> 16) & 0xff; 232 *p++ = (inlen >> 8) & 0xff; 233 *p++ = inlen & 0xff; 234 235 /* NB keylen is at most 32 bytes */ 236 *p++ = 0; 237 *p++ = 0; 238 *p++ = 0; 239 *p = (unsigned char)((ctr->keylen + 16) & 0xff); 240 ctr->bltmp_pos = 8; 241 if (!ctr_BCC_update(ctr, in1, in1len) 242 || !ctr_BCC_update(ctr, in2, in2len) 243 || !ctr_BCC_update(ctr, in3, in3len) 244 || !ctr_BCC_update(ctr, &c80, 1) 245 || !ctr_BCC_final(ctr)) 246 return 0; 247 /* Set up key K */ 248 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1)) 249 return 0; 250 /* X follows key K */ 251 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen, 252 AES_BLOCK_SIZE) 253 || outlen != AES_BLOCK_SIZE) 254 return 0; 255 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX, 256 AES_BLOCK_SIZE) 257 || outlen != AES_BLOCK_SIZE) 258 return 0; 259 if (ctr->keylen != 16) 260 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen, 261 ctr->KX + 16, AES_BLOCK_SIZE) 262 || outlen != AES_BLOCK_SIZE) 263 return 0; 264 return 1; 265} 266 267/* 268 * NB the no-df Update in SP800-90A specifies a constant input length 269 * of seedlen, however other uses of this algorithm pad the input with 270 * zeroes if necessary and have up to two parameters XORed together, 271 * so we handle both cases in this function instead. 272 */ 273__owur static int ctr_update(PROV_DRBG *drbg, 274 const unsigned char *in1, size_t in1len, 275 const unsigned char *in2, size_t in2len, 276 const unsigned char *nonce, size_t noncelen) 277{ 278 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 279 int outlen = AES_BLOCK_SIZE; 280 unsigned char V_tmp[48], out[48]; 281 unsigned char len; 282 283 /* correct key is already set up. */ 284 memcpy(V_tmp, ctr->V, 16); 285 inc_128(ctr); 286 memcpy(V_tmp + 16, ctr->V, 16); 287 if (ctr->keylen == 16) { 288 len = 32; 289 } else { 290 inc_128(ctr); 291 memcpy(V_tmp + 32, ctr->V, 16); 292 len = 48; 293 } 294 if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len) 295 || outlen != len) 296 return 0; 297 memcpy(ctr->K, out, ctr->keylen); 298 memcpy(ctr->V, out + ctr->keylen, 16); 299 300 if (ctr->use_df) { 301 /* If no input reuse existing derived value */ 302 if (in1 != NULL || nonce != NULL || in2 != NULL) 303 if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len)) 304 return 0; 305 /* If this a reuse input in1len != 0 */ 306 if (in1len) 307 ctr_XOR(ctr, ctr->KX, drbg->seedlen); 308 } else { 309 ctr_XOR(ctr, in1, in1len); 310 ctr_XOR(ctr, in2, in2len); 311 } 312 313 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1) 314 || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1)) 315 return 0; 316 return 1; 317} 318 319static int drbg_ctr_instantiate(PROV_DRBG *drbg, 320 const unsigned char *entropy, size_t entropylen, 321 const unsigned char *nonce, size_t noncelen, 322 const unsigned char *pers, size_t perslen) 323{ 324 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 325 326 if (entropy == NULL) 327 return 0; 328 329 memset(ctr->K, 0, sizeof(ctr->K)); 330 memset(ctr->V, 0, sizeof(ctr->V)); 331 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)) 332 return 0; 333 334 inc_128(ctr); 335 if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen)) 336 return 0; 337 return 1; 338} 339 340static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength, 341 int prediction_resistance, 342 const unsigned char *pstr, 343 size_t pstr_len, 344 const OSSL_PARAM params[]) 345{ 346 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 347 struct drbg_set_ctx_params_st p; 348 int ret = 0; 349 350 if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p)) 351 return 0; 352 353 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) 354 return 0; 355 356 if (!ossl_prov_is_running() 357 || !drbg_ctr_set_ctx_params_locked(drbg, &p)) 358 goto err; 359 ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, 360 pstr, pstr_len); 361 err: 362 if (drbg->lock != NULL) 363 CRYPTO_THREAD_unlock(drbg->lock); 364 return ret; 365} 366 367static int drbg_ctr_reseed(PROV_DRBG *drbg, 368 const unsigned char *entropy, size_t entropylen, 369 const unsigned char *adin, size_t adinlen) 370{ 371 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 372 373 if (entropy == NULL) 374 return 0; 375 376 inc_128(ctr); 377 if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0)) 378 return 0; 379 return 1; 380} 381 382static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance, 383 const unsigned char *ent, size_t ent_len, 384 const unsigned char *adin, size_t adin_len) 385{ 386 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 387 388 return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len, 389 adin, adin_len); 390} 391 392static void ctr96_inc(unsigned char *counter) 393{ 394 u32 n = 12, c = 1; 395 396 do { 397 --n; 398 c += counter[n]; 399 counter[n] = (u8)c; 400 c >>= 8; 401 } while (n); 402} 403 404static int drbg_ctr_generate(PROV_DRBG *drbg, 405 unsigned char *out, size_t outlen, 406 const unsigned char *adin, size_t adinlen) 407{ 408 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 409 unsigned int ctr32, blocks; 410 int outl, buflen; 411 412 if (adin != NULL && adinlen != 0) { 413 inc_128(ctr); 414 415 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) 416 return 0; 417 /* This means we reuse derived value */ 418 if (ctr->use_df) { 419 adin = NULL; 420 adinlen = 1; 421 } 422 } else { 423 adinlen = 0; 424 } 425 426 inc_128(ctr); 427 428 if (outlen == 0) { 429 inc_128(ctr); 430 431 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) 432 return 0; 433 return 1; 434 } 435 436 memset(out, 0, outlen); 437 438 do { 439 if (!EVP_CipherInit_ex(ctr->ctx_ctr, 440 NULL, NULL, NULL, ctr->V, -1)) 441 return 0; 442 443 /*- 444 * outlen has type size_t while EVP_CipherUpdate takes an 445 * int argument and thus cannot be guaranteed to process more 446 * than 2^31-1 bytes at a time. We process such huge generate 447 * requests in 2^30 byte chunks, which is the greatest multiple 448 * of AES block size lower than or equal to 2^31-1. 449 */ 450 buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen; 451 blocks = (buflen + 15) / 16; 452 453 ctr32 = GETU32(ctr->V + 12) + blocks; 454 if (ctr32 < blocks) { 455 /* 32-bit counter overflow into V. */ 456 if (ctr32 != 0) { 457 blocks -= ctr32; 458 buflen = blocks * 16; 459 ctr32 = 0; 460 } 461 ctr96_inc(ctr->V); 462 } 463 PUTU32(ctr->V + 12, ctr32); 464 465 if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen) 466 || outl != buflen) 467 return 0; 468 469 out += buflen; 470 outlen -= buflen; 471 } while (outlen); 472 473 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0)) 474 return 0; 475 return 1; 476} 477 478static int drbg_ctr_generate_wrapper 479 (void *vdrbg, unsigned char *out, size_t outlen, 480 unsigned int strength, int prediction_resistance, 481 const unsigned char *adin, size_t adin_len) 482{ 483 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 484 485 return ossl_prov_drbg_generate(drbg, out, outlen, strength, 486 prediction_resistance, adin, adin_len); 487} 488 489static int drbg_ctr_uninstantiate(PROV_DRBG *drbg) 490{ 491 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 492 493 OPENSSL_cleanse(ctr->K, sizeof(ctr->K)); 494 OPENSSL_cleanse(ctr->V, sizeof(ctr->V)); 495 OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp)); 496 OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX)); 497 ctr->bltmp_pos = 0; 498 return ossl_prov_drbg_uninstantiate(drbg); 499} 500 501static int drbg_ctr_uninstantiate_wrapper(void *vdrbg) 502{ 503 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 504 int ret; 505 506 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) 507 return 0; 508 509 ret = drbg_ctr_uninstantiate(drbg); 510 511 if (drbg->lock != NULL) 512 CRYPTO_THREAD_unlock(drbg->lock); 513 514 return ret; 515} 516 517static int drbg_ctr_verify_zeroization(void *vdrbg) 518{ 519 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 520 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 521 int ret = 0; 522 523 if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) 524 return 0; 525 526 PROV_DRBG_VERIFY_ZEROIZATION(ctr->K); 527 PROV_DRBG_VERIFY_ZEROIZATION(ctr->V); 528 PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp); 529 PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX); 530 if (ctr->bltmp_pos != 0) 531 goto err; 532 533 ret = 1; 534 err: 535 if (drbg->lock != NULL) 536 CRYPTO_THREAD_unlock(drbg->lock); 537 return ret; 538} 539 540static int drbg_ctr_init_lengths(PROV_DRBG *drbg) 541{ 542 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 543 int res = 1; 544 545 /* Maximum number of bits per request = 2^19 = 2^16 bytes */ 546 drbg->max_request = 1 << 16; 547 if (ctr->use_df) { 548 drbg->min_entropylen = 0; 549 drbg->max_entropylen = DRBG_MAX_LENGTH; 550 drbg->min_noncelen = 0; 551 drbg->max_noncelen = DRBG_MAX_LENGTH; 552 drbg->max_perslen = DRBG_MAX_LENGTH; 553 drbg->max_adinlen = DRBG_MAX_LENGTH; 554 555 if (ctr->keylen > 0) { 556 drbg->min_entropylen = ctr->keylen; 557 drbg->min_noncelen = drbg->min_entropylen / 2; 558 } 559 } else { 560 const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH; 561 562 drbg->min_entropylen = len; 563 drbg->max_entropylen = len; 564 /* Nonce not used */ 565 drbg->min_noncelen = 0; 566 drbg->max_noncelen = 0; 567 drbg->max_perslen = len; 568 drbg->max_adinlen = len; 569 } 570 return res; 571} 572 573static int drbg_ctr_init(PROV_DRBG *drbg) 574{ 575 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; 576 size_t keylen; 577 578 if (ctr->cipher_ctr == NULL) { 579 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER); 580 return 0; 581 } 582 ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr); 583 if (ctr->ctx_ecb == NULL) 584 ctr->ctx_ecb = EVP_CIPHER_CTX_new(); 585 if (ctr->ctx_ctr == NULL) 586 ctr->ctx_ctr = EVP_CIPHER_CTX_new(); 587 if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) { 588 ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); 589 goto err; 590 } 591 592 if (!EVP_CipherInit_ex(ctr->ctx_ecb, 593 ctr->cipher_ecb, NULL, NULL, NULL, 1) 594 || !EVP_CipherInit_ex(ctr->ctx_ctr, 595 ctr->cipher_ctr, NULL, NULL, NULL, 1)) { 596 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS); 597 goto err; 598 } 599 600 drbg->strength = (unsigned int)(keylen * 8); 601 drbg->seedlen = keylen + 16; 602 603 if (ctr->use_df) { 604 /* df initialisation */ 605 static const unsigned char df_key[32] = { 606 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 607 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 608 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 609 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 610 }; 611 612 if (ctr->ctx_df == NULL) 613 ctr->ctx_df = EVP_CIPHER_CTX_new(); 614 if (ctr->ctx_df == NULL) { 615 ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB); 616 goto err; 617 } 618 /* Set key schedule for df_key */ 619 if (!EVP_CipherInit_ex(ctr->ctx_df, 620 ctr->cipher_ecb, NULL, df_key, NULL, 1)) { 621 ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED); 622 goto err; 623 } 624 } 625 return drbg_ctr_init_lengths(drbg); 626 627err: 628 EVP_CIPHER_CTX_free(ctr->ctx_ecb); 629 EVP_CIPHER_CTX_free(ctr->ctx_ctr); 630 ctr->ctx_ecb = ctr->ctx_ctr = NULL; 631 return 0; 632} 633 634static int drbg_ctr_new(PROV_DRBG *drbg) 635{ 636 PROV_DRBG_CTR *ctr; 637 638 ctr = OPENSSL_secure_zalloc(sizeof(*ctr)); 639 if (ctr == NULL) 640 return 0; 641 642 ctr->use_df = 1; 643 drbg->data = ctr; 644 OSSL_FIPS_IND_INIT(drbg) 645 return drbg_ctr_init_lengths(drbg); 646} 647 648static void *drbg_ctr_new_wrapper(void *provctx, void *parent, 649 const OSSL_DISPATCH *parent_dispatch) 650{ 651 return ossl_rand_drbg_new(provctx, parent, parent_dispatch, 652 &drbg_ctr_new, &drbg_ctr_free, 653 &drbg_ctr_instantiate, &drbg_ctr_uninstantiate, 654 &drbg_ctr_reseed, &drbg_ctr_generate); 655} 656 657static void drbg_ctr_free(void *vdrbg) 658{ 659 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 660 PROV_DRBG_CTR *ctr; 661 662 if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) { 663 EVP_CIPHER_CTX_free(ctr->ctx_ecb); 664 EVP_CIPHER_CTX_free(ctr->ctx_ctr); 665 EVP_CIPHER_CTX_free(ctr->ctx_df); 666 EVP_CIPHER_free(ctr->cipher_ecb); 667 EVP_CIPHER_free(ctr->cipher_ctr); 668 669 OPENSSL_secure_clear_free(ctr, sizeof(*ctr)); 670 } 671 ossl_rand_drbg_free(drbg); 672} 673 674#define drbg_ctr_get_ctx_params_st drbg_get_ctx_params_st 675 676{- produce_param_decoder('drbg_ctr_get_ctx_params', 677 (['DRBG_PARAM_CIPHER', 'cipher', 'utf8_string'], 678 ['DRBG_PARAM_USE_DF', 'df', 'int'], 679 ['RAND_PARAM_STATE', 'state', 'int'], 680 ['RAND_PARAM_STRENGTH', 'str', 'uint'], 681 ['RAND_PARAM_MAX_REQUEST', 'maxreq', 'size_t'], 682 ['DRBG_PARAM_MIN_ENTROPYLEN', 'minentlen', 'size_t'], 683 ['DRBG_PARAM_MAX_ENTROPYLEN', 'maxentlen', 'size_t'], 684 ['DRBG_PARAM_MIN_NONCELEN', 'minnonlen', 'size_t'], 685 ['DRBG_PARAM_MAX_NONCELEN', 'maxnonlen', 'size_t'], 686 ['DRBG_PARAM_MAX_PERSLEN', 'maxperlen', 'size_t'], 687 ['DRBG_PARAM_MAX_ADINLEN', 'maxadlen', 'size_t'], 688 ['DRBG_PARAM_RESEED_COUNTER', 'reseed_cnt', 'uint'], 689 ['DRBG_PARAM_RESEED_TIME', 'reseed_time', 'time_t'], 690 ['DRBG_PARAM_RESEED_REQUESTS', 'reseed_req', 'uint'], 691 ['DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_int', 'uint64'], 692 ['KDF_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'], 693 )); -} 694 695static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) 696{ 697 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 698 PROV_DRBG_CTR *ctr; 699 struct drbg_ctr_get_ctx_params_st p; 700 int ret = 0, complete = 0; 701 702 if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p)) 703 return 0; 704 705 if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete)) 706 return 0; 707 708 if (complete) 709 return 1; 710 711 ctr = (PROV_DRBG_CTR *)drbg->data; 712 713 if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock)) 714 return 0; 715 716 if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df)) 717 goto err; 718 719 if (p.cipher != NULL) { 720 if (ctr->cipher_ctr == NULL 721 || !OSSL_PARAM_set_utf8_string(p.cipher, 722 EVP_CIPHER_get0_name(ctr->cipher_ctr))) 723 goto err; 724 } 725 726 ret = ossl_drbg_get_ctx_params(drbg, &p); 727 err: 728 if (drbg->lock != NULL) 729 CRYPTO_THREAD_unlock(drbg->lock); 730 731 return ret; 732} 733 734static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx, 735 ossl_unused void *provctx) 736{ 737 return drbg_ctr_get_ctx_params_list; 738} 739 740static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx, 741 const struct drbg_set_ctx_params_st *p) 742{ 743 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data; 744 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); 745 OSSL_PROVIDER *prov = NULL; 746 char *ecb; 747 const char *propquery = NULL; 748 int i, cipher_init = 0; 749 750 if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) { 751 /* FIPS errors out in the drbg_ctr_init() call later */ 752 ctr->use_df = i != 0; 753 cipher_init = 1; 754 } 755 756 if (p->propq != NULL) { 757 if (p->propq->data_type != OSSL_PARAM_UTF8_STRING) 758 return 0; 759 propquery = (const char *)p->propq->data; 760 } 761 762 if (p->prov != NULL) { 763 if (p->prov->data_type != OSSL_PARAM_UTF8_STRING) 764 return 0; 765 if ((prov = ossl_provider_find(libctx, 766 (const char *)p->prov->data, 1)) == NULL) 767 return 0; 768 } 769 770 if (p->cipher != NULL) { 771 const char *base = (const char *)p->cipher->data; 772 size_t ctr_str_len = sizeof("CTR") - 1; 773 size_t ecb_str_len = sizeof("ECB") - 1; 774 775 if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING 776 || p->cipher->data_size < ctr_str_len) { 777 ossl_provider_free(prov); 778 return 0; 779 } 780 if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) { 781 ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER); 782 ossl_provider_free(prov); 783 return 0; 784 } 785 if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) { 786 ossl_provider_free(prov); 787 return 0; 788 } 789 strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB"); 790 EVP_CIPHER_free(ctr->cipher_ecb); 791 EVP_CIPHER_free(ctr->cipher_ctr); 792 /* 793 * Try to fetch algorithms from our own provider code, fallback 794 * to generic fetch only if that fails 795 */ 796 (void)ERR_set_mark(); 797 ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL); 798 if (ctr->cipher_ctr == NULL) { 799 (void)ERR_pop_to_mark(); 800 ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery); 801 } else { 802 (void)ERR_clear_last_mark(); 803 } 804 (void)ERR_set_mark(); 805 ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL); 806 if (ctr->cipher_ecb == NULL) { 807 (void)ERR_pop_to_mark(); 808 ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery); 809 } else { 810 (void)ERR_clear_last_mark(); 811 } 812 OPENSSL_free(ecb); 813 if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) { 814 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS); 815 ossl_provider_free(prov); 816 return 0; 817 } 818 cipher_init = 1; 819 } 820 ossl_provider_free(prov); 821 822 if (cipher_init && !drbg_ctr_init(ctx)) 823 return 0; 824 825 return ossl_drbg_set_ctx_params(ctx, p); 826} 827 828#define drbg_ctr_set_ctx_params_st drbg_set_ctx_params_st 829 830{- produce_param_decoder('drbg_ctr_set_ctx_params', 831 (['DRBG_PARAM_PROPERTIES', 'propq', 'utf8_string'], 832 ['DRBG_PARAM_CIPHER', 'cipher', 'utf8_string'], 833 ['DRBG_PARAM_USE_DF', 'df', 'int'], 834 ['PROV_PARAM_CORE_PROV_NAME', 'prov', 'utf8_string'], 835 ['DRBG_PARAM_RESEED_REQUESTS', 'reseed_req', 'uint'], 836 ['DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_time', 'uint64'], 837 )); -} 838 839static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 840{ 841 PROV_DRBG *drbg = (PROV_DRBG *)vctx; 842 struct drbg_set_ctx_params_st p; 843 int ret; 844 845 if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p)) 846 return 0; 847 848 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock)) 849 return 0; 850 851 ret = drbg_ctr_set_ctx_params_locked(drbg, &p); 852 853 if (drbg->lock != NULL) 854 CRYPTO_THREAD_unlock(drbg->lock); 855 856 return ret; 857} 858 859static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx, 860 ossl_unused void *provctx) 861{ 862 return drbg_ctr_set_ctx_params_list; 863} 864 865const OSSL_DISPATCH ossl_drbg_ctr_functions[] = { 866 { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper }, 867 { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free }, 868 { OSSL_FUNC_RAND_INSTANTIATE, 869 (void(*)(void))drbg_ctr_instantiate_wrapper }, 870 { OSSL_FUNC_RAND_UNINSTANTIATE, 871 (void(*)(void))drbg_ctr_uninstantiate_wrapper }, 872 { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper }, 873 { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper }, 874 { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking }, 875 { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock }, 876 { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock }, 877 { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS, 878 (void(*)(void))drbg_ctr_settable_ctx_params }, 879 { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params }, 880 { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, 881 (void(*)(void))drbg_ctr_gettable_ctx_params }, 882 { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params }, 883 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, 884 (void(*)(void))drbg_ctr_verify_zeroization }, 885 { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed }, 886 { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed }, 887 OSSL_DISPATCH_END 888}; 889