Coverage Report

Created: 2026-09-12 06:55

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