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