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