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