]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/rands/drbg_ctr.c
Rename OPENSSL_CTX prefix to OSSL_LIB_CTX
[thirdparty/openssl.git] / providers / implementations / rands / drbg_ctr.c
1 /*
2 * Copyright 2011-2020 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 <stdlib.h>
11 #include <string.h>
12 #include <openssl/crypto.h>
13 #include <openssl/err.h>
14 #include <openssl/rand.h>
15 #include <openssl/aes.h>
16 #include "e_os.h" /* strcasecmp */
17 #include "crypto/modes.h"
18 #include "internal/thread_once.h"
19 #include "prov/implementations.h"
20 #include "prov/provider_ctx.h"
21 #include "prov/providercommonerr.h"
22 #include "drbg_local.h"
23
24 static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
25 static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
26 static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper;
27 static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper;
28 static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper;
29 static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper;
30 static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params;
31 static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params;
32 static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
33 static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
34 static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;
35
36 /*
37 * The state of a DRBG AES-CTR.
38 */
39 typedef struct rand_drbg_ctr_st {
40 EVP_CIPHER_CTX *ctx_ecb;
41 EVP_CIPHER_CTX *ctx_ctr;
42 EVP_CIPHER_CTX *ctx_df;
43 EVP_CIPHER *cipher_ecb;
44 EVP_CIPHER *cipher_ctr;
45 size_t keylen;
46 int use_df;
47 unsigned char K[32];
48 unsigned char V[16];
49 /* Temporary block storage used by ctr_df */
50 unsigned char bltmp[16];
51 size_t bltmp_pos;
52 unsigned char KX[48];
53 } PROV_DRBG_CTR;
54
55 /*
56 * Implementation of NIST SP 800-90A CTR DRBG.
57 */
58 static void inc_128(PROV_DRBG_CTR *ctr)
59 {
60 unsigned char *p = &ctr->V[0];
61 u32 n = 16, c = 1;
62
63 do {
64 --n;
65 c += p[n];
66 p[n] = (u8)c;
67 c >>= 8;
68 } while (n);
69 }
70
71 static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
72 {
73 size_t i, n;
74
75 if (in == NULL || inlen == 0)
76 return;
77
78 /*
79 * Any zero padding will have no effect on the result as we
80 * are XORing. So just process however much input we have.
81 */
82 n = inlen < ctr->keylen ? inlen : ctr->keylen;
83 for (i = 0; i < n; i++)
84 ctr->K[i] ^= in[i];
85 if (inlen <= ctr->keylen)
86 return;
87
88 n = inlen - ctr->keylen;
89 if (n > 16) {
90 /* Should never happen */
91 n = 16;
92 }
93 for (i = 0; i < n; i++)
94 ctr->V[i] ^= in[i + ctr->keylen];
95 }
96
97 /*
98 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
99 */
100 __owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out,
101 const unsigned char *in, int len)
102 {
103 int i, outlen = AES_BLOCK_SIZE;
104
105 for (i = 0; i < len; i++)
106 out[i] ^= in[i];
107
108 if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
109 || outlen != len)
110 return 0;
111 return 1;
112 }
113
114
115 /*
116 * Handle several BCC operations for as much data as we need for K and X
117 */
118 __owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
119 {
120 unsigned char in_tmp[48];
121 unsigned char num_of_blk = 2;
122
123 memcpy(in_tmp, in, 16);
124 memcpy(in_tmp + 16, in, 16);
125 if (ctr->keylen != 16) {
126 memcpy(in_tmp + 32, in, 16);
127 num_of_blk = 3;
128 }
129 return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
130 }
131
132 /*
133 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
134 * see 10.3.1 stage 7.
135 */
136 __owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
137 {
138 unsigned char bltmp[48] = {0};
139 unsigned char num_of_blk;
140
141 memset(ctr->KX, 0, 48);
142 num_of_blk = ctr->keylen == 16 ? 2 : 3;
143 bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
144 bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
145 return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
146 }
147
148 /*
149 * Process several blocks into BCC algorithm, some possibly partial
150 */
151 __owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
152 const unsigned char *in, size_t inlen)
153 {
154 if (in == NULL || inlen == 0)
155 return 1;
156
157 /* If we have partial block handle it first */
158 if (ctr->bltmp_pos) {
159 size_t left = 16 - ctr->bltmp_pos;
160
161 /* If we now have a complete block process it */
162 if (inlen >= left) {
163 memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
164 if (!ctr_BCC_blocks(ctr, ctr->bltmp))
165 return 0;
166 ctr->bltmp_pos = 0;
167 inlen -= left;
168 in += left;
169 }
170 }
171
172 /* Process zero or more complete blocks */
173 for (; inlen >= 16; in += 16, inlen -= 16) {
174 if (!ctr_BCC_blocks(ctr, in))
175 return 0;
176 }
177
178 /* Copy any remaining partial block to the temporary buffer */
179 if (inlen > 0) {
180 memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
181 ctr->bltmp_pos += inlen;
182 }
183 return 1;
184 }
185
186 __owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
187 {
188 if (ctr->bltmp_pos) {
189 memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
190 if (!ctr_BCC_blocks(ctr, ctr->bltmp))
191 return 0;
192 }
193 return 1;
194 }
195
196 __owur static int ctr_df(PROV_DRBG_CTR *ctr,
197 const unsigned char *in1, size_t in1len,
198 const unsigned char *in2, size_t in2len,
199 const unsigned char *in3, size_t in3len)
200 {
201 static unsigned char c80 = 0x80;
202 size_t inlen;
203 unsigned char *p = ctr->bltmp;
204 int outlen = AES_BLOCK_SIZE;
205
206 if (!ctr_BCC_init(ctr))
207 return 0;
208 if (in1 == NULL)
209 in1len = 0;
210 if (in2 == NULL)
211 in2len = 0;
212 if (in3 == NULL)
213 in3len = 0;
214 inlen = in1len + in2len + in3len;
215 /* Initialise L||N in temporary block */
216 *p++ = (inlen >> 24) & 0xff;
217 *p++ = (inlen >> 16) & 0xff;
218 *p++ = (inlen >> 8) & 0xff;
219 *p++ = inlen & 0xff;
220
221 /* NB keylen is at most 32 bytes */
222 *p++ = 0;
223 *p++ = 0;
224 *p++ = 0;
225 *p = (unsigned char)((ctr->keylen + 16) & 0xff);
226 ctr->bltmp_pos = 8;
227 if (!ctr_BCC_update(ctr, in1, in1len)
228 || !ctr_BCC_update(ctr, in2, in2len)
229 || !ctr_BCC_update(ctr, in3, in3len)
230 || !ctr_BCC_update(ctr, &c80, 1)
231 || !ctr_BCC_final(ctr))
232 return 0;
233 /* Set up key K */
234 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
235 return 0;
236 /* X follows key K */
237 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
238 AES_BLOCK_SIZE)
239 || outlen != AES_BLOCK_SIZE)
240 return 0;
241 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
242 AES_BLOCK_SIZE)
243 || outlen != AES_BLOCK_SIZE)
244 return 0;
245 if (ctr->keylen != 16)
246 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
247 ctr->KX + 16, AES_BLOCK_SIZE)
248 || outlen != AES_BLOCK_SIZE)
249 return 0;
250 return 1;
251 }
252
253 /*
254 * NB the no-df Update in SP800-90A specifies a constant input length
255 * of seedlen, however other uses of this algorithm pad the input with
256 * zeroes if necessary and have up to two parameters XORed together,
257 * so we handle both cases in this function instead.
258 */
259 __owur static int ctr_update(PROV_DRBG *drbg,
260 const unsigned char *in1, size_t in1len,
261 const unsigned char *in2, size_t in2len,
262 const unsigned char *nonce, size_t noncelen)
263 {
264 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
265 int outlen = AES_BLOCK_SIZE;
266 unsigned char V_tmp[48], out[48];
267 unsigned char len;
268
269 /* correct key is already set up. */
270 memcpy(V_tmp, ctr->V, 16);
271 inc_128(ctr);
272 memcpy(V_tmp + 16, ctr->V, 16);
273 if (ctr->keylen == 16) {
274 len = 32;
275 } else {
276 inc_128(ctr);
277 memcpy(V_tmp + 32, ctr->V, 16);
278 len = 48;
279 }
280 if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
281 || outlen != len)
282 return 0;
283 memcpy(ctr->K, out, ctr->keylen);
284 memcpy(ctr->V, out + ctr->keylen, 16);
285
286 if (ctr->use_df) {
287 /* If no input reuse existing derived value */
288 if (in1 != NULL || nonce != NULL || in2 != NULL)
289 if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
290 return 0;
291 /* If this a reuse input in1len != 0 */
292 if (in1len)
293 ctr_XOR(ctr, ctr->KX, drbg->seedlen);
294 } else {
295 ctr_XOR(ctr, in1, in1len);
296 ctr_XOR(ctr, in2, in2len);
297 }
298
299 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
300 || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
301 return 0;
302 return 1;
303 }
304
305 static int drbg_ctr_instantiate(PROV_DRBG *drbg,
306 const unsigned char *entropy, size_t entropylen,
307 const unsigned char *nonce, size_t noncelen,
308 const unsigned char *pers, size_t perslen)
309 {
310 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
311
312 if (entropy == NULL)
313 return 0;
314
315 memset(ctr->K, 0, sizeof(ctr->K));
316 memset(ctr->V, 0, sizeof(ctr->V));
317 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
318 return 0;
319
320 inc_128(ctr);
321 if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
322 return 0;
323 return 1;
324 }
325
326 static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
327 int prediction_resistance,
328 const unsigned char *pstr,
329 size_t pstr_len)
330 {
331 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
332
333 return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
334 pstr, pstr_len);
335 }
336
337 static int drbg_ctr_reseed(PROV_DRBG *drbg,
338 const unsigned char *entropy, size_t entropylen,
339 const unsigned char *adin, size_t adinlen)
340 {
341 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
342
343 if (entropy == NULL)
344 return 0;
345
346 inc_128(ctr);
347 if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
348 return 0;
349 return 1;
350 }
351
352 static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
353 const unsigned char *ent, size_t ent_len,
354 const unsigned char *adin, size_t adin_len)
355 {
356 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
357
358 return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
359 adin, adin_len);
360 }
361
362 static void ctr96_inc(unsigned char *counter)
363 {
364 u32 n = 12, c = 1;
365
366 do {
367 --n;
368 c += counter[n];
369 counter[n] = (u8)c;
370 c >>= 8;
371 } while (n);
372 }
373
374 static int drbg_ctr_generate(PROV_DRBG *drbg,
375 unsigned char *out, size_t outlen,
376 const unsigned char *adin, size_t adinlen)
377 {
378 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
379 unsigned int ctr32, blocks;
380 int outl, buflen;
381
382 if (adin != NULL && adinlen != 0) {
383 inc_128(ctr);
384
385 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
386 return 0;
387 /* This means we reuse derived value */
388 if (ctr->use_df) {
389 adin = NULL;
390 adinlen = 1;
391 }
392 } else {
393 adinlen = 0;
394 }
395
396 inc_128(ctr);
397
398 if (outlen == 0) {
399 inc_128(ctr);
400
401 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
402 return 0;
403 return 1;
404 }
405
406 memset(out, 0, outlen);
407
408 do {
409 if (!EVP_CipherInit_ex(ctr->ctx_ctr,
410 NULL, NULL, NULL, ctr->V, -1))
411 return 0;
412
413 /*-
414 * outlen has type size_t while EVP_CipherUpdate takes an
415 * int argument and thus cannot be guaranteed to process more
416 * than 2^31-1 bytes at a time. We process such huge generate
417 * requests in 2^30 byte chunks, which is the greatest multiple
418 * of AES block size lower than or equal to 2^31-1.
419 */
420 buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
421 blocks = (buflen + 15) / 16;
422
423 ctr32 = GETU32(ctr->V + 12) + blocks;
424 if (ctr32 < blocks) {
425 /* 32-bit counter overflow into V. */
426 if (ctr32 != 0) {
427 blocks -= ctr32;
428 buflen = blocks * 16;
429 ctr32 = 0;
430 }
431 ctr96_inc(ctr->V);
432 }
433 PUTU32(ctr->V + 12, ctr32);
434
435 if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
436 || outl != buflen)
437 return 0;
438
439 out += buflen;
440 outlen -= buflen;
441 } while (outlen);
442
443 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
444 return 0;
445 return 1;
446 }
447
448 static int drbg_ctr_generate_wrapper
449 (void *vdrbg, unsigned char *out, size_t outlen,
450 unsigned int strength, int prediction_resistance,
451 const unsigned char *adin, size_t adin_len)
452 {
453 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
454
455 return ossl_prov_drbg_generate(drbg, out, outlen, strength,
456 prediction_resistance, adin, adin_len);
457 }
458
459 static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
460 {
461 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
462
463 OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
464 OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
465 OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
466 OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
467 ctr->bltmp_pos = 0;
468 return ossl_prov_drbg_uninstantiate(drbg);
469 }
470
471 static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
472 {
473 return drbg_ctr_uninstantiate((PROV_DRBG *)vdrbg);
474 }
475
476 static int drbg_ctr_verify_zeroization(void *vdrbg)
477 {
478 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
479 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
480
481 PROV_DRBG_VERYIFY_ZEROIZATION(ctr->K);
482 PROV_DRBG_VERYIFY_ZEROIZATION(ctr->V);
483 PROV_DRBG_VERYIFY_ZEROIZATION(ctr->bltmp);
484 PROV_DRBG_VERYIFY_ZEROIZATION(ctr->KX);
485 if (ctr->bltmp_pos != 0)
486 return 0;
487 return 1;
488 }
489
490 static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
491 {
492 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
493 int res = 1;
494
495 #ifdef FIPS_MODULE
496 if (!ctr->use_df) {
497 PROVerr(0, RAND_R_DERIVATION_FUNCTION_MANDATORY_FOR_FIPS);
498 ctr->use_df = 1;
499 res = 0;
500 }
501 #endif
502 /* Maximum number of bits per request = 2^19 = 2^16 bytes */
503 drbg->max_request = 1 << 16;
504 if (ctr->use_df) {
505 drbg->min_entropylen = 0;
506 drbg->max_entropylen = DRBG_MAX_LENGTH;
507 drbg->min_noncelen = 0;
508 drbg->max_noncelen = DRBG_MAX_LENGTH;
509 drbg->max_perslen = DRBG_MAX_LENGTH;
510 drbg->max_adinlen = DRBG_MAX_LENGTH;
511
512 if (ctr->keylen > 0) {
513 drbg->min_entropylen = ctr->keylen;
514 drbg->min_noncelen = drbg->min_entropylen / 2;
515 }
516 } else {
517 const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
518
519 drbg->min_entropylen = len;
520 drbg->max_entropylen = len;
521 /* Nonce not used */
522 drbg->min_noncelen = 0;
523 drbg->max_noncelen = 0;
524 drbg->max_perslen = len;
525 drbg->max_adinlen = len;
526 }
527 return res;
528 }
529
530 static int drbg_ctr_init(PROV_DRBG *drbg)
531 {
532 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
533 size_t keylen;
534
535 if (ctr->cipher_ctr == NULL) {
536 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
537 return 0;
538 }
539 ctr->keylen = keylen = EVP_CIPHER_key_length(ctr->cipher_ctr);
540 if (ctr->ctx_ecb == NULL)
541 ctr->ctx_ecb = EVP_CIPHER_CTX_new();
542 if (ctr->ctx_ctr == NULL)
543 ctr->ctx_ctr = EVP_CIPHER_CTX_new();
544 if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
545 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
546 goto err;
547 }
548
549 if (!EVP_CipherInit_ex(ctr->ctx_ecb,
550 ctr->cipher_ecb, NULL, NULL, NULL, 1)
551 || !EVP_CipherInit_ex(ctr->ctx_ctr,
552 ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
553 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
554 goto err;
555 }
556
557 drbg->strength = keylen * 8;
558 drbg->seedlen = keylen + 16;
559
560 if (ctr->use_df) {
561 /* df initialisation */
562 static const unsigned char df_key[32] = {
563 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
564 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
565 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
566 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
567 };
568
569 if (ctr->ctx_df == NULL)
570 ctr->ctx_df = EVP_CIPHER_CTX_new();
571 if (ctr->ctx_df == NULL) {
572 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
573 goto err;
574 }
575 /* Set key schedule for df_key */
576 if (!EVP_CipherInit_ex(ctr->ctx_df,
577 ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
578 ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
579 goto err;
580 }
581 }
582 return drbg_ctr_init_lengths(drbg);
583
584 err:
585 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
586 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
587 ctr->ctx_ecb = ctr->ctx_ctr = NULL;
588 return 0;
589 }
590
591 static int drbg_ctr_new(PROV_DRBG *drbg)
592 {
593 PROV_DRBG_CTR *ctr;
594
595 ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
596 if (ctr == NULL) {
597 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
598 return 0;
599 }
600
601 ctr->use_df = 1;
602 drbg->data = ctr;
603 return drbg_ctr_init_lengths(drbg);
604 }
605
606 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
607 const OSSL_DISPATCH *parent_dispatch)
608 {
609 return prov_rand_drbg_new(provctx, parent, parent_dispatch, &drbg_ctr_new,
610 &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
611 &drbg_ctr_reseed, &drbg_ctr_generate);
612 }
613
614 static void drbg_ctr_free(void *vdrbg)
615 {
616 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
617 PROV_DRBG_CTR *ctr;
618
619 if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
620 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
621 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
622 EVP_CIPHER_CTX_free(ctr->ctx_df);
623 EVP_CIPHER_free(ctr->cipher_ecb);
624 EVP_CIPHER_free(ctr->cipher_ctr);
625
626 OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
627 }
628 prov_rand_drbg_free(drbg);
629 }
630
631 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
632 {
633 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
634 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
635 OSSL_PARAM *p;
636
637 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
638 if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
639 return 0;
640
641 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
642 if (p != NULL) {
643 if (ctr->cipher_ctr == NULL
644 || !OSSL_PARAM_set_utf8_string(p, EVP_CIPHER_name(ctr->cipher_ctr)))
645 return 0;
646 }
647
648 return drbg_get_ctx_params(drbg, params);
649 }
650
651 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *provctx)
652 {
653 static const OSSL_PARAM known_gettable_ctx_params[] = {
654 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
655 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
656 OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
657 OSSL_PARAM_END
658 };
659 return known_gettable_ctx_params;
660 }
661
662 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
663 {
664 PROV_DRBG *ctx = (PROV_DRBG *)vctx;
665 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
666 OSSL_LIB_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
667 const OSSL_PARAM *p;
668 char *ecb;
669 const char *propquery = NULL;
670 int i, cipher_init = 0;
671
672 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
673 && OSSL_PARAM_get_int(p, &i)) {
674 /* FIPS errors out in the drbg_ctr_init() call later */
675 ctr->use_df = i != 0;
676 cipher_init = 1;
677 }
678
679 if ((p = OSSL_PARAM_locate_const(params,
680 OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
681 if (p->data_type != OSSL_PARAM_UTF8_STRING)
682 return 0;
683 propquery = (const char *)p->data;
684 }
685
686 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
687 const char *base = (const char *)p->data;
688
689 if (p->data_type != OSSL_PARAM_UTF8_STRING
690 || p->data_size < 3)
691 return 0;
692 if (strcasecmp("CTR", base + p->data_size - sizeof("CTR")) != 0) {
693 ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
694 return 0;
695 }
696 if ((ecb = OPENSSL_strdup(base)) == NULL) {
697 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
698 return 0;
699 }
700 strcpy(ecb + p->data_size - sizeof("ECB"), "ECB");
701 EVP_CIPHER_free(ctr->cipher_ecb);
702 EVP_CIPHER_free(ctr->cipher_ctr);
703 ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
704 ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
705 OPENSSL_free(ecb);
706 if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
707 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
708 return 0;
709 }
710 cipher_init = 1;
711 }
712
713 if (cipher_init && !drbg_ctr_init(ctx))
714 return 0;
715
716 return drbg_set_ctx_params(ctx, params);
717 }
718
719 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *provctx)
720 {
721 static const OSSL_PARAM known_settable_ctx_params[] = {
722 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
723 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
724 #ifndef FIPS_MODULE
725 /*
726 * Don't advertise this for FIPS, it isn't allowed to change.
727 * The parameter can still be passed and will be processed but errors
728 * out.
729 */
730 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
731 #endif
732 OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
733 OSSL_PARAM_END
734 };
735 return known_settable_ctx_params;
736 }
737
738 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
739 { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
740 { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
741 { OSSL_FUNC_RAND_INSTANTIATE,
742 (void(*)(void))drbg_ctr_instantiate_wrapper },
743 { OSSL_FUNC_RAND_UNINSTANTIATE,
744 (void(*)(void))drbg_ctr_uninstantiate_wrapper },
745 { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
746 { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
747 { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))drbg_enable_locking },
748 { OSSL_FUNC_RAND_LOCK, (void(*)(void))drbg_lock },
749 { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))drbg_unlock },
750 { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
751 (void(*)(void))drbg_ctr_settable_ctx_params },
752 { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
753 { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
754 (void(*)(void))drbg_ctr_gettable_ctx_params },
755 { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
756 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
757 (void(*)(void))drbg_ctr_verify_zeroization },
758 { 0, NULL }
759 };