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 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  */
inc_128(PROV_DRBG_CTR * ctr)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 
ctr_XOR(PROV_DRBG_CTR * ctr,const unsigned char * in,size_t inlen)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  */
ctr_BCC_block(PROV_DRBG_CTR * ctr,unsigned char * out,const unsigned char * in,int len)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  */
ctr_BCC_blocks(PROV_DRBG_CTR * ctr,const unsigned char * in)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  */
ctr_BCC_init(PROV_DRBG_CTR * ctr)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  */
ctr_BCC_update(PROV_DRBG_CTR * ctr,const unsigned char * in,size_t inlen)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 
ctr_BCC_final(PROV_DRBG_CTR * ctr)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 
ctr_df(PROV_DRBG_CTR * ctr,const unsigned char * in1,size_t in1len,const unsigned char * in2,size_t in2len,const unsigned char * in3,size_t in3len)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  */
ctr_update(PROV_DRBG * drbg,const unsigned char * in1,size_t in1len,const unsigned char * in2,size_t in2len,const unsigned char * nonce,size_t noncelen)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 
drbg_ctr_instantiate(PROV_DRBG * drbg,const unsigned char * entropy,size_t entropylen,const unsigned char * nonce,size_t noncelen,const unsigned char * pers,size_t perslen)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 
drbg_ctr_instantiate_wrapper(void * vdrbg,unsigned int strength,int prediction_resistance,const unsigned char * pstr,size_t pstr_len,const OSSL_PARAM params[])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 
drbg_ctr_reseed(PROV_DRBG * drbg,const unsigned char * entropy,size_t entropylen,const unsigned char * adin,size_t adinlen)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 
drbg_ctr_reseed_wrapper(void * vdrbg,int prediction_resistance,const unsigned char * ent,size_t ent_len,const unsigned char * adin,size_t adin_len)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 
ctr96_inc(unsigned char * counter)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 
drbg_ctr_generate(PROV_DRBG * drbg,unsigned char * out,size_t outlen,const unsigned char * adin,size_t adinlen)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 
drbg_ctr_generate_wrapper(void * vdrbg,unsigned char * out,size_t outlen,unsigned int strength,int prediction_resistance,const unsigned char * adin,size_t adin_len)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 
drbg_ctr_uninstantiate(PROV_DRBG * drbg)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 
drbg_ctr_uninstantiate_wrapper(void * vdrbg)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 
drbg_ctr_verify_zeroization(void * vdrbg)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 
drbg_ctr_init_lengths(PROV_DRBG * drbg)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 
drbg_ctr_init(PROV_DRBG * drbg)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 
drbg_ctr_new(PROV_DRBG * drbg)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     OSSL_FIPS_IND_INIT(drbg)
629     return drbg_ctr_init_lengths(drbg);
630 }
631 
drbg_ctr_new_wrapper(void * provctx,void * parent,const OSSL_DISPATCH * parent_dispatch)632 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
633                                    const OSSL_DISPATCH *parent_dispatch)
634 {
635     return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
636                               &drbg_ctr_new, &drbg_ctr_free,
637                               &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
638                               &drbg_ctr_reseed, &drbg_ctr_generate);
639 }
640 
drbg_ctr_free(void * vdrbg)641 static void drbg_ctr_free(void *vdrbg)
642 {
643     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
644     PROV_DRBG_CTR *ctr;
645 
646     if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
647         EVP_CIPHER_CTX_free(ctr->ctx_ecb);
648         EVP_CIPHER_CTX_free(ctr->ctx_ctr);
649         EVP_CIPHER_CTX_free(ctr->ctx_df);
650         EVP_CIPHER_free(ctr->cipher_ecb);
651         EVP_CIPHER_free(ctr->cipher_ctr);
652 
653         OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
654     }
655     ossl_rand_drbg_free(drbg);
656 }
657 
drbg_ctr_get_ctx_params(void * vdrbg,OSSL_PARAM params[])658 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
659 {
660     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
661     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
662     OSSL_PARAM *p;
663     int ret = 0, complete = 0;
664 
665     if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
666         return 0;
667 
668     if (complete)
669         return 1;
670 
671     if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
672         return 0;
673 
674     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
675     if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
676         goto err;
677 
678     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
679     if (p != NULL) {
680         if (ctr->cipher_ctr == NULL
681             || !OSSL_PARAM_set_utf8_string(p,
682                                            EVP_CIPHER_get0_name(ctr->cipher_ctr)))
683             goto err;
684     }
685 
686     ret = ossl_drbg_get_ctx_params(drbg, params);
687  err:
688     if (drbg->lock != NULL)
689         CRYPTO_THREAD_unlock(drbg->lock);
690 
691     return ret;
692 }
693 
drbg_ctr_gettable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)694 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
695                                                       ossl_unused void *provctx)
696 {
697     static const OSSL_PARAM known_gettable_ctx_params[] = {
698         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
699         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
700         OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
701         OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
702         OSSL_PARAM_END
703     };
704     return known_gettable_ctx_params;
705 }
706 
drbg_ctr_set_ctx_params_locked(void * vctx,const OSSL_PARAM params[])707 static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
708 {
709     PROV_DRBG *ctx = (PROV_DRBG *)vctx;
710     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
711     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
712     const OSSL_PARAM *p;
713     char *ecb;
714     const char *propquery = NULL;
715     int i, cipher_init = 0;
716 
717     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
718             && OSSL_PARAM_get_int(p, &i)) {
719         /* FIPS errors out in the drbg_ctr_init() call later */
720         ctr->use_df = i != 0;
721         cipher_init = 1;
722     }
723 
724     if ((p = OSSL_PARAM_locate_const(params,
725                                      OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
726         if (p->data_type != OSSL_PARAM_UTF8_STRING)
727             return 0;
728         propquery = (const char *)p->data;
729     }
730 
731     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
732         const char *base = (const char *)p->data;
733         size_t ctr_str_len = sizeof("CTR") - 1;
734         size_t ecb_str_len = sizeof("ECB") - 1;
735 
736         if (p->data_type != OSSL_PARAM_UTF8_STRING
737                 || p->data_size < ctr_str_len)
738             return 0;
739         if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
740             ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
741             return 0;
742         }
743         if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
744             return 0;
745         strcpy(ecb + p->data_size - ecb_str_len, "ECB");
746         EVP_CIPHER_free(ctr->cipher_ecb);
747         EVP_CIPHER_free(ctr->cipher_ctr);
748         ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
749         ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
750         OPENSSL_free(ecb);
751         if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
752             ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
753             return 0;
754         }
755         cipher_init = 1;
756     }
757 
758     if (cipher_init && !drbg_ctr_init(ctx))
759         return 0;
760 
761     return ossl_drbg_set_ctx_params(ctx, params);
762 }
763 
drbg_ctr_set_ctx_params(void * vctx,const OSSL_PARAM params[])764 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
765 {
766     PROV_DRBG *drbg = (PROV_DRBG *)vctx;
767     int ret;
768 
769     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
770         return 0;
771 
772     ret = drbg_ctr_set_ctx_params_locked(vctx, params);
773 
774     if (drbg->lock != NULL)
775         CRYPTO_THREAD_unlock(drbg->lock);
776 
777     return ret;
778 }
779 
drbg_ctr_settable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)780 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
781                                                       ossl_unused void *provctx)
782 {
783     static const OSSL_PARAM known_settable_ctx_params[] = {
784         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
785         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
786         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
787         OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
788         OSSL_PARAM_END
789     };
790     return known_settable_ctx_params;
791 }
792 
793 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
794     { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
795     { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
796     { OSSL_FUNC_RAND_INSTANTIATE,
797       (void(*)(void))drbg_ctr_instantiate_wrapper },
798     { OSSL_FUNC_RAND_UNINSTANTIATE,
799       (void(*)(void))drbg_ctr_uninstantiate_wrapper },
800     { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
801     { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
802     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
803     { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
804     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
805     { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
806       (void(*)(void))drbg_ctr_settable_ctx_params },
807     { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
808     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
809       (void(*)(void))drbg_ctr_gettable_ctx_params },
810     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
811     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
812       (void(*)(void))drbg_ctr_verify_zeroization },
813     { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
814     { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
815     OSSL_DISPATCH_END
816 };
817