Coverage Report

Created: 2025-12-31 06:58

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
345k
{
72
345k
    unsigned char *p = &ctr->V[0];
73
345k
    u32 n = 16, c = 1;
74
75
5.52M
    do {
76
5.52M
        --n;
77
5.52M
        c += p[n];
78
5.52M
        p[n] = (u8)c;
79
5.52M
        c >>= 8;
80
5.52M
    } while (n);
81
345k
}
82
83
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
84
71.6k
{
85
71.6k
    size_t i, n;
86
87
71.6k
    if (in == NULL || inlen == 0)
88
71.4k
        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
174
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
95
174
    if (!ossl_assert(n <= sizeof(ctr->K)))
96
0
        return;
97
5.73k
    for (i = 0; i < n; i++)
98
5.56k
        ctr->K[i] ^= in[i];
99
174
    if (inlen <= ctr->keylen)
100
1
        return;
101
102
173
    n = inlen - ctr->keylen;
103
173
    if (n > 16) {
104
        /* Should never happen */
105
0
        n = 16;
106
0
    }
107
2.94k
    for (i = 0; i < n; i++)
108
2.76k
        ctr->V[i] ^= in[i + ctr->keylen];
109
173
}
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
550
{
117
550
    int i, outlen = AES_BLOCK_SIZE;
118
119
26.9k
    for (i = 0; i < len; i++)
120
26.4k
        out[i] ^= in[i];
121
122
550
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
123
550
        || outlen != len)
124
0
        return 0;
125
550
    return 1;
126
550
}
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
431
{
133
431
    unsigned char in_tmp[48];
134
431
    unsigned char num_of_blk = 2;
135
136
431
    memcpy(in_tmp, in, 16);
137
431
    memcpy(in_tmp + 16, in, 16);
138
431
    if (ctr->keylen != 16) {
139
431
        memcpy(in_tmp + 32, in, 16);
140
431
        num_of_blk = 3;
141
431
    }
142
431
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
143
431
}
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
119
{
151
119
    unsigned char bltmp[48] = { 0 };
152
119
    unsigned char num_of_blk;
153
154
119
    memset(ctr->KX, 0, 48);
155
119
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
156
119
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
157
119
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
158
119
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
159
119
}
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
476
{
167
476
    if (in == NULL || inlen == 0)
168
196
        return 1;
169
170
    /* If we have partial block handle it first */
171
280
    if (ctr->bltmp_pos) {
172
228
        size_t left = 16 - ctr->bltmp_pos;
173
174
        /* If we now have a complete block process it */
175
228
        if (inlen >= left) {
176
161
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
177
161
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
178
0
                return 0;
179
161
            ctr->bltmp_pos = 0;
180
161
            inlen -= left;
181
161
            in += left;
182
161
        }
183
228
    }
184
185
    /* Process zero or more complete blocks */
186
431
    for (; inlen >= 16; in += 16, inlen -= 16) {
187
151
        if (!ctr_BCC_blocks(ctr, in))
188
0
            return 0;
189
151
    }
190
191
    /* Copy any remaining partial block to the temporary buffer */
192
280
    if (inlen > 0) {
193
228
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
194
228
        ctr->bltmp_pos += inlen;
195
228
    }
196
280
    return 1;
197
280
}
198
199
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
200
119
{
201
119
    if (ctr->bltmp_pos) {
202
119
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
203
119
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
204
0
            return 0;
205
119
    }
206
119
    return 1;
207
119
}
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
119
{
214
119
    static unsigned char c80 = 0x80;
215
119
    size_t inlen;
216
119
    unsigned char *p = ctr->bltmp;
217
119
    int outlen = AES_BLOCK_SIZE;
218
219
119
    if (!ctr_BCC_init(ctr))
220
0
        return 0;
221
119
    if (in1 == NULL)
222
0
        in1len = 0;
223
119
    if (in2 == NULL)
224
119
        in2len = 0;
225
119
    if (in3 == NULL)
226
77
        in3len = 0;
227
119
    inlen = in1len + in2len + in3len;
228
    /* Initialise L||N in temporary block */
229
119
    *p++ = (inlen >> 24) & 0xff;
230
119
    *p++ = (inlen >> 16) & 0xff;
231
119
    *p++ = (inlen >> 8) & 0xff;
232
119
    *p++ = inlen & 0xff;
233
234
    /* NB keylen is at most 32 bytes */
235
119
    *p++ = 0;
236
119
    *p++ = 0;
237
119
    *p++ = 0;
238
119
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
239
119
    ctr->bltmp_pos = 8;
240
119
    if (!ctr_BCC_update(ctr, in1, in1len)
241
119
        || !ctr_BCC_update(ctr, in2, in2len)
242
119
        || !ctr_BCC_update(ctr, in3, in3len)
243
119
        || !ctr_BCC_update(ctr, &c80, 1)
244
119
        || !ctr_BCC_final(ctr))
245
0
        return 0;
246
    /* Set up key K */
247
119
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
248
0
        return 0;
249
    /* X follows key K */
250
119
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
251
119
            AES_BLOCK_SIZE)
