Coverage Report

Created: 2026-02-14 07:20

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