Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/rands/drbg_ctr.c
Line
Count
Source
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
/* clang-format off */
10
11
/* clang-format on */
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
31
static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
32
static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
33
static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper;
34
static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper;
35
static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper;
36
static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper;
37
static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params;
38
static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params;
39
static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
40
static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
41
static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;
42
43
static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *drbg,
44
    const struct drbg_set_ctx_params_st *p);
45
static 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
 */
51
typedef 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
 */
70
static void inc_128(PROV_DRBG_CTR *ctr)
71
455k
{
72
455k
    unsigned char *p = &ctr->V[0];
73
455k
    u32 n = 16, c = 1;
74
75
7.28M
    do {
76
7.28M
        --n;
77
7.28M
        c += p[n];
78
7.28M
        p[n] = (u8)c;
79
7.28M
        c >>= 8;
80
7.28M
    } while (n);
81
455k
}
82
83
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
84
278
{
85
278
    size_t i, n;
86
87
278
    if (in == NULL || inlen == 0)
88
0
        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
278
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
95
278
    if (!ossl_assert(n <= sizeof(ctr->K)))
96
0
        return;
97
9.17k
    for (i = 0; i < n; i++)
98
8.89k
        ctr->K[i] ^= in[i];
99
278
    if (inlen <= ctr->keylen)
100
0
        return;
101
102
278
    n = inlen - ctr->keylen;
103
278
    if (n > 16) {
104
        /* Should never happen */
105
0
        n = 16;
106
0
    }
107
4.72k
    for (i = 0; i < n; i++)
108
4.44k
        ctr->V[i] ^= in[i + ctr->keylen];
109
278
}
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
896
{
117
896
    int i, outlen = AES_BLOCK_SIZE;
118
119
43.9k
    for (i = 0; i < len; i++)
120
43.0k
        out[i] ^= in[i];
121
122
896
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
123
896
        || outlen != len)
124
0
        return 0;
125
896
    return 1;
126
896
}
127
128
/*
129
 * Handle several BCC operations for as much data as we need for K and X
130
 */
131
__owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
132
702
{
133
702
    unsigned char in_tmp[48];
134
702
    unsigned char num_of_blk = 2;
135
136
702
    memcpy(in_tmp, in, 16);
137
702
    memcpy(in_tmp + 16, in, 16);
138
702
    if (ctr->keylen != 16) {
139
702
        memcpy(in_tmp + 32, in, 16);
140
702
        num_of_blk = 3;
141
702
    }
142
702
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
143
702
}
144
145
/*
146
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
147
 * see 10.3.1 stage 7.
148
 */
149
__owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
150
194
{
151
194
    unsigned char bltmp[48] = { 0 };
152
194
    unsigned char num_of_blk;
153
154
194
    memset(ctr->KX, 0, 48);
155
194
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
156
194
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
157
194
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
158
194
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
159
194
}
160
161
/*
162
 * Process several blocks into BCC algorithm, some possibly partial
163
 */
164
__owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
165
    const unsigned char *in, size_t inlen)
166
776
{
167
776
    if (in == NULL || inlen == 0)
168
320
        return 1;
169
170
    /* If we have partial block handle it first */
171
456
    if (ctr->bltmp_pos) {
172
372
        size_t left = 16 - ctr->bltmp_pos;
173
174
        /* If we now have a complete block process it */
175
372
        if (inlen >= left) {
176
262
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
177
262
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
178
0
                return 0;
179
262
            ctr->bltmp_pos = 0;
180
262
            inlen -= left;
181
262
            in += left;
182
262
        }
183
372
    }
184
185
    /* Process zero or more complete blocks */
186
702
    for (; inlen >= 16; in += 16, inlen -= 16) {
187
246
        if (!ctr_BCC_blocks(ctr, in))
188
0
            return 0;
189
246
    }
190
191
    /* Copy any remaining partial block to the temporary buffer */
192
456
    if (inlen > 0) {
193
372
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
194
372
        ctr->bltmp_pos += inlen;
195
372
    }
196
456
    return 1;
197
456
}
198
199
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
200
194
{
201
194
    if (ctr->bltmp_pos) {
202
194
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
203
194
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
204
0
            return 0;
205
194
    }
206
194
    return 1;
207
194
}
208
209
__owur static int ctr_df(PROV_DRBG_CTR *ctr,
210
    const unsigned char *in1, size_t in1len,
211
    const unsigned char *in2, size_t in2len,
212
    const unsigned char *in3, size_t in3len)
213
194
{
214
194
    static unsigned char c80 = 0x80;
215
194
    size_t inlen;
216
194
    unsigned char *p = ctr->bltmp;
217
194
    int outlen = AES_BLOCK_SIZE;
218
219
194
    if (!ctr_BCC_init(ctr))
220
0
        return 0;
221
194
    if (in1 == NULL)
222
0
        in1len = 0;
223
194
    if (in2 == NULL)
224
194
        in2len = 0;
225
194
    if (in3 == NULL)
226
126
        in3len = 0;
227
194
    inlen = in1len + in2len + in3len;
228
    /* Initialise L||N in temporary block */
229
194
    *p++ = (inlen >> 24) & 0xff;
230
194
    *p++ = (inlen >> 16) & 0xff;
231
194
    *p++ = (inlen >> 8) & 0xff;
232
194
    *p++ = inlen & 0xff;
233
234
    /* NB keylen is at most 32 bytes */
235
194
    *p++ = 0;
236
194
    *p++ = 0;
237
194
    *p++ = 0;
238
194
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
239
194
    ctr->bltmp_pos = 8;
240
194
    if (!ctr_BCC_update(ctr, in1, in1len)
241
194
        || !ctr_BCC_update(ctr, in2, in2len)
242
194
        || !ctr_BCC_update(ctr, in3, in3len)
243
194
        || !ctr_BCC_update(ctr, &c80, 1)
244
194
        || !ctr_BCC_final(ctr))
245
0
        return 0;
246
    /* Set up key K */
247
194
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
248
0
        return 0;
249
    /* X follows key K */
250
194
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
251
194
            AES_BLOCK_SIZE)