252
119
        || outlen != AES_BLOCK_SIZE)
253
0
        return 0;
254
119
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
255
119
            AES_BLOCK_SIZE)
256
119
        || outlen != AES_BLOCK_SIZE)
257
0
        return 0;
258
119
    if (ctr->keylen != 16)
259
119
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
260
119
                ctr->KX + 16, AES_BLOCK_SIZE)
261
119
            || outlen != AES_BLOCK_SIZE)
262
0
            return 0;
263
119
    return 1;
264
119
}
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
115k
{
277
115k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
278
115k
    int outlen = AES_BLOCK_SIZE;
279
115k
    unsigned char V_tmp[48], out[48];
280
115k
    unsigned char len;
281
282
    /* correct key is already set up. */
283
115k
    memcpy(V_tmp, ctr->V, 16);
284
115k
    inc_128(ctr);
285
115k
    memcpy(V_tmp + 16, ctr->V, 16);
286
115k
    if (ctr->keylen == 16) {
287
0
        len = 32;
288
115k
    } else {
289
115k
        inc_128(ctr);
290
115k
        memcpy(V_tmp + 32, ctr->V, 16);
291
115k
        len = 48;
292
115k
    }
293
115k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
294
115k
        || outlen != len)
295
0
        return 0;
296
115k
    memcpy(ctr->K, out, ctr->keylen);
297
115k
    memcpy(ctr->V, out + ctr->keylen, 16);
298
299
115k
    if (ctr->use_df) {
300
        /* If no input reuse existing derived value */
301
79.2k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
302
119
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
303
0
                return 0;
304
        /* If this a reuse input in1len != 0 */
305
79.2k
        if (in1len)
306
171
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
307
79.2k
    } else {
308
35.7k
        ctr_XOR(ctr, in1, in1len);
309
35.7k
        ctr_XOR(ctr, in2, in2len);
310
35.7k
    }
311
312
115k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
313
115k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
314
0
        return 0;
315
115k
    return 1;
