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