252
194
        || outlen != AES_BLOCK_SIZE)
253
0
        return 0;
254
194
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
255
194
            AES_BLOCK_SIZE)
256
194
        || outlen != AES_BLOCK_SIZE)
257
0
        return 0;
258
194
    if (ctr->keylen != 16)
259
194
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
260
194
                ctr->KX + 16, AES_BLOCK_SIZE)
261
194
            || outlen != AES_BLOCK_SIZE)
262
0
            return 0;
263
194
    return 1;
264
194
}
265
266
/*
267
 * NB the no-df Update in SP800-90A specifies a constant input length
268
 * of seedlen, however other uses of this algorithm pad the input with
269
 * zeroes if necessary and have up to two parameters XORed together,
270
 * so we handle both cases in this function instead.
271
 */
272
__owur static int ctr_update(PROV_DRBG *drbg,
273
    const unsigned char *in1, size_t in1len,
274
    const unsigned char *in2, size_t in2len,
275
    const unsigned char *nonce, size_t noncelen)
276
151k
{
277
151k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
278
151k
    int outlen = AES_BLOCK_SIZE;
279
151k
    unsigned char V_tmp[48], out[48];
280
151k
    unsigned char len;
281
282
    /* correct key is already set up. */
283
151k
    memcpy(V_tmp, ctr->V, 16);
284
151k
    inc_128(ctr);
285
151k
    memcpy(V_tmp + 16, ctr->V, 16);
286
151k
    if (ctr->keylen == 16) {
287
0
        len = 32;
288
151k
    } else {
289
151k
        inc_128(ctr);
290
151k
        memcpy(V_tmp + 32, ctr->V, 16);
291
151k
        len = 48;
292
151k
    }
293
151k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
294
151k
        || outlen != len)
295
0
        return 0;
296
151k
    memcpy(ctr->K, out, ctr->keylen);
297
151k
    memcpy(ctr->V, out + ctr->keylen, 16);
298
299
151k
    if (ctr->use_df) {
300
        /* If no input reuse existing derived value */
301
151k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
302
194
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
303
0
                return 0;
304
        /* If this a reuse input in1len != 0 */
305
151k
        if (in1len)
306
278
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
307
151k
    } else {
308
0
        ctr_XOR(ctr, in1, in1len);
309
0
        ctr_XOR(ctr, in2, in2len);
310
0
    }
311
312
151k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
313
151k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
314
0
        return 0;
315
151k
    return 1;
316
151k
}
317
318
static int drbg_ctr_instantiate(PROV_DRBG *drbg,
319
    const unsigned char *entropy, size_t entropylen,
320
    const unsigned char *nonce, size_t noncelen,
321
    const unsigned char *pers, size_t perslen)
322
68
{
323
68
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
324
325
68
    if (entropy == NULL)
326
0
        return 0;
327
328
68
    memset(ctr->K, 0, sizeof(ctr->K));
329
68
    memset(ctr->V, 0, sizeof(ctr->V));
330
68
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
331
0
        return 0;
332
333
68
    inc_128(ctr);
334
68
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
335
0
        return 0;
336
68
    return 1;
337
68
}
338
339
static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
340
    int prediction_resistance,
341
    const unsigned char *pstr,
342
    size_t pstr_len,
343
    const OSSL_PARAM params[])
344
53
{
345
53
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
346
53
    struct drbg_set_ctx_params_st p;
347
53
    int ret = 0;
348
349
53
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
350
0
        return 0;
351
352
53
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
353
0
        return 0;
354
355
53
    if (!ossl_prov_is_running()
356
53
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
357
0
        goto err;
358
53
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
359
53
        pstr, pstr_len);
360
53
err:
361
53
    if (drbg->lock != NULL)
362
0
        CRYPTO_THREAD_unlock(drbg->lock);
363
53
    return ret;
364
53
}
365
366
static int drbg_ctr_reseed(PROV_DRBG *drbg,
367
    const unsigned char *entropy, size_t entropylen,
368
    const unsigned char *adin, size_t adinlen)
369
42
{
370
42
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
371
372
42
    if (entropy == NULL)
373
0
        return 0;
374
375
42
    inc_128(ctr);
376
42
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
377
0
        return 0;
378
42
    return 1;
379
42
}
380
381
static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
382
    const unsigned char *ent, size_t ent_len,
383
    const unsigned char *adin, size_t adin_len)
384
0
{
385
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
386
387
0
    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
388
0
        adin, adin_len);
389
0
}
390
391
static void ctr96_inc(unsigned char *counter)
392
0
{
393
0
    u32 n = 12, c = 1;
394
395
0
    do {
396
0
        --n;
397
0
        c += counter[n];
398
0
        counter[n] = (u8)c;
399
0
        c >>= 8;
400
0
    } while (n);
401
0
}
402
403
static int drbg_ctr_generate(PROV_DRBG *drbg,
404
    unsigned char *out, size_t outlen,
405
    const unsigned char *adin, size_t adinlen)