316
115k
}
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
43
{
323
43
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
324
325
43
    if (entropy == NULL)
326
0
        return 0;
327
328
43
    memset(ctr->K, 0, sizeof(ctr->K));
329
43
    memset(ctr->V, 0, sizeof(ctr->V));
330
43
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
331
0
        return 0;
332
333
43
    inc_128(ctr);
334
43
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
335
0
        return 0;
336
43
    return 1;
337
43
}
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
24
{
345
24
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
346
24
    struct drbg_set_ctx_params_st p;
347
24
    int ret = 0;
348
349
24
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
350
0
        return 0;
351
352
24
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
353
0
        return 0;
354
355
24
    if (!ossl_prov_is_running()
356
24
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
357
0
        goto err;
358
24
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
359
24
        pstr, pstr_len);
360
24
err:
361
24
    if (drbg->lock != NULL)
362
0
        CRYPTO_THREAD_unlock(drbg->lock);
363
24
    return ret;
364
24
}
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
26
{
370
26
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
371
372
26
    if (entropy == NULL)
373
0
        return 0;
374
375
26
    inc_128(ctr);
376
26
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
377
0
        return 0;
378
26
    return 1;
379
26
}
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
114k
{
407
114k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
408
114k
    unsigned int ctr32, blocks;
409
114k
    int outl, buflen;
410
411
114k
    if (adin != NULL && adinlen != 0) {
412
52
        inc_128(ctr);
413
414
52
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
415
0
            return 0;
416
        /* This means we reuse derived value */
417
52
        if (ctr->use_df) {
418
52
            adin = NULL;
419
52
            adinlen = 1;
420
52
        }
421
114k
    } else {
422
114k
        adinlen = 0;
423
114k
    }
424
425
114k
    inc_128(ctr);
426
427
114k
    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
114k
    memset(out, 0, outlen);
436
437
114k
    do {
438
114k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
439
114k
                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
114k
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
450
114k
        blocks = (buflen + 15) / 16;
451
452
114k
        ctr32 = GETU32(ctr->V + 12) + blocks;
453
114k
        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
114k
        PUTU32(ctr->V + 12, ctr32);
463
464
114k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
465
114k
            || outl != buflen)
466
0
            return 0;
467
468
114k
        out += buflen;
469
114k
        outlen -= buflen;
470
114k
    } while (outlen);
471
472
114k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
473
0
        return 0;
474
114k
    return 1;
475
114k
}
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
114k
{
481
114k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482
483
114k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
484
114k
        prediction_resistance, adin, adin_len);
485
114k
}
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
206
{
540
206
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
541
206
    int res = 1;
542
543
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
544
206
    drbg->max_request = 1 << 16;
545
206
    if (ctr->use_df) {
546
205
        drbg->min_entropylen = 0;
547
205
        drbg->max_entropylen = DRBG_MAX_LENGTH;
548
205
        drbg->min_noncelen = 0;
549
205
        drbg->max_noncelen = DRBG_MAX_LENGTH;
550
205
        drbg->max_perslen = DRBG_MAX_LENGTH;
551
205
        drbg->max_adinlen = DRBG_MAX_LENGTH;
552
553
205
        if (ctr->keylen > 0) {
554
42
            drbg->min_entropylen = ctr->keylen;
555
42
            drbg->min_noncelen = drbg->min_entropylen / 2;
556
42
        }
557
205
    } 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
206
    return res;
569
206
}
570
571
static int drbg_ctr_init(PROV_DRBG *drbg)
572
43
{
573
43
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
574
43
    size_t keylen;
575
576
43
    if (ctr->cipher_ctr == NULL) {
577
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
578
0
        return 0;
579
0
    }
580
43
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
581
43
    if (ctr->ctx_ecb == NULL)
582
43
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
583
43
    if (ctr->ctx_ctr == NULL)
584
43
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
585
43
    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
43
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
591
43
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
592
43
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
593
43
            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
43
    drbg->strength = (unsigned int)(keylen * 8);
599
43
    drbg->seedlen = keylen + 16;
600
601
43
    if (ctr->use_df) {
602
        /* df initialisation */
603
42
        static const unsigned char df_key[32] = {
604
42
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
605
42
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
606
42
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
607
42
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
608
42
        };
609
610
42
        if (ctr->ctx_df == NULL)
611
42
            ctr->ctx_df = EVP_CIPHER_CTX_new();
612
42
        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
42
        if (!EVP_CipherInit_ex(ctr->ctx_df,
618
42
                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
42
    }
623
43
    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
43
}
631
632
static int drbg_ctr_new(PROV_DRBG *drbg)
633
163
{
634
163
    PROV_DRBG_CTR *ctr;
635
636
163
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
637
163
    if (ctr == NULL)
638
0
        return 0;
639
640
163
    ctr->use_df = 1;
641
163
    drbg->data = ctr;
642
163
    OSSL_FIPS_IND_INIT(drbg)
643
163
    return drbg_ctr_init_lengths(drbg);
644
163
}
645
646
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
647
    const OSSL_DISPATCH *parent_dispatch)
648
163
{
649
163
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
650
163
        &drbg_ctr_new, &drbg_ctr_free,
651
163
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
652
163
        &drbg_ctr_reseed, &drbg_ctr_generate);
653
163
}
654
655
static void drbg_ctr_free(void *vdrbg)
656
149
{
657
149
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
658
149
    PROV_DRBG_CTR *ctr;
659
660
149
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
661
149
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
662
149
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
663
149
        EVP_CIPHER_CTX_free(ctr->ctx_df);
664
149
        EVP_CIPHER_free(ctr->cipher_ecb);
665
149
        EVP_CIPHER_free(ctr->cipher_ctr);
666
667
149
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
668
149
    }
