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