406
151k
{
407
151k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
408
151k
    unsigned int ctr32, blocks;
409
151k
    int outl, buflen;
410
411
151k
    if (adin != NULL && adinlen != 0) {
412
84
        inc_128(ctr);
413
414
84
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
415
0
            return 0;
416
        /* This means we reuse derived value */
417
84
        if (ctr->use_df) {
418
84
            adin = NULL;
419
84
            adinlen = 1;
420
84
        }
421
151k
    } else {
422
151k
        adinlen = 0;
423
151k
    }
424
425
151k
    inc_128(ctr);
426
427
151k
    if (outlen == 0) {
428
0
        inc_128(ctr);
429
430
0
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
431
0
            return 0;
432
0
        return 1;
433
0
    }
434
435
151k
    memset(out, 0, outlen);
436
437
151k
    do {
438
151k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
439
151k
                NULL, NULL, NULL, ctr->V, -1))
440
0
            return 0;
441
442
        /*-
443
         * outlen has type size_t while EVP_CipherUpdate takes an
444
         * int argument and thus cannot be guaranteed to process more
445
         * than 2^31-1 bytes at a time. We process such huge generate
446
         * requests in 2^30 byte chunks, which is the greatest multiple
447
         * of AES block size lower than or equal to 2^31-1.
448
         */
449
151k
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
450
151k
        blocks = (buflen + 15) / 16;
451
452
151k
        ctr32 = GETU32(ctr->V + 12) + blocks;
453
151k
        if (ctr32 < blocks) {
454
            /* 32-bit counter overflow into V. */
455
0
            if (ctr32 != 0) {
456
0
                blocks -= ctr32;
457
0
                buflen = blocks * 16;
458
0
                ctr32 = 0;
459
0
            }
460
0
            ctr96_inc(ctr->V);
461
0
        }
462
151k
        PUTU32(ctr->V + 12, ctr32);
463
464
151k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
465
151k
            || outl != buflen)
466
0
            return 0;
467
468
151k
        out += buflen;
469
151k
        outlen -= buflen;
470
151k
    } while (outlen);
471
472
151k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
473
0
        return 0;
474
151k
    return 1;
475
151k
}
476
477
static int drbg_ctr_generate_wrapper(void *vdrbg, unsigned char *out, size_t outlen,
478
    unsigned int strength, int prediction_resistance,
479
    const unsigned char *adin, size_t adin_len)
480
151k
{
481
151k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482
483
151k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
484
151k
        prediction_resistance, adin, adin_len);
485
151k
}
486
487
static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
488
0
{
489
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
490
491
0
    OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
492
0
    OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
493
0
    OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
494
0
    OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
495
0
    ctr->bltmp_pos = 0;
496
0
    return ossl_prov_drbg_uninstantiate(drbg);
497
0
}
498
499
static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
500
0
{
501
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
502
0
    int ret;
503
504
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
505
0
        return 0;
506
507
0
    ret = drbg_ctr_uninstantiate(drbg);
508
509
0
    if (drbg->lock != NULL)
510
0
        CRYPTO_THREAD_unlock(drbg->lock);
511
512
0
    return ret;
513
0
}
514
515
static int drbg_ctr_verify_zeroization(void *vdrbg)
516
0
{
517
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
518
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
519
0
    int ret = 0;
520
521
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
522
0
        return 0;
523
524
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->K);
525
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->V);
526
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp);
527
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX);
528
0
    if (ctr->bltmp_pos != 0)
529
0
        goto err;
530
531
0
    ret = 1;
532
0
err:
533
0
    if (drbg->lock != NULL)
534
0
        CRYPTO_THREAD_unlock(drbg->lock);
535
0
    return ret;
536
0
}
537
538
static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
539
330
{
540
330
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
541
330
    int res = 1;
542
543
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
544
330
    drbg->max_request = 1 << 16;
545
330
    if (ctr->use_df) {
546
330
        drbg->min_entropylen = 0;
547
330
        drbg->max_entropylen = DRBG_MAX_LENGTH;
548
330
        drbg->min_noncelen = 0;
549
330
        drbg->max_noncelen = DRBG_MAX_LENGTH;
550
330
        drbg->max_perslen = DRBG_MAX_LENGTH;
551
330
        drbg->max_adinlen = DRBG_MAX_LENGTH;
552
553
330
        if (ctr->keylen > 0) {
554
68
            drbg->min_entropylen = ctr->keylen;
555
68
            drbg->min_noncelen = drbg->min_entropylen / 2;
556
68
        }
557
330
    } else {
558
0
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
559
560
0
        drbg->min_entropylen = len;
561
0
        drbg->max_entropylen = len;
562
        /* Nonce not used */
563
0
        drbg->min_noncelen = 0;
564
0
        drbg->max_noncelen = 0;
565
0
        drbg->max_perslen = len;
566
0
        drbg->max_adinlen = len;
567
0
    }
568
330
    return res;
569
330
}
570
571
static int drbg_ctr_init(PROV_DRBG *drbg)
572
68
{
573
68
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
574
68
    size_t keylen;
575
576
68
    if (ctr->cipher_ctr == NULL) {
577
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
578
0
        return 0;
579
0
    }
580
68
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
581
68
    if (ctr->ctx_ecb == NULL)
582
68
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
583
68
    if (ctr->ctx_ctr == NULL)
584
68
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
585
68
    if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
586
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
587
0
        goto err;
588
0
    }
589
590
68
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
591
68
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
592
68
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
593
68
            ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