669
149
    ossl_rand_drbg_free(drbg);
670
149
}
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
83.8k
{
727
83.8k
    const char *s;
728
729
83.8k
    memset(r, 0, sizeof(*r));
730
83.8k
    if (p != NULL)
731
167k
        for (; (s = p->key) != NULL; p++)
732
83.8k
            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
41.9k
            case 'm':
760
41.9k
                switch(s[1]) {
761
0
                default:
762
0
                    break;
763
41.9k
                case 'a':
764
41.9k
                    switch(s[2]) {
765
0
                    default:
766
0
                        break;
767
41.9k
                    case 'x':
768
41.9k
                        switch(s[3]) {
769
0
                        default:
770
0
                            break;
771
41.9k
                        case '_':
772
41.9k
                            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
41.9k
                            case 'r':
820
41.9k
                                if (ossl_likely(strcmp("equest", s + 5) == 0)) {
821
                                    /* OSSL_RAND_PARAM_MAX_REQUEST */
822
41.9k
                                    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
41.9k
                                    r->maxreq = (OSSL_PARAM *)p;
828
41.9k
                                }
829
41.9k
                            }
830
41.9k
                        }
831
41.9k
                    }
832
41.9k
                    break;
833
41.9k
                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
41.9k
                }
870
41.9k
                break;
871
41.9k
            case 'r':
872
41.9k
                switch(s[1]) {
873
0
                default:
874
0
                    break;
875
41.9k
                case 'e':
876
41.9k
                    switch(s[2]) {
877
0
                    default:
878
0
                        break;
879
41.9k
                    case 's':
880
41.9k
                        switch(s[3]) {
881
0
                        default:
882
0
                            break;
883
41.9k
                        case 'e':
884
41.9k
                            switch(s[4]) {
885
0
                            default:
886
0
                                break;
887
41.9k
                            case 'e':
888
41.9k
                                switch(s[5]) {
889
0
                                default:
890
0
                                    break;
891
41.9k
                                case 'd':
892
41.9k
                                    switch(s[6]) {
893
0
                                    default:
894
0
                                        break;
895
41.9k
                                    case '_':
896
41.9k
                                        switch(s[7]) {
897
0
                                        default:
898
0
                                            break;
899
41.9k
                                        case 'c':
900
41.9k
                                            if (ossl_likely(strcmp("ounter", s + 8) == 0)) {
901
                                                /* OSSL_DRBG_PARAM_RESEED_COUNTER */
902
41.9k
                                                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
41.9k
                                                r->reseed_cnt = (OSSL_PARAM *)p;
908
41.9k
                                            }
909
41.9k
                                            break;
910
41.9k
                                        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
41.9k
                                        }
960
41.9k
                                    }
961
41.9k
                                }
962
41.9k
                            }
963
41.9k
                        }
964
41.9k
                    }
965
41.9k
                }
966
41.9k
                break;
967
41.9k
            case 's':
968
45
                switch(s[1]) {
969
0
                default:
970
0
                    break;
971
45
                case 't':
972
45
                    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
45
                    case 'r':
987
45
                        if (ossl_likely(strcmp("ength", s + 3) == 0)) {
988
                            /* OSSL_RAND_PARAM_STRENGTH */
989
45
                            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
45
                            r->str = (OSSL_PARAM *)p;
995
45
                        }
996
45
                    }
