xref: /freebsd/crypto/openssl/providers/implementations/rands/drbg_ctr.c (revision 44096ebd22ddd0081a357011714eff8963614b65)
1 /*
2  * Copyright 2011-2024 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 <openssl/proverr.h>
17 #include "crypto/modes.h"
18 #include "internal/thread_once.h"
19 #include "prov/implementations.h"
20 #include "prov/providercommon.h"
21 #include "prov/provider_ctx.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                                         const OSSL_PARAM params[])
331 {
332     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
333 
334     if (!ossl_prov_is_running() || !drbg_ctr_set_ctx_params(drbg, params))
335         return 0;
336     return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
337                                       pstr, pstr_len);
338 }
339 
340 static int drbg_ctr_reseed(PROV_DRBG *drbg,
341                            const unsigned char *entropy, size_t entropylen,
342                            const unsigned char *adin, size_t adinlen)
343 {
344     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
345 
346     if (entropy == NULL)
347         return 0;
348 
349     inc_128(ctr);
350     if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
351         return 0;
352     return 1;
353 }
354 
355 static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
356                                    const unsigned char *ent, size_t ent_len,
357                                    const unsigned char *adin, size_t adin_len)
358 {
359     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
360 
361     return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
362                                  adin, adin_len);
363 }
364 
365 static void ctr96_inc(unsigned char *counter)
366 {
367     u32 n = 12, c = 1;
368 
369     do {
370         --n;
371         c += counter[n];
372         counter[n] = (u8)c;
373         c >>= 8;
374     } while (n);
375 }
376 
377 static int drbg_ctr_generate(PROV_DRBG *drbg,
378                              unsigned char *out, size_t outlen,
379                              const unsigned char *adin, size_t adinlen)
380 {
381     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
382     unsigned int ctr32, blocks;
383     int outl, buflen;
384 
385     if (adin != NULL && adinlen != 0) {
386         inc_128(ctr);
387 
388         if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
389             return 0;
390         /* This means we reuse derived value */
391         if (ctr->use_df) {
392             adin = NULL;
393             adinlen = 1;
394         }
395     } else {
396         adinlen = 0;
397     }
398 
399     inc_128(ctr);
400 
401     if (outlen == 0) {
402         inc_128(ctr);
403 
404         if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
405             return 0;
406         return 1;
407     }
408 
409     memset(out, 0, outlen);
410 
411     do {
412         if (!EVP_CipherInit_ex(ctr->ctx_ctr,
413                                NULL, NULL, NULL, ctr->V, -1))
414             return 0;
415 
416         /*-
417          * outlen has type size_t while EVP_CipherUpdate takes an
418          * int argument and thus cannot be guaranteed to process more
419          * than 2^31-1 bytes at a time. We process such huge generate
420          * requests in 2^30 byte chunks, which is the greatest multiple
421          * of AES block size lower than or equal to 2^31-1.
422          */
423         buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
424         blocks = (buflen + 15) / 16;
425 
426         ctr32 = GETU32(ctr->V + 12) + blocks;
427         if (ctr32 < blocks) {
428             /* 32-bit counter overflow into V. */
429             if (ctr32 != 0) {
430                 blocks -= ctr32;
431                 buflen = blocks * 16;
432                 ctr32 = 0;
433             }
434             ctr96_inc(ctr->V);
435         }
436         PUTU32(ctr->V + 12, ctr32);
437 
438         if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
439             || outl != buflen)
440             return 0;
441 
442         out += buflen;
443         outlen -= buflen;
444     } while (outlen);
445 
446     if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
447         return 0;
448     return 1;
449 }
450 
451 static int drbg_ctr_generate_wrapper
452     (void *vdrbg, unsigned char *out, size_t outlen,
453      unsigned int strength, int prediction_resistance,
454      const unsigned char *adin, size_t adin_len)
455 {
456     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
457 
458     return ossl_prov_drbg_generate(drbg, out, outlen, strength,
459                                    prediction_resistance, adin, adin_len);
460 }
461 
462 static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
463 {
464     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
465 
466     OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
467     OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
468     OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
469     OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
470     ctr->bltmp_pos = 0;
471     return ossl_prov_drbg_uninstantiate(drbg);
472 }
473 
474 static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
475 {
476     return drbg_ctr_uninstantiate((PROV_DRBG *)vdrbg);
477 }
478 
479 static int drbg_ctr_verify_zeroization(void *vdrbg)
480 {
481     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
483 
484     PROV_DRBG_VERYIFY_ZEROIZATION(ctr->K);
485     PROV_DRBG_VERYIFY_ZEROIZATION(ctr->V);
486     PROV_DRBG_VERYIFY_ZEROIZATION(ctr->bltmp);
487     PROV_DRBG_VERYIFY_ZEROIZATION(ctr->KX);
488     if (ctr->bltmp_pos != 0)
489         return 0;
490     return 1;
491 }
492 
493 static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
494 {
495     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
496     int res = 1;
497 
498     /* Maximum number of bits per request = 2^19  = 2^16 bytes */
499     drbg->max_request = 1 << 16;
500     if (ctr->use_df) {
501         drbg->min_entropylen = 0;
502         drbg->max_entropylen = DRBG_MAX_LENGTH;
503         drbg->min_noncelen = 0;
504         drbg->max_noncelen = DRBG_MAX_LENGTH;
505         drbg->max_perslen = DRBG_MAX_LENGTH;
506         drbg->max_adinlen = DRBG_MAX_LENGTH;
507 
508         if (ctr->keylen > 0) {
509             drbg->min_entropylen = ctr->keylen;
510             drbg->min_noncelen = drbg->min_entropylen / 2;
511         }
512     } else {
513         const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
514 
515         drbg->min_entropylen = len;
516         drbg->max_entropylen = len;
517         /* Nonce not used */
518         drbg->min_noncelen = 0;
519         drbg->max_noncelen = 0;
520         drbg->max_perslen = len;
521         drbg->max_adinlen = len;
522     }
523     return res;
524 }
525 
526 static int drbg_ctr_init(PROV_DRBG *drbg)
527 {
528     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
529     size_t keylen;
530 
531     if (ctr->cipher_ctr == NULL) {
532         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
533         return 0;
534     }
535     ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
536     if (ctr->ctx_ecb == NULL)
537         ctr->ctx_ecb = EVP_CIPHER_CTX_new();
538     if (ctr->ctx_ctr == NULL)
539         ctr->ctx_ctr = EVP_CIPHER_CTX_new();
540     if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
541         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
542         goto err;
543     }
544 
545     if (!EVP_CipherInit_ex(ctr->ctx_ecb,
546                            ctr->cipher_ecb, NULL, NULL, NULL, 1)
547         || !EVP_CipherInit_ex(ctr->ctx_ctr,
548                               ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
549         ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
550         goto err;
551     }
552 
553     drbg->strength = keylen * 8;
554     drbg->seedlen = keylen + 16;
555 
556     if (ctr->use_df) {
557         /* df initialisation */
558         static const unsigned char df_key[32] = {
559             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
560             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
561             0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
562             0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
563         };
564 
565         if (ctr->ctx_df == NULL)
566             ctr->ctx_df = EVP_CIPHER_CTX_new();
567         if (ctr->ctx_df == NULL) {
568             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
569             goto err;
570         }
571         /* Set key schedule for df_key */
572         if (!EVP_CipherInit_ex(ctr->ctx_df,
573                                ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
574             ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
575             goto err;
576         }
577     }
578     return drbg_ctr_init_lengths(drbg);
579 
580 err:
581     EVP_CIPHER_CTX_free(ctr->ctx_ecb);
582     EVP_CIPHER_CTX_free(ctr->ctx_ctr);
583     ctr->ctx_ecb = ctr->ctx_ctr = NULL;
584     return 0;
585 }
586 
587 static int drbg_ctr_new(PROV_DRBG *drbg)
588 {
589     PROV_DRBG_CTR *ctr;
590 
591     ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
592     if (ctr == NULL) {
593         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
594         return 0;
595     }
596 
597     ctr->use_df = 1;
598     drbg->data = ctr;
599     return drbg_ctr_init_lengths(drbg);
600 }
601 
602 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
603                                    const OSSL_DISPATCH *parent_dispatch)
604 {
605     return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
606                               &drbg_ctr_new, &drbg_ctr_free,
607                               &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
608                               &drbg_ctr_reseed, &drbg_ctr_generate);
609 }
610 
611 static void drbg_ctr_free(void *vdrbg)
612 {
613     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
614     PROV_DRBG_CTR *ctr;
615 
616     if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
617         EVP_CIPHER_CTX_free(ctr->ctx_ecb);
618         EVP_CIPHER_CTX_free(ctr->ctx_ctr);
619         EVP_CIPHER_CTX_free(ctr->ctx_df);
620         EVP_CIPHER_free(ctr->cipher_ecb);
621         EVP_CIPHER_free(ctr->cipher_ctr);
622 
623         OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
624     }
625     ossl_rand_drbg_free(drbg);
626 }
627 
628 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
629 {
630     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
631     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
632     OSSL_PARAM *p;
633 
634     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
635     if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
636         return 0;
637 
638     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
639     if (p != NULL) {
640         if (ctr->cipher_ctr == NULL
641             || !OSSL_PARAM_set_utf8_string(p,
642                                            EVP_CIPHER_get0_name(ctr->cipher_ctr)))
643             return 0;
644     }
645 
646     return ossl_drbg_get_ctx_params(drbg, params);
647 }
648 
649 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
650                                                       ossl_unused void *provctx)
651 {
652     static const OSSL_PARAM known_gettable_ctx_params[] = {
653         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
654         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
655         OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
656         OSSL_PARAM_END
657     };
658     return known_gettable_ctx_params;
659 }
660 
661 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
662 {
663     PROV_DRBG *ctx = (PROV_DRBG *)vctx;
664     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
665     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
666     const OSSL_PARAM *p;
667     char *ecb;
668     const char *propquery = NULL;
669     int i, cipher_init = 0;
670 
671     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
672             && OSSL_PARAM_get_int(p, &i)) {
673         /* FIPS errors out in the drbg_ctr_init() call later */
674         ctr->use_df = i != 0;
675         cipher_init = 1;
676     }
677 
678     if ((p = OSSL_PARAM_locate_const(params,
679                                      OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
680         if (p->data_type != OSSL_PARAM_UTF8_STRING)
681             return 0;
682         propquery = (const char *)p->data;
683     }
684 
685     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
686         const char *base = (const char *)p->data;
687         size_t ctr_str_len = sizeof("CTR") - 1;
688         size_t ecb_str_len = sizeof("ECB") - 1;
689 
690         if (p->data_type != OSSL_PARAM_UTF8_STRING
691                 || p->data_size < ctr_str_len)
692             return 0;
693         if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
694             ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
695             return 0;
696         }
697         if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
698             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
699             return 0;
700         }
701         strcpy(ecb + p->data_size - ecb_str_len, "ECB");
702         EVP_CIPHER_free(ctr->cipher_ecb);
703         EVP_CIPHER_free(ctr->cipher_ctr);
704         ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
705         ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
706         OPENSSL_free(ecb);
707         if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
708             ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
709             return 0;
710         }
711         cipher_init = 1;
712     }
713 
714     if (cipher_init && !drbg_ctr_init(ctx))
715         return 0;
716 
717     return ossl_drbg_set_ctx_params(ctx, params);
718 }
719 
720 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
721                                                       ossl_unused void *provctx)
722 {
723     static const OSSL_PARAM known_settable_ctx_params[] = {
724         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
725         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
726         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
727         OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
728         OSSL_PARAM_END
729     };
730     return known_settable_ctx_params;
731 }
732 
733 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
734     { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
735     { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
736     { OSSL_FUNC_RAND_INSTANTIATE,
737       (void(*)(void))drbg_ctr_instantiate_wrapper },
738     { OSSL_FUNC_RAND_UNINSTANTIATE,
739       (void(*)(void))drbg_ctr_uninstantiate_wrapper },
740     { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
741     { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
742     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
743     { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
744     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
745     { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
746       (void(*)(void))drbg_ctr_settable_ctx_params },
747     { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
748     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
749       (void(*)(void))drbg_ctr_gettable_ctx_params },
750     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
751     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
752       (void(*)(void))drbg_ctr_verify_zeroization },
753     { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
754     { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
755     { 0, NULL }
756 };
757