594
0
        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
595
0
        goto err;
596
0
    }
597
598
68
    drbg->strength = (unsigned int)(keylen * 8);
599
68
    drbg->seedlen = keylen + 16;
600
601
#ifdef FIPS_MODULE
602
    /*
603
     * FIPS requires that we use a derivation function since our
604
     * entropy source is outside the fips boundary
605
     */
606
    if (ctr->use_df == 0) {
607
        ERR_raise_data(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED,
608
            "FIPS requires the use of a derivation function");
609
        goto err;
610
    }
611
#endif
612
613
68
    if (ctr->use_df) {
614
        /* df initialisation */
615
68
        static const unsigned char df_key[32] = {
616
68
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
617
68
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
618
68
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
619
68
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
620
68
        };
621
622
68
        if (ctr->ctx_df == NULL)
623
68
            ctr->ctx_df = EVP_CIPHER_CTX_new();
624
68
        if (ctr->ctx_df == NULL) {
625
0
            ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
626
0
            goto err;
627
0
        }
628
        /* Set key schedule for df_key */
629
68
        if (!EVP_CipherInit_ex(ctr->ctx_df,
630
68
                ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
631
0
            ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
632
0
            goto err;
633
0
        }
634
68
    }
635
68
    return drbg_ctr_init_lengths(drbg);
636
637
0
err:
638
0
    EVP_CIPHER_CTX_free(ctr->ctx_ecb);
639
0
    EVP_CIPHER_CTX_free(ctr->ctx_ctr);
640
0
    ctr->ctx_ecb = ctr->ctx_ctr = NULL;
641
0
    return 0;
642
68
}
643
644
static int drbg_ctr_new(PROV_DRBG *drbg)
645
262
{
646
262
    PROV_DRBG_CTR *ctr;
647
648
262
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
649
262
    if (ctr == NULL)
650
0
        return 0;
651
652
262
    ctr->use_df = 1;
653
262
    drbg->data = ctr;
654
262
    OSSL_FIPS_IND_INIT(drbg)
655
262
    return drbg_ctr_init_lengths(drbg);
656
262
}
657
658
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
659
    const OSSL_DISPATCH *parent_dispatch)
660
262
{
661
262
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
662
262
        &drbg_ctr_new, &drbg_ctr_free,
663
262
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
664
262
        &drbg_ctr_reseed, &drbg_ctr_generate);
665
262
}
666
667
static void drbg_ctr_free(void *vdrbg)
668
219
{
669
219
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
670
219
    PROV_DRBG_CTR *ctr;
671
672
219
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
673
219
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
674
219
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
675
219
        EVP_CIPHER_CTX_free(ctr->ctx_df);
676
219
        EVP_CIPHER_free(ctr->cipher_ecb);
677
219
        EVP_CIPHER_free(ctr->cipher_ctr);
678
679
219
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
680
219
    }
681
219
    ossl_rand_drbg_free(drbg);
682
219
}
683
684
#define drbg_ctr_get_ctx_params_st drbg_get_ctx_params_st
685
686
/* clang-format off */
687
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
688
#ifndef drbg_ctr_get_ctx_params_list
689
static ossl_unused const OSSL_PARAM drbg_ctr_get_ctx_params_list[] = {
690
    OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
691
    OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
692
    OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
693
    OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
694
    OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
695
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MIN_ENTROPYLEN, NULL),
696
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ENTROPYLEN, NULL),
697
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MIN_NONCELEN, NULL),
698
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_NONCELEN, NULL),
699
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_PERSLEN, NULL),
700
    OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ADINLEN, NULL),
701
    OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, NULL),
702
    OSSL_PARAM_time_t(OSSL_DRBG_PARAM_RESEED_TIME, NULL),
703
    OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL),
704
    OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL),
705
# if defined(FIPS_MODULE)
706
    OSSL_PARAM_int(OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR, NULL),
707
# endif
708
    OSSL_PARAM_END
709
};
710
#endif
711
712
#ifndef drbg_ctr_get_ctx_params_st
713
struct drbg_ctr_get_ctx_params_st {
714
    OSSL_PARAM *cipher;
715
    OSSL_PARAM *df;
716
# if defined(FIPS_MODULE)
717
    OSSL_PARAM *ind;
718
# endif
719
    OSSL_PARAM *maxadlen;
720
    OSSL_PARAM *maxentlen;
721
    OSSL_PARAM *maxnonlen;
722
    OSSL_PARAM *maxperlen;
723
    OSSL_PARAM *maxreq;
724
    OSSL_PARAM *minentlen;
725
    OSSL_PARAM *minnonlen;
726
    OSSL_PARAM *reseed_cnt;
727
    OSSL_PARAM *reseed_int;
728
    OSSL_PARAM *reseed_req;
729
    OSSL_PARAM *reseed_time;
730
    OSSL_PARAM *state;
731
    OSSL_PARAM *str;
732
};
733
#endif
734
735
#ifndef drbg_ctr_get_ctx_params_decoder
736
static ossl_unused int drbg_ctr_get_ctx_params_decoder
737
    (const OSSL_PARAM *p, struct drbg_ctr_get_ctx_params_st *r)
738
241k
{
739
241k
    const char *s;
740
741
241k
    memset(r, 0, sizeof(*r));
742
241k
    if (p != NULL)
743
482k
        for (; (s = p->key) != NULL; p++)
744
241k
            switch(s[0]) {
745
0
            default:
746
0
                break;
747
0
            case 'c':
748
0
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
749
                    /* OSSL_DRBG_PARAM_CIPHER */
750
0
                    if (ossl_unlikely(r->cipher != NULL)) {
751
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
752
0
                                       "param %s is repeated", s);
753
0
                        return 0;
754
0
                    }
755
0
                    r->cipher = (OSSL_PARAM *)p;
756
0
                }