997
45
                }
998
45
                break;
999
45
            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
83.8k
            }
1010
83.8k
    return 1;
1011
83.8k
}
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
83.8k
{
1018
83.8k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
1019
83.8k
    PROV_DRBG_CTR *ctr;
1020
83.8k
    struct drbg_ctr_get_ctx_params_st p;
1021
83.8k
    int ret = 0, complete = 0;
1022
1023
83.8k
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
1024
0
        return 0;
1025
1026
83.8k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
1027
0
        return 0;
1028
1029
83.8k
    if (complete)
1030
83.8k
        return 1;
1031
1032
45
    ctr = (PROV_DRBG_CTR *)drbg->data;
1033
1034
45
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
1035
0
        return 0;
1036
1037
45
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
1038
0
        goto err;
1039
1040
45
    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
45
    ret = ossl_drbg_get_ctx_params(drbg, &p);
1048
45
err:
1049
45
    if (drbg->lock != NULL)
1050
45
        CRYPTO_THREAD_unlock(drbg->lock);
1051
1052
45
    return ret;
1053
45
}
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
124
{
1064
124
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
1065
124
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
1066
124
    OSSL_PROVIDER *prov = NULL;
1067
124
    char *ecb;
1068
124
    const char *propquery = NULL;
1069
124
    int i, cipher_init = 0;
1070
1071
124
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
1072
        /* FIPS errors out in the drbg_ctr_init() call later */
1073
124
        ctr->use_df = i != 0;
1074
124
        cipher_init = 1;
1075
124
    }
1076
1077
124
    if (p->propq != NULL) {
1078
89
        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
1079
0
            return 0;
1080
89
        propquery = (const char *)p->propq->data;
1081
89
    }
1082
1083
124
    if (p->prov != NULL) {
1084
85
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
1085
0
            return 0;
1086
85
        if ((prov = ossl_provider_find(libctx,
1087
85
                 (const char *)p->prov->data, 1))
1088
85
            == NULL)
1089
43
            return 0;
1090
85
    }
1091
1092
81
    if (p->cipher != NULL) {
1093
81
        const char *base = (const char *)p->cipher->data;
1094
81
        size_t ctr_str_len = sizeof("CTR") - 1;
1095
81
        size_t ecb_str_len = sizeof("ECB") - 1;
1096
1097
81
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
1098
81
            || p->cipher->data_size < ctr_str_len) {
1099
17
            ossl_provider_free(prov);
1100
17
            return 0;
1101
17
        }
1102
64
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
1103
29
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
1104
29
            ossl_provider_free(prov);
1105
29
            return 0;
1106
29
        }
1107
35
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
1108
0
            ossl_provider_free(prov);
1109
0
            return 0;
1110
0
        }
1111
35
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
1112
35
        EVP_CIPHER_free(ctr->cipher_ecb);
1113
35
        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
35
        (void)ERR_set_mark();
1119
35
        ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
1120
35
        if (ctr->cipher_ctr == NULL) {
1121
0
            (void)ERR_pop_to_mark();
1122
0
            ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
1123
35
        } else {
1124
35
            (void)ERR_clear_last_mark();
1125
35
        }
1126
35
        (void)ERR_set_mark();
1127
35
        ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
1128
35
        if (ctr->cipher_ecb == NULL) {
1129
0
            (void)ERR_pop_to_mark();
1130
0
            ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
1131
35
        } else {
1132
35
            (void)ERR_clear_last_mark();
1133
35
        }
1134
35
        OPENSSL_free(ecb);
1135
35
        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
35
        cipher_init = 1;
1141
35
    }
1142
35
    ossl_provider_free(prov);
1143
1144
35
    if (cipher_init && !drbg_ctr_init(ctx))
1145
0
        return 0;
1146
1147
35
    return ossl_drbg_set_ctx_params(ctx, p);
