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