757
0
                break;
758
0
            case 'f':
759
# if defined(FIPS_MODULE)
760
                if (ossl_likely(strcmp("ips-indicator", s + 1) == 0)) {
761
                    /* OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR */
762
                    if (ossl_unlikely(r->ind != NULL)) {
763
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
764
                                       "param %s is repeated", s);
765
                        return 0;
766
                    }
767
                    r->ind = (OSSL_PARAM *)p;
768
                }
769
# endif
770
0
                break;
771
120k
            case 'm':
772
120k
                switch(s[1]) {
773
0
                default:
774
0
                    break;
775
120k
                case 'a':
776
120k
                    switch(s[2]) {
777
0
                    default:
778
0
                        break;
779
120k
                    case 'x':
780
120k
                        switch(s[3]) {
781
0
                        default:
782
0
                            break;
783
120k
                        case '_':
784
120k
                            switch(s[4]) {
785
0
                            default:
786
0
                                break;
787
0
                            case 'a':
788
0
                                if (ossl_likely(strcmp("dinlen", s + 5) == 0)) {
789
                                    /* OSSL_DRBG_PARAM_MAX_ADINLEN */
790
0
                                    if (ossl_unlikely(r->maxadlen != NULL)) {
791
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
792
0
                                                       "param %s is repeated", s);
793
0
                                        return 0;
794
0
                                    }
795
0
                                    r->maxadlen = (OSSL_PARAM *)p;
796
0
                                }
797
0
                                break;
798
0
                            case 'e':
799
0
                                if (ossl_likely(strcmp("ntropylen", s + 5) == 0)) {
800
                                    /* OSSL_DRBG_PARAM_MAX_ENTROPYLEN */
801
0
                                    if (ossl_unlikely(r->maxentlen != NULL)) {
802
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
803
0
                                                       "param %s is repeated", s);
804
0
                                        return 0;
805
0
                                    }
806
0
                                    r->maxentlen = (OSSL_PARAM *)p;
807
0
                                }
808
0
                                break;
809
0
                            case 'n':
810
0
                                if (ossl_likely(strcmp("oncelen", s + 5) == 0)) {
811
                                    /* OSSL_DRBG_PARAM_MAX_NONCELEN */
812
0
                                    if (ossl_unlikely(r->maxnonlen != NULL)) {
813
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
814
0
                                                       "param %s is repeated", s);
815
0
                                        return 0;
816
0
                                    }
817
0
                                    r->maxnonlen = (OSSL_PARAM *)p;
818
0
                                }
819
0
                                break;
820
0
                            case 'p':
821
0
                                if (ossl_likely(strcmp("erslen", s + 5) == 0)) {
822
                                    /* OSSL_DRBG_PARAM_MAX_PERSLEN */
823
0
                                    if (ossl_unlikely(r->maxperlen != NULL)) {
824
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
825
0
                                                       "param %s is repeated", s);
826
0
                                        return 0;
827
0
                                    }
828
0
                                    r->maxperlen = (OSSL_PARAM *)p;
829
0
                                }
830
0
                                break;
831
120k
                            case 'r':
832
120k
                                if (ossl_likely(strcmp("equest", s + 5) == 0)) {
833
                                    /* OSSL_RAND_PARAM_MAX_REQUEST */
834
120k
                                    if (ossl_unlikely(r->maxreq != NULL)) {
835
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
836
0
                                                       "param %s is repeated", s);
837
0
                                        return 0;
838
0
                                    }
839
120k
                                    r->maxreq = (OSSL_PARAM *)p;
840
120k
                                }
841
120k
                            }
842
120k
                        }
843
120k
                    }
844
120k
                    break;
845
120k
                case 'i':
846
0
                    switch(s[2]) {
847
0
                    default:
848
0
                        break;
849
0
                    case 'n':
850
0
                        switch(s[3]) {
851
0
                        default:
852
0
                            break;
853
0
                        case '_':
854
0
                            switch(s[4]) {
855
0
                            default:
856
0
                                break;
857
0
                            case 'e':
858
0
                                if (ossl_likely(strcmp("ntropylen", s + 5) == 0)) {
859
                                    /* OSSL_DRBG_PARAM_MIN_ENTROPYLEN */
860
0
                                    if (ossl_unlikely(r->minentlen != NULL)) {
861
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
862
0
                                                       "param %s is repeated", s);
863
0
                                        return 0;
864
0
                                    }
865
0
                                    r->minentlen = (OSSL_PARAM *)p;
866
0
                                }
867
0
                                break;
868
0
                            case 'n':
869
0
                                if (ossl_likely(strcmp("oncelen", s + 5) == 0)) {
870
                                    /* OSSL_DRBG_PARAM_MIN_NONCELEN */
871
0
                                    if (ossl_unlikely(r->minnonlen != NULL)) {
872
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
873
0
                                                       "param %s is repeated", s);
874
0
                                        return 0;
875
0
                                    }
876
0
                                    r->minnonlen = (OSSL_PARAM *)p;
877
0
                                }
878
0
                            }
879
0
                        }
880
0
                    }
881
120k
                }
882
120k
                break;
883
120k
            case 'r':