1148
35
}
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
74
{
1181
74
    const char *s;
1182
1183
74
    memset(r, 0, sizeof(*r));
1184
74
    if (p != NULL)
1185
494
        for (; (s = p->key) != NULL; p++)
1186
420
            switch(s[0]) {
1187
0
            default:
1188
0
                break;
1189
74
            case 'c':
1190
74
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
1191
                    /* OSSL_DRBG_PARAM_CIPHER */
1192
74
                    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
74
                    r->cipher = (OSSL_PARAM *)p;
1198
74
                }
1199
74
                break;
1200
124
            case 'p':
1201
124
                switch(s[1]) {
1202
0
                default:
1203
0
                    break;
1204
124
                case 'r':
1205
124
                    switch(s[2]) {
1206
0
                    default:
1207
0
                        break;
1208
124
                    case 'o':
1209
124
                        switch(s[3]) {
1210
0
                        default:
1211
0
                            break;
1212
50
                        case 'p':
1213
50
                            if (ossl_likely(strcmp("erties", s + 4) == 0)) {
1214
                                /* OSSL_DRBG_PARAM_PROPERTIES */
1215
50
                                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
50
                                r->propq = (OSSL_PARAM *)p;
1221
50
                            }
1222
50
                            break;
1223
74
                        case 'v':
1224
74
                            if (ossl_likely(strcmp("ider-name", s + 4) == 0)) {
1225
                                /* OSSL_PROV_PARAM_CORE_PROV_NAME */
1226
74
                                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
74
                                r->prov = (OSSL_PARAM *)p;
1232
74
                            }
1233
124
                        }
1234
124
                    }
1235
124
                }
1236
124
                break;
1237
148
            case 'r':
1238
148
                switch(s[1]) {
1239
0
                default:
1240
0
                    break;
1241
148
                case 'e':
1242
148
                    switch(s[2]) {
1243
0
                    default:
1244
0
                        break;
1245
148
                    case 's':
1246
148
                        switch(s[3]) {
1247
0
                        default:
1248
0
                            break;
1249
148
                        case 'e':
1250
148
                            switch(s[4]) {
1251
0
                            default:
1252
0
                                break;
1253
148
                            case 'e':
1254
148
                                switch(s[5]) {
1255
0
                                default:
1256
0
                                    break;
1257
148
                                case 'd':
1258
148
                                    switch(s[6]) {
1259
0
                                    default:
1260
0
                                        break;
1261
148
                                    case '_':
1262
148
                                        switch(s[7]) {
1263
0
                                        default:
1264
0
                                            break;
1265
74
                                        case 'r':
1266
74
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
1267
                                                /* OSSL_DRBG_PARAM_RESEED_REQUESTS */
1268
74
                                                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
74
                                                r->reseed_req = (OSSL_PARAM *)p;
1274
74
                                            }
1275
74
                                            break;
1276
74
                                        case 't':
1277
74
                                            if (ossl_likely(strcmp("ime_interval", s + 8) == 0)) {
1278
                                                /* OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL */
1279
74
                                                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
74
                                                r->reseed_time = (OSSL_PARAM *)p;
1285
74
                                            }
1286
148
                                        }
1287
148
                                    }
1288
148
                                }
1289
148
                            }
1290
148
                        }
1291
148
                    }
1292
148
                }
1293
148
                break;
1294
148
            case 'u':
1295
74
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1296
                    /* OSSL_DRBG_PARAM_USE_DF */
1297
74
                    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
74
                    r->df = (OSSL_PARAM *)p;
1303
74
                }
1304
420
            }
1305
74
    return 1;
1306
74
}
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
50
{
1313
50
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
1314
50
    struct drbg_set_ctx_params_st p;
1315
50
    int ret;
1316
1317
50
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
1318
0
        return 0;
1319
1320
50
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
1321
0
        return 0;
1322
1323
50
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
1324
1325
50
    if (drbg->lock != NULL)
1326
0
        CRYPTO_THREAD_unlock(drbg->lock);
1327
1328
50
    return ret;
1329
50
}
1330
1331
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
1332
    ossl_unused void *provctx)
1333
161
{
1334
161
    return drbg_ctr_set_ctx_params_list;
1335
161
}
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
};