xref: /freebsd/crypto/openssl/providers/implementations/rands/drbg_ctr.c (revision 78e936b2d0b5e6554425009199be31e76bc67c10)
1 /*
2  * Copyright 2011-2026 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 #ifdef FIPS_MODULE
592     /*
593      * FIPS requires that we use a derivation function since our
594      * entropy source is outside the fips boundary
595      */
596     if (ctr->use_df == 0) {
597         ERR_raise_data(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED,
598             "FIPS requires the use of a derivation function");
599         goto err;
600     }
601 #endif
602 
603     if (ctr->use_df) {
604         /* df initialisation */
605         static const unsigned char df_key[32] = {
606             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
607             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
608             0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
609             0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
610         };
611 
612         if (ctr->ctx_df == NULL)
613             ctr->ctx_df = EVP_CIPHER_CTX_new();
614         if (ctr->ctx_df == NULL) {
615             ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
616             goto err;
617         }
618         /* Set key schedule for df_key */
619         if (!EVP_CipherInit_ex(ctr->ctx_df,
620                 ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
621             ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
622             goto err;
623         }
624     }
625     return drbg_ctr_init_lengths(drbg);
626 
627 err:
628     EVP_CIPHER_CTX_free(ctr->ctx_ecb);
629     EVP_CIPHER_CTX_free(ctr->ctx_ctr);
630     ctr->ctx_ecb = ctr->ctx_ctr = NULL;
631     return 0;
632 }
633 
drbg_ctr_new(PROV_DRBG * drbg)634 static int drbg_ctr_new(PROV_DRBG *drbg)
635 {
636     PROV_DRBG_CTR *ctr;
637 
638     ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
639     if (ctr == NULL)
640         return 0;
641 
642     ctr->use_df = 1;
643     drbg->data = ctr;
644     OSSL_FIPS_IND_INIT(drbg)
645     return drbg_ctr_init_lengths(drbg);
646 }
647 
drbg_ctr_new_wrapper(void * provctx,void * parent,const OSSL_DISPATCH * parent_dispatch)648 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
649     const OSSL_DISPATCH *parent_dispatch)
650 {
651     return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
652         &drbg_ctr_new, &drbg_ctr_free,
653         &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
654         &drbg_ctr_reseed, &drbg_ctr_generate);
655 }
656 
drbg_ctr_free(void * vdrbg)657 static void drbg_ctr_free(void *vdrbg)
658 {
659     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
660     PROV_DRBG_CTR *ctr;
661 
662     if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
663         EVP_CIPHER_CTX_free(ctr->ctx_ecb);
664         EVP_CIPHER_CTX_free(ctr->ctx_ctr);
665         EVP_CIPHER_CTX_free(ctr->ctx_df);
666         EVP_CIPHER_free(ctr->cipher_ecb);
667         EVP_CIPHER_free(ctr->cipher_ctr);
668 
669         OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
670     }
671     ossl_rand_drbg_free(drbg);
672 }
673 
drbg_ctr_get_ctx_params(void * vdrbg,OSSL_PARAM params[])674 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
675 {
676     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
677     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
678     OSSL_PARAM *p;
679     int ret = 0, complete = 0;
680 
681     if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
682         return 0;
683 
684     if (complete)
685         return 1;
686 
687     if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
688         return 0;
689 
690     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
691     if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
692         goto err;
693 
694     p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
695     if (p != NULL) {
696         if (ctr->cipher_ctr == NULL
697             || !OSSL_PARAM_set_utf8_string(p,
698                 EVP_CIPHER_get0_name(ctr->cipher_ctr)))
699             goto err;
700     }
701 
702     ret = ossl_drbg_get_ctx_params(drbg, params);
703 err:
704     if (drbg->lock != NULL)
705         CRYPTO_THREAD_unlock(drbg->lock);
706 
707     return ret;
708 }
709 
drbg_ctr_gettable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)710 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
711     ossl_unused void *provctx)
712 {
713     static const OSSL_PARAM known_gettable_ctx_params[] = {
714         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
715         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
716         OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
717         OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
718             OSSL_PARAM_END
719     };
720     return known_gettable_ctx_params;
721 }
722 
drbg_ctr_set_ctx_params_locked(void * vctx,const OSSL_PARAM params[])723 static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
724 {
725     PROV_DRBG *ctx = (PROV_DRBG *)vctx;
726     PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
727     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
728     const OSSL_PARAM *p;
729     char *ecb;
730     const char *propquery = NULL;
731     int i, cipher_init = 0;
732 
733     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
734         && OSSL_PARAM_get_int(p, &i)) {
735         /* FIPS errors out in the drbg_ctr_init() call later */
736         ctr->use_df = i != 0;
737         cipher_init = 1;
738     }
739 
740     if ((p = OSSL_PARAM_locate_const(params,
741              OSSL_DRBG_PARAM_PROPERTIES))
742         != NULL) {
743         if (p->data_type != OSSL_PARAM_UTF8_STRING)
744             return 0;
745     }
746 
747 #ifndef FIPS_MODULE
748     propquery = "provider=default";
749     if (p != NULL
750         && p->data_type == OSSL_PARAM_UTF8_STRING)
751         propquery = (const char *)p->data;
752 #endif
753 
754     if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
755         const char *base = (const char *)p->data;
756         size_t ctr_str_len = sizeof("CTR") - 1;
757         size_t ecb_str_len = sizeof("ECB") - 1;
758 
759         if (p->data_type != OSSL_PARAM_UTF8_STRING
760             || p->data_size < ctr_str_len) {
761             return 0;
762         }
763         if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
764             ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
765             return 0;
766         }
767         if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
768             return 0;
769         }
770         strcpy(ecb + p->data_size - ecb_str_len, "ECB");
771         EVP_CIPHER_free(ctr->cipher_ecb);
772         EVP_CIPHER_free(ctr->cipher_ctr);
773         ctr->cipher_ctr = NULL;
774         ctr->cipher_ecb = NULL;
775         /*
776          * Try to fetch algorithms from our own provider code, fallback
777          * to generic fetch only if that fails
778          */
779         ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
780         ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
781         OPENSSL_free(ecb);
782         if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
783             ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
784             return 0;
785         }
786         cipher_init = 1;
787     }
788 
789     if (cipher_init && !drbg_ctr_init(ctx))
790         return 0;
791 
792     return ossl_drbg_set_ctx_params(ctx, params);
793 }
794 
drbg_ctr_set_ctx_params(void * vctx,const OSSL_PARAM params[])795 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
796 {
797     PROV_DRBG *drbg = (PROV_DRBG *)vctx;
798     int ret;
799 
800     if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
801         return 0;
802 
803     ret = drbg_ctr_set_ctx_params_locked(vctx, params);
804 
805     if (drbg->lock != NULL)
806         CRYPTO_THREAD_unlock(drbg->lock);
807 
808     return ret;
809 }
810 
drbg_ctr_settable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)811 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
812     ossl_unused void *provctx)
813 {
814     static const OSSL_PARAM known_settable_ctx_params[] = {
815         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
816         OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
817         OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
818         OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
819         OSSL_PARAM_END
820     };
821     return known_settable_ctx_params;
822 }
823 
824 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
825     { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_ctr_new_wrapper },
826     { OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_ctr_free },
827     { OSSL_FUNC_RAND_INSTANTIATE,
828         (void (*)(void))drbg_ctr_instantiate_wrapper },
829     { OSSL_FUNC_RAND_UNINSTANTIATE,
830         (void (*)(void))drbg_ctr_uninstantiate_wrapper },
831     { OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_ctr_generate_wrapper },
832     { OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_ctr_reseed_wrapper },
833     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },
834     { OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },
835     { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },
836     { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
837         (void (*)(void))drbg_ctr_settable_ctx_params },
838     { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_ctr_set_ctx_params },
839     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
840         (void (*)(void))drbg_ctr_gettable_ctx_params },
841     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_ctr_get_ctx_params },
842     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
843         (void (*)(void))drbg_ctr_verify_zeroization },
844     { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },
845     { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },
846     OSSL_DISPATCH_END
847 };
848