884
120k
                switch(s[1]) {
885
0
                default:
886
0
                    break;
887
120k
                case 'e':
888
120k
                    switch(s[2]) {
889
0
                    default:
890
0
                        break;
891
120k
                    case 's':
892
120k
                        switch(s[3]) {
893
0
                        default:
894
0
                            break;
895
120k
                        case 'e':
896
120k
                            switch(s[4]) {
897
0
                            default:
898
0
                                break;
899
120k
                            case 'e':
900
120k
                                switch(s[5]) {
901
0
                                default:
902
0
                                    break;
903
120k
                                case 'd':
904
120k
                                    switch(s[6]) {
905
0
                                    default:
906
0
                                        break;
907
120k
                                    case '_':
908
120k
                                        switch(s[7]) {
909
0
                                        default:
910
0
                                            break;
911
120k
                                        case 'c':
912
120k
                                            if (ossl_likely(strcmp("ounter", s + 8) == 0)) {
913
                                                /* OSSL_DRBG_PARAM_RESEED_COUNTER */
914
120k
                                                if (ossl_unlikely(r->reseed_cnt != NULL)) {
915
0
                                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
916
0
                                                                   "param %s is repeated", s);
917
0
                                                    return 0;
918
0
                                                }
919
120k
                                                r->reseed_cnt = (OSSL_PARAM *)p;
920
120k
                                            }
921
120k
                                            break;
922
120k
                                        case 'r':
923
0
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
924
                                                /* OSSL_DRBG_PARAM_RESEED_REQUESTS */
925
0
                                                if (ossl_unlikely(r->reseed_req != NULL)) {
926
0
                                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
927
0
                                                                   "param %s is repeated", s);
928
0
                                                    return 0;
929
0
                                                }
930
0
                                                r->reseed_req = (OSSL_PARAM *)p;
931
0
                                            }
932
0
                                            break;
933
0
                                        case 't':
934
0
                                            switch(s[8]) {
935
0
                                            default:
936
0
                                                break;
937
0
                                            case 'i':
938
0
                                                switch(s[9]) {
939
0
                                                default:
940
0
                                                    break;
941
0
                                                case 'm':
942
0
                                                    switch(s[10]) {
943
0
                                                    default:
944
0
                                                        break;
945
0
                                                    case 'e':
946
0
                                                        switch(s[11]) {
947
0
                                                        default:
948
0
                                                            break;
949
0
                                                        case '_':
950
0
                                                            if (ossl_likely(strcmp("interval", s + 12) == 0)) {
951
                                                                /* OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL */
952
0
                                                                if (ossl_unlikely(r->reseed_int != NULL)) {
953
0
                                                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
954
0
                                                                                   "param %s is repeated", s);
955
0
                                                                    return 0;
956
0
                                                                }
957
0
                                                                r->reseed_int = (OSSL_PARAM *)p;
958
0
                                                            }
959
0
                                                            break;
960
0
                                                        case '\0':
961
0
                                                            if (ossl_unlikely(r->reseed_time != NULL)) {
962
0
                                                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
963
0
                                                                               "param %s is repeated", s);
964
0
                                                                return 0;
965
0
                                                            }
966
0
                                                            r->reseed_time = (OSSL_PARAM *)p;
967
0
                                                        }
968
0
                                                    }
969
0
                                                }
970
0
                                            }
971
120k
                                        }
972
120k
                                    }
973
120k
                                }
974
120k
                            }
975
120k
                        }
976
120k
                    }
977
120k
                }
978
120k
                break;
979
120k
            case 's':
980
99
                switch(s[1]) {
981
0
                default:
982
0
                    break;
983
99
                case 't':
984
99
                    switch(s[2]) {
985
0
                    default:
986
0
                        break;
987
0
                    case 'a':
988
0
                        if (ossl_likely(strcmp("te", s + 3) == 0)) {
989
                            /* OSSL_RAND_PARAM_STATE */
990
0
                            if (ossl_unlikely(r->state != NULL)) {
991
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
992
0
                                               "param %s is repeated", s);
993
0
                                return 0;
994
0
                            }
995
0
                            r->state = (OSSL_PARAM *)p;
996
0
                        }
997
0
                        break;
998
99
                    case 'r':
999
99
                        if (ossl_likely(strcmp("ength", s + 3) == 0)) {
1000
                            /* OSSL_RAND_PARAM_STRENGTH */
1001
99
                            if (ossl_unlikely(r->str != NULL)) {
1002
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1003
0
                                               "param %s is repeated", s);
1004
0
                                return 0;
1005
0
                            }
1006
99
                            r->str = (OSSL_PARAM *)p;
1007
99
                        }
1008
99
                    }
1009
99
                }
1010
99
                break;
1011
99
            case 'u':
1012
0
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1013
                    /* OSSL_DRBG_PARAM_USE_DF */
1014
0
                    if (ossl_unlikely(r->df != NULL)) {
1015
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1016
0
                                       "param %s is repeated", s);
1017
0
                        return 0;
1018
0
                    }
1019
0
                    r->df = (OSSL_PARAM *)p;
1020
0
                }
1021
241k
            }
1022
241k
    return 1;
1023
241k
}
1024
#endif
1025
/* End of machine generated */
1026
/* clang-format on */
1027
1028
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
1029
241k
{
1030
241k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
1031
241k
    PROV_DRBG_CTR *ctr;
1032
241k
    struct drbg_ctr_get_ctx_params_st p;
1033
241k
    int ret = 0, complete = 0;
1034
1035
241k
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
1036
0
        return 0;
1037
1038
241k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
1039
0
        return 0;
1040
1041
241k
    if (complete)
1042
241k
        return 1;
1043
1044
99
    ctr = (PROV_DRBG_CTR *)drbg->data;
1045
1046
99
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
1047
0
        return 0;
1048
1049
99
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
1050
0
        goto err;
1051
1052
99
    if (p.cipher != NULL) {
1053
0
        if (ctr->cipher_ctr == NULL
1054
0
            || !OSSL_PARAM_set_utf8_string(p.cipher,
1055
0
                EVP_CIPHER_get0_name(ctr->cipher_ctr)))
1056
0
            goto err;
1057
0
    }
1058
1059
99
    ret = ossl_drbg_get_ctx_params(drbg, &p);
1060
99
err:
1061
99
    if (drbg->lock != NULL)
1062
99
        CRYPTO_THREAD_unlock(drbg->lock);
1063
1064
99
    return ret;
1065
99
}
1066
1067
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
1068
    ossl_unused void *provctx)
1069
0
{
1070
0
    return drbg_ctr_get_ctx_params_list;
1071
0
}
1072
1073
static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
1074
    const struct drbg_set_ctx_params_st *p)
1075
180
{
1076
180
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
1077
180
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
1078
180
    char *ecb;
1079
180
    const char *propquery = NULL;
1080
180
    int i, cipher_init = 0;
1081
1082
180
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
1083
        /* FIPS errors out in the drbg_ctr_init() call later */
1084
180
        ctr->use_df = i != 0;
1085
180
        cipher_init = 1;
1086
180
    }
1087
1088
180
#ifndef FIPS_MODULE
1089
180
    propquery = "provider=default";
1090
180
    if (p->propq != NULL
1091
127
        && p->propq->data_type == OSSL_PARAM_UTF8_STRING)
1092
127
        propquery = (const char *)p->propq->data;
1093
180
#endif
1094
1095
180
    if (p->cipher != NULL) {
1096
180
        const char *base = (const char *)p->cipher->data;
1097
180
        size_t ctr_str_len = sizeof("CTR") - 1;
1098
180
        size_t ecb_str_len = sizeof("ECB") - 1;
1099
1100
180
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
1101
180
            || p->cipher->data_size < ctr_str_len) {
1102
45
            return 0;
1103
45
        }
1104
135
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
1105
82
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
1106
82
            return 0;
1107
82
        }
1108
53
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
1109
0
            return 0;
1110
0
        }
1111
53
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
1112
53
        EVP_CIPHER_free(ctr->cipher_ecb);
1113
53
        EVP_CIPHER_free(ctr->cipher_ctr);
1114
53
        ctr->cipher_ctr = NULL;
1115
53
        ctr->cipher_ecb = NULL;
1116
        /*
1117
         * Try to fetch algorithms from our own provider code, fallback
1118
         * to generic fetch only if that fails
1119
         */
1120
53
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
1121
53
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
1122
53
        OPENSSL_free(ecb);
1123
53
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
1124
0
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
1125
0
            return 0;
1126
0
        }
1127
53
        cipher_init = 1;
1128
53
    }
1129
1130
53
    if (cipher_init && !drbg_ctr_init(ctx))
1131
0
        return 0;
1132
1133
53
    return ossl_drbg_set_ctx_params(ctx, p);
1134
53
}
1135
1136
#define drbg_ctr_set_ctx_params_st drbg_set_ctx_params_st
1137
1138
/* clang-format off */
1139
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
1140
#ifndef drbg_ctr_set_ctx_params_list
1141
static ossl_unused const OSSL_PARAM drbg_ctr_set_ctx_params_list[] = {
1142
    OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
1143
    OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
1144
    OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
1145
    OSSL_PARAM_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME, NULL, 0),
1146
    OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL),
1147
    OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL),
1148
    OSSL_PARAM_END
1149
};
1150
#endif
1151
1152
#ifndef drbg_ctr_set_ctx_params_st
1153
struct drbg_ctr_set_ctx_params_st {
1154
    OSSL_PARAM *cipher;
1155
    OSSL_PARAM *df;
1156
    OSSL_PARAM *propq;
1157
    OSSL_PARAM *prov;
1158
    OSSL_PARAM *reseed_req;
1159
    OSSL_PARAM *reseed_time;
1160
};
1161
#endif
1162
1163
#ifndef drbg_ctr_set_ctx_params_decoder
1164
static ossl_unused int drbg_ctr_set_ctx_params_decoder
1165
    (const OSSL_PARAM *p, struct drbg_ctr_set_ctx_params_st *r)
1166
34
{
1167
34
    const char *s;
1168
1169
34
    memset(r, 0, sizeof(*r));
1170
34
    if (p != NULL)
1171
216
        for (; (s = p->key) != NULL; p++)
1172
182
            switch(s[0]) {
1173
0
            default:
1174
0
                break;
1175
34
            case 'c':
1176
34
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
1177
                    /* OSSL_DRBG_PARAM_CIPHER */
1178
34
                    if (ossl_unlikely(r->cipher != NULL)) {
1179
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1180
0
                                       "param %s is repeated", s);
1181
0
                        return 0;
1182
0
                    }
1183
34
                    r->cipher = (OSSL_PARAM *)p;
1184
34
                }
1185
34
                break;
1186
46
            case 'p':
1187
46
                switch(s[1]) {
1188
0
                default:
1189
0
                    break;
1190
46
                case 'r':
1191
46
                    switch(s[2]) {
1192
0
                    default:
1193
0
                        break;
1194
46
                    case 'o':
1195
46
                        switch(s[3]) {
1196
0
                        default:
1197
0
                            break;
1198
23
                        case 'p':
1199
23
                            if (ossl_likely(strcmp("erties", s + 4) == 0)) {
1200
                                /* OSSL_DRBG_PARAM_PROPERTIES */
1201
23
                                if (ossl_unlikely(r->propq != NULL)) {
1202
0
                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1203
0
                                                   "param %s is repeated", s);
1204
0
                                    return 0;
1205
0
                                }
1206
23
                                r->propq = (OSSL_PARAM *)p;
1207
23
                            }
1208
23
                            break;
1209
23
                        case 'v':
1210
23
                            if (ossl_likely(strcmp("ider-name", s + 4) == 0)) {
1211
                                /* OSSL_PROV_PARAM_CORE_PROV_NAME */
1212
23
                                if (ossl_unlikely(r->prov != NULL)) {
1213
0
                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1214
0
                                                   "param %s is repeated", s);
1215
0
                                    return 0;
1216
0
                                }
1217
23
                                r->prov = (OSSL_PARAM *)p;
1218
23
                            }
1219
46
                        }
1220
46
                    }
1221
46
                }
1222
46
                break;
1223
68
            case 'r':
1224
68
                switch(s[1]) {
1225
0
                default:
1226
0
                    break;
1227
68
                case 'e':
1228
68
                    switch(s[2]) {
1229
0
                    default:
1230
0
                        break;
1231
68
                    case 's':
1232
68
                        switch(s[3]) {
1233
0
                        default:
1234
0
                            break;
1235
68
                        case 'e':
1236
68
                            switch(s[4]) {
1237
0
                            default:
1238
0
                                break;
1239
68
                            case 'e':
1240
68
                                switch(s[5]) {
1241
0
                                default:
1242
0
                                    break;
1243
68
                                case 'd':
1244
68
                                    switch(s[6]) {
1245
0
                                    default:
1246
0
                                        break;
1247
68
                                    case '_':
1248
68
                                        switch(s[7]) {
1249
0
                                        default:
1250
0
                                            break;
1251
34
                                        case 'r':
1252
34
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
1253
                                                /* OSSL_DRBG_PARAM_RESEED_REQUESTS */
1254
34
                                                if (ossl_unlikely(r->reseed_req != NULL)) {
1255
0
                                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1256
0
                                                                   "param %s is repeated", s);
1257
0
                                                    return 0;
1258
0
                                                }
1259
34
                                                r->reseed_req = (OSSL_PARAM *)p;
1260
34
                                            }
1261
34
                                            break;
1262
34
                                        case 't':
1263
34
                                            if (ossl_likely(strcmp("ime_interval", s + 8) == 0)) {
1264
                                                /* OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL */
1265
34
                                                if (ossl_unlikely(r->reseed_time != NULL)) {
1266
0
                                                    ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1267
0
                                                                   "param %s is repeated", s);
1268
0
                                                    return 0;
1269
0
                                                }
1270
34
                                                r->reseed_time = (OSSL_PARAM *)p;
1271
34
                                            }
1272
68
                                        }
1273
68
                                    }
1274
68
                                }
1275
68
                            }
1276
68
                        }
1277
68
                    }
1278
68
                }
1279
68
                break;
1280
68
            case 'u':
1281
34
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1282
                    /* OSSL_DRBG_PARAM_USE_DF */
1283
34
                    if (ossl_unlikely(r->df != NULL)) {
1284
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1285
0
                                       "param %s is repeated", s);
1286
0
                        return 0;
1287
0
                    }
1288
34
                    r->df = (OSSL_PARAM *)p;
1289
34
                }
1290
182
            }
1291
34
    return 1;
1292
34
}
1293
#endif
1294
/* End of machine generated */
1295
/* clang-format on */
1296
1297
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
1298
127
{
1299
127
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
1300
127
    struct drbg_set_ctx_params_st p;
1301
127
    int ret;
1302
1303
127
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
1304
0
        return 0;
1305
1306
127
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
1307
0
        return 0;
1308
1309
127
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
1310
1311
127
    if (drbg->lock != NULL)
1312
0
        CRYPTO_THREAD_unlock(drbg->lock);
1313
1314
127
    return ret;
1315
127
}
1316
1317
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
1318
    ossl_unused void *provctx)
1319
262
{
1320
262
    return drbg_ctr_set_ctx_params_list;
1321
262
}
1322
1323
const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
1324
    { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_ctr_new_wrapper },
1325
    { OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_ctr_free },
1326
    { OSSL_FUNC_RAND_INSTANTIATE,
1327
        (void (*)(void))drbg_ctr_instantiate_wrapper },
1328
    { OSSL_FUNC_RAND_UNINSTANTIATE,
1329
        (void (*)(void))drbg_ctr_uninstantiate_wrapper },
1330
    { OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_ctr_generate_wrapper },
1331
    { OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_ctr_reseed_wrapper },
1332
    { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },
1333
    { OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },
1334
    { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },
1335
    { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
1336
        (void (*)(void))drbg_ctr_settable_ctx_params },
1337
    { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_ctr_set_ctx_params },
1338
    { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
1339
        (void (*)(void))drbg_ctr_gettable_ctx_params },
1340
    { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_ctr_get_ctx_params },
1341
    { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
1342
        (void (*)(void))drbg_ctr_verify_zeroization },
1343
    { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },
1344
    { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },
1345
    OSSL_DISPATCH_END
1346
};