Coverage Report

Created: 2026-07-23 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/rands/drbg_ctr.c
Line
Count
Source
1
/*
2
 * Copyright 2011-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
501k
{
72
501k
    unsigned char *p = &ctr->V[0];
73
501k
    u32 n = 16, c = 1;
74
75
8.02M
    do {
76
8.02M
        --n;
77
8.02M
        c += p[n];
78
8.02M
        p[n] = (u8)c;
79
8.02M
        c >>= 8;
80
8.02M
    } while (n);
81
501k
}
82
83
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
84
77.0k
{
85
77.0k
    size_t i, n;
86
87
77.0k
    if (in == NULL || inlen == 0)
88
76.8k
        return;
89
90
    /*
91
     * Any zero padding will have no effect on the result as we
92
     * are XORing. So just process however much input we have.
93
     */
94
181
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
95
181
    if (!ossl_assert(n <= sizeof(ctr->K)))
96
0
        return;
97
5.97k
    for (i = 0; i < n; i++)
98
5.78k
        ctr->K[i] ^= in[i];
99
181
    if (inlen <= ctr->keylen)
100
1
        return;
101
102
180
    n = inlen - ctr->keylen;
103
180
    if (n > 16) {
104
        /* Should never happen */
105
0
        n = 16;
106
0
    }
107
3.06k
    for (i = 0; i < n; i++)
108
2.88k
        ctr->V[i] ^= in[i + ctr->keylen];
109
180
}
110
111
/*
112
 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
113
 */
114
__owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out,
115
    const unsigned char *in, int len)
116
574
{
117
574
    int i, outlen = AES_BLOCK_SIZE;
118
119
28.1k
    for (i = 0; i < len; i++)
120
27.5k
        out[i] ^= in[i];
121
122
574
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
123
574
        || outlen != len)
124
0
        return 0;
125
574
    return 1;
126
574
}
127
128
/*
129
 * Handle several BCC operations for as much data as we need for K and X
130
 */
131
__owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
132
450
{
133
450
    unsigned char in_tmp[48];
134
450
    unsigned char num_of_blk = 2;
135
136
450
    memcpy(in_tmp, in, 16);
137
450
    memcpy(in_tmp + 16, in, 16);
138
450
    if (ctr->keylen != 16) {
139
450
        memcpy(in_tmp + 32, in, 16);
140
450
        num_of_blk = 3;
141
450
    }
142
450
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
143
450
}
144
145
/*
146
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
147
 * see 10.3.1 stage 7.
148
 */
149
__owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
150
124
{
151
124
    unsigned char bltmp[48] = { 0 };
152
124
    unsigned char num_of_blk;
153
154
124
    memset(ctr->KX, 0, 48);
155
124
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
156
124
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
157
124
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
158
124
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
159
124
}
160
161
/*
162
 * Process several blocks into BCC algorithm, some possibly partial
163
 */
164
__owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
165
    const unsigned char *in, size_t inlen)
166
496
{
167
496
    if (in == NULL || inlen == 0)
168
204
        return 1;
169
170
    /* If we have partial block handle it first */
171
292
    if (ctr->bltmp_pos) {
172
238
        size_t left = 16 - ctr->bltmp_pos;
173
174
        /* If we now have a complete block process it */
175
238
        if (inlen >= left) {
176
168
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
177
168
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
178
0
                return 0;
179
168
            ctr->bltmp_pos = 0;
180
168
            inlen -= left;
181
168
            in += left;
182
168
        }
183
238
    }
184
185
    /* Process zero or more complete blocks */
186
450
    for (; inlen >= 16; in += 16, inlen -= 16) {
187
158
        if (!ctr_BCC_blocks(ctr, in))
188
0
            return 0;
189
158
    }
190
191
    /* Copy any remaining partial block to the temporary buffer */
192
292
    if (inlen > 0) {
193
238
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
194
238
        ctr->bltmp_pos += inlen;
195
238
    }
196
292
    return 1;
197
292
}
198
199
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
200
124
{
201
124
    if (ctr->bltmp_pos) {
202
124
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
203
124
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
204
0
            return 0;
205
124
    }
206
124
    return 1;
207
124
}
208
209
__owur static int ctr_df(PROV_DRBG_CTR *ctr,
210
    const unsigned char *in1, size_t in1len,
211
    const unsigned char *in2, size_t in2len,
212
    const unsigned char *in3, size_t in3len)
213
124
{
214
124
    static unsigned char c80 = 0x80;
215
124
    size_t inlen;
216
124
    unsigned char *p = ctr->bltmp;
217
124
    int outlen = AES_BLOCK_SIZE;
218
219
124
    if (!ctr_BCC_init(ctr))
220
0
        return 0;
221
124
    if (in1 == NULL)
222
0
        in1len = 0;
223
124
    if (in2 == NULL)
224
124
        in2len = 0;
225
124
    if (in3 == NULL)
226
80
        in3len = 0;
227
124
    inlen = in1len + in2len + in3len;
228
    /* Initialise L||N in temporary block */
229
124
    *p++ = (inlen >> 24) & 0xff;
230
124
    *p++ = (inlen >> 16) & 0xff;
231
124
    *p++ = (inlen >> 8) & 0xff;
232
124
    *p++ = inlen & 0xff;
233
234
    /* NB keylen is at most 32 bytes */
235
124
    *p++ = 0;
236
124
    *p++ = 0;
237
124
    *p++ = 0;
238
124
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
239
124
    ctr->bltmp_pos = 8;
240
124
    if (!ctr_BCC_update(ctr, in1, in1len)
241
124
        || !ctr_BCC_update(ctr, in2, in2len)
242
124
        || !ctr_BCC_update(ctr, in3, in3len)
243
124
        || !ctr_BCC_update(ctr, &c80, 1)
244
124
        || !ctr_BCC_final(ctr))
245
0
        return 0;
246
    /* Set up key K */
247
124
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
248
0
        return 0;
249
    /* X follows key K */
250
124
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
251
124
            AES_BLOCK_SIZE)
252
124
        || outlen != AES_BLOCK_SIZE)
253
0
        return 0;
254
124
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
255
124
            AES_BLOCK_SIZE)
256
124
        || outlen != AES_BLOCK_SIZE)
257
0
        return 0;
258
124
    if (ctr->keylen != 16)
259
124
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
260
124
                ctr->KX + 16, AES_BLOCK_SIZE)
261
124
            || outlen != AES_BLOCK_SIZE)
262
0
            return 0;
263
124
    return 1;
264
124
}
265
266
/*
267
 * NB the no-df Update in SP800-90A specifies a constant input length
268
 * of seedlen, however other uses of this algorithm pad the input with
269
 * zeroes if necessary and have up to two parameters XORed together,
270
 * so we handle both cases in this function instead.
271
 */
272
__owur static int ctr_update(PROV_DRBG *drbg,
273
    const unsigned char *in1, size_t in1len,
274
    const unsigned char *in2, size_t in2len,
275
    const unsigned char *nonce, size_t noncelen)
276
167k
{
277
167k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
278
167k
    int outlen = AES_BLOCK_SIZE;
279
167k
    unsigned char V_tmp[48], out[48];
280
167k
    unsigned char len;
281
282
    /* correct key is already set up. */
283
167k
    memcpy(V_tmp, ctr->V, 16);
284
167k
    inc_128(ctr);
285
167k
    memcpy(V_tmp + 16, ctr->V, 16);
286
167k
    if (ctr->keylen == 16) {
287
0
        len = 32;
288
167k
    } else {
289
167k
        inc_128(ctr);
290
167k
        memcpy(V_tmp + 32, ctr->V, 16);
291
167k
        len = 48;
292
167k
    }
293
167k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
294
167k
        || outlen != len)
295
0
        return 0;
296
167k
    memcpy(ctr->K, out, ctr->keylen);
297
167k
    memcpy(ctr->V, out + ctr->keylen, 16);
298
299
167k
    if (ctr->use_df) {
300
        /* If no input reuse existing derived value */
301
128k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
302
124
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
303
0
                return 0;
304
        /* If this a reuse input in1len != 0 */
305
128k
        if (in1len)
306
178
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
307
128k
    } else {
308
38.4k
        ctr_XOR(ctr, in1, in1len);
309
38.4k
        ctr_XOR(ctr, in2, in2len);
310
38.4k
    }
311
312
167k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
313
167k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
314
0
        return 0;
315
167k
    return 1;
316
167k
}
317
318
static int drbg_ctr_instantiate(PROV_DRBG *drbg,
319
    const unsigned char *entropy, size_t entropylen,
320
    const unsigned char *nonce, size_t noncelen,
321
    const unsigned char *pers, size_t perslen)
322
45
{
323
45
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
324
325
45
    if (entropy == NULL)
326
0
        return 0;
327
328
45
    memset(ctr->K, 0, sizeof(ctr->K));
329
45
    memset(ctr->V, 0, sizeof(ctr->V));
330
45
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
331
0
        return 0;
332
333
45
    inc_128(ctr);
334
45
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
335
0
        return 0;
336
45
    return 1;
337
45
}
338
339
static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
340
    int prediction_resistance,
341
    const unsigned char *pstr,
342
    size_t pstr_len,
343
    const OSSL_PARAM params[])
344
26
{
345
26
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
346
26
    struct drbg_set_ctx_params_st p;
347
26
    int ret = 0;
348
349
26
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
350
0
        return 0;
351
352
26
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
353
0
        return 0;
354
355
26
    if (!ossl_prov_is_running()
356
26
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
357
0
        goto err;
358
26
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
359
26
        pstr, pstr_len);
360
26
err:
361
26
    if (drbg->lock != NULL)
362
0
        CRYPTO_THREAD_unlock(drbg->lock);
363
26
    return ret;
364
26
}
365
366
static int drbg_ctr_reseed(PROV_DRBG *drbg,
367
    const unsigned char *entropy, size_t entropylen,
368
    const unsigned char *adin, size_t adinlen)
369
27
{
370
27
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
371
372
27
    if (entropy == NULL)
373
0
        return 0;
374
375
27
    inc_128(ctr);
376
27
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
377
0
        return 0;
378
27
    return 1;
379
27
}
380
381
static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
382
    const unsigned char *ent, size_t ent_len,
383
    const unsigned char *adin, size_t adin_len)
384
0
{
385
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
386
387
0
    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
388
0
        adin, adin_len);
389
0
}
390
391
static void ctr96_inc(unsigned char *counter)
392
0
{
393
0
    u32 n = 12, c = 1;
394
395
0
    do {
396
0
        --n;
397
0
        c += counter[n];
398
0
        counter[n] = (u8)c;
399
0
        c >>= 8;
400
0
    } while (n);
401
0
}
402
403
static int drbg_ctr_generate(PROV_DRBG *drbg,
404
    unsigned char *out, size_t outlen,
405
    const unsigned char *adin, size_t adinlen)
406
167k
{
407
167k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
408
167k
    unsigned int ctr32, blocks;
409
167k
    int outl, buflen;
410
411
167k
    if (adin != NULL && adinlen != 0) {
412
54
        inc_128(ctr);
413
414
54
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
415
0
            return 0;
416
        /* This means we reuse derived value */
417
54
        if (ctr->use_df) {
418
54
            adin = NULL;
419
54
            adinlen = 1;
420
54
        }
421
167k
    } else {
422
167k
        adinlen = 0;
423
167k
    }
424
425
167k
    inc_128(ctr);
426
427
167k
    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
167k
    memset(out, 0, outlen);
436
437
167k
    do {
438
167k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
439
167k
                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
167k
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
450
167k
        blocks = (buflen + 15) / 16;
451
452
167k
        ctr32 = GETU32(ctr->V + 12) + blocks;
453
167k
        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
167k
        PUTU32(ctr->V + 12, ctr32);
463
464
167k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
465
167k
            || outl != buflen)
466
0
            return 0;
467
468
167k
        out += buflen;
469
167k
        outlen -= buflen;
470
167k
    } while (outlen);
471
472
167k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
473
0
        return 0;
474
167k
    return 1;
475
167k
}
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
167k
{
481
167k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482
483
167k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
484
167k
        prediction_resistance, adin, adin_len);
485
167k
}
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
197
{
540
197
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
541
197
    int res = 1;
542
543
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
544
197
    drbg->max_request = 1 << 16;
545
197
    if (ctr->use_df) {
546
196
        drbg->min_entropylen = 0;
547
196
        drbg->max_entropylen = DRBG_MAX_LENGTH;
548
196
        drbg->min_noncelen = 0;
549
196
        drbg->max_noncelen = DRBG_MAX_LENGTH;
550
196
        drbg->max_perslen = DRBG_MAX_LENGTH;
551
196
        drbg->max_adinlen = DRBG_MAX_LENGTH;
552
553
196
        if (ctr->keylen > 0) {
554
44
            drbg->min_entropylen = ctr->keylen;
555
44
            drbg->min_noncelen = drbg->min_entropylen / 2;
556
44
        }
557
196
    } 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
197
    return res;
569
197
}
570
571
static int drbg_ctr_init(PROV_DRBG *drbg)
572
45
{
573
45
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
574
45
    size_t keylen;
575
576
45
    if (ctr->cipher_ctr == NULL) {
577
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
578
0
        return 0;
579
0
    }
580
45
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
581
45
    if (ctr->ctx_ecb == NULL)
582
45
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
583
45
    if (ctr->ctx_ctr == NULL)
584
45
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
585
45
    if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
586
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
587
0
        goto err;
588
0
    }
589
590
45
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
591
45
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
592
45
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
593
45
            ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
594
0
        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
595
0
        goto err;
596
0
    }
597
598
45
    drbg->strength = (unsigned int)(keylen * 8);
599
45
    drbg->seedlen = keylen + 16;
600
601
45
    if (ctr->use_df) {
602
        /* df initialisation */
603
44
        static const unsigned char df_key[32] = {
604
44
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
605
44
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
606
44
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
607
44
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
608
44
        };
609
610
44
        if (ctr->ctx_df == NULL)
611
44
            ctr->ctx_df = EVP_CIPHER_CTX_new();
612
44
        if (ctr->ctx_df == NULL) {
613
0
            ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
614
0
            goto err;
615
0
        }
616
        /* Set key schedule for df_key */
617
44
        if (!EVP_CipherInit_ex(ctr->ctx_df,
618
44
                ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
619
0
            ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
620
0
            goto err;
621
0
        }
622
44
    }
623
45
    return drbg_ctr_init_lengths(drbg);
624
625
0
err:
626
0
    EVP_CIPHER_CTX_free(ctr->ctx_ecb);
627
0
    EVP_CIPHER_CTX_free(ctr->ctx_ctr);
628
0
    ctr->ctx_ecb = ctr->ctx_ctr = NULL;
629
0
    return 0;
630
45
}
631
632
static int drbg_ctr_new(PROV_DRBG *drbg)
633
152
{
634
152
    PROV_DRBG_CTR *ctr;
635
636
152
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
637
152
    if (ctr == NULL)
638
0
        return 0;
639
640
152
    ctr->use_df = 1;
641
152
    drbg->data = ctr;
642
152
    OSSL_FIPS_IND_INIT(drbg)
643
152
    return drbg_ctr_init_lengths(drbg);
644
152
}
645
646
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
647
    const OSSL_DISPATCH *parent_dispatch)
648
152
{
649
152
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
650
152
        &drbg_ctr_new, &drbg_ctr_free,
651
152
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
652
152
        &drbg_ctr_reseed, &drbg_ctr_generate);
653
152
}
654
655
static void drbg_ctr_free(void *vdrbg)
656
136
{
657
136
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
658
136
    PROV_DRBG_CTR *ctr;
659
660
136
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
661
136
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
662
136
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
663
136
        EVP_CIPHER_CTX_free(ctr->ctx_df);
664
136
        EVP_CIPHER_free(ctr->cipher_ecb);
665
136
        EVP_CIPHER_free(ctr->cipher_ctr);
666
667
136
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
668
136
    }
669
136
    ossl_rand_drbg_free(drbg);
670
136
}
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
156k
{
727
156k
    const char *s;
728
729
156k
    memset(r, 0, sizeof(*r));
730
156k
    if (p != NULL)
731
312k
        for (; (s = p->key) != NULL; p++)
732
156k
            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
78.0k
            case 'm':
760
78.0k
                switch(s[1]) {
761
0
                default:
762
0
                    break;
763
78.0k
                case 'a':
764
78.0k
                    switch(s[2]) {
765
0
                    default:
766
0
                        break;
767
78.0k
                    case 'x':
768
78.0k
                        switch(s[3]) {
769
0
                        default:
770
0
                            break;
771
78.0k
                        case '_':
772
78.0k
                            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
78.0k
                            case 'r':
820
78.0k
                                if (ossl_likely(strcmp("equest", s + 5) == 0)) {
821
                                    /* OSSL_RAND_PARAM_MAX_REQUEST */
822
78.0k
                                    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
78.0k
                                    r->maxreq = (OSSL_PARAM *)p;
828
78.0k
                                }
829
78.0k
                            }
830
78.0k
                        }
831
78.0k
                    }
832
78.0k
                    break;
833
78.0k
                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
78.0k
                }
870
78.0k
                break;
871
78.0k
            case 'r':
872
78.0k
                switch(s[1]) {
873
0
                default:
874
0
                    break;
875
78.0k
                case 'e':
876
78.0k
                    switch(s[2]) {
877
0
                    default:
878
0
                        break;
879
78.0k
                    case 's':
880
78.0k
                        switch(s[3]) {
881
0
                        default:
882
0
                            break;
883
78.0k
                        case 'e':
884
78.0k
                            switch(s[4]) {
885
0
                            default:
886
0
                                break;
887
78.0k
                            case 'e':
888
78.0k
                                switch(s[5]) {
889
0
                                default:
890
0
                                    break;
891
78.0k
                                case 'd':
892
78.0k
                                    switch(s[6]) {
893
0
                                    default:
894
0
                                        break;
895
78.0k
                                    case '_':
896
78.0k
                                        switch(s[7]) {
897
0
                                        default:
898
0
                                            break;
899
78.0k
                                        case 'c':
900
78.0k
                                            if (ossl_likely(strcmp("ounter", s + 8) == 0)) {
901
                                                /* OSSL_DRBG_PARAM_RESEED_COUNTER */
902
78.0k
                                                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
78.0k
                                                r->reseed_cnt = (OSSL_PARAM *)p;
908
78.0k
                                            }
909
78.0k
                                            break;
910
78.0k
                                        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
78.0k
                                        }
960
78.0k
                                    }
961
78.0k
                                }
962
78.0k
                            }
963
78.0k
                        }
964
78.0k
                    }
965
78.0k
                }
966
78.0k
                break;
967
78.0k
            case 's':
968
48
                switch(s[1]) {
969
0
                default:
970
0
                    break;
971
48
                case 't':
972
48
                    switch(s[2]) {
973
0
                    default:
974
0
                        break;
975
0
                    case 'a':
976
0
                        if (ossl_likely(strcmp("te", s + 3) == 0)) {
977
                            /* OSSL_RAND_PARAM_STATE */
978
0
                            if (ossl_unlikely(r->state != NULL)) {
979
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
980
0
                                               "param %s is repeated", s);
981
0
                                return 0;
982
0
                            }
983
0
                            r->state = (OSSL_PARAM *)p;
984
0
                        }
985
0
                        break;
986
48
                    case 'r':
987
48
                        if (ossl_likely(strcmp("ength", s + 3) == 0)) {
988
                            /* OSSL_RAND_PARAM_STRENGTH */
989
48
                            if (ossl_unlikely(r->str != NULL)) {
990
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
991
0
                                               "param %s is repeated", s);
992
0
                                return 0;
993
0
                            }
994
48
                            r->str = (OSSL_PARAM *)p;
995
48
                        }
996
48
                    }
997
48
                }
998
48
                break;
999
48
            case 'u':
1000
0
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1001
                    /* OSSL_DRBG_PARAM_USE_DF */
1002
0
                    if (ossl_unlikely(r->df != NULL)) {
1003
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1004
0
                                       "param %s is repeated", s);
1005
0
                        return 0;
1006
0
                    }
1007
0
                    r->df = (OSSL_PARAM *)p;
1008
0
                }
1009
156k
            }
1010
156k
    return 1;
1011
156k
}
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
156k
{
1018
156k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
1019
156k
    PROV_DRBG_CTR *ctr;
1020
156k
    struct drbg_ctr_get_ctx_params_st p;
1021
156k
    int ret = 0, complete = 0;
1022
1023
156k
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
1024
0
        return 0;
1025
1026
156k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
1027
0
        return 0;
1028
1029
156k
    if (complete)
1030
156k
        return 1;
1031
1032
48
    ctr = (PROV_DRBG_CTR *)drbg->data;
1033
1034
48
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
1035
0
        return 0;
1036
1037
48
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
1038
0
        goto err;
1039
1040
48
    if (p.cipher != NULL) {
1041
0
        if (ctr->cipher_ctr == NULL
1042
0
            || !OSSL_PARAM_set_utf8_string(p.cipher,
1043
0
                EVP_CIPHER_get0_name(ctr->cipher_ctr)))
1044
0
            goto err;
1045
0
    }
1046
1047
48
    ret = ossl_drbg_get_ctx_params(drbg, &p);
1048
48
err:
1049
48
    if (drbg->lock != NULL)
1050
48
        CRYPTO_THREAD_unlock(drbg->lock);
1051
1052
48
    return ret;
1053
48
}
1054
1055
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
1056
    ossl_unused void *provctx)
1057
0
{
1058
0
    return drbg_ctr_get_ctx_params_list;
1059
0
}
1060
1061
static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
1062
    const struct drbg_set_ctx_params_st *p)
1063
120
{
1064
120
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
1065
120
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
1066
120
    OSSL_PROVIDER *prov = NULL;
1067
120
    char *ecb;
1068
120
    const char *propquery = NULL;
1069
120
    int i, cipher_init = 0;
1070
1071
120
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
1072
        /* FIPS errors out in the drbg_ctr_init() call later */
1073
120
        ctr->use_df = i != 0;
1074
120
        cipher_init = 1;
1075
120
    }
1076
1077
120
    if (p->propq != NULL) {
1078
83
        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
1079
0
            return 0;
1080
83
        propquery = (const char *)p->propq->data;
1081
83
    }
1082
1083
120
    if (p->prov != NULL) {
1084
81
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
1085
0
            return 0;
1086
81
        if ((prov = ossl_provider_find(libctx,
1087
81
                 (const char *)p->prov->data, 1))
1088
81
            == NULL)
1089
37
            return 0;
1090
81
    }
1091
1092
83
    if (p->cipher != NULL) {
1093
83
        const char *base = (const char *)p->cipher->data;
1094
83
        size_t ctr_str_len = sizeof("CTR") - 1;
1095
83
        size_t ecb_str_len = sizeof("ECB") - 1;
1096
1097
83
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
1098
83
            || p->cipher->data_size < ctr_str_len) {
1099
19
            ossl_provider_free(prov);
1100
19
            return 0;
1101
19
        }
1102
64
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
1103
27
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
1104
27
            ossl_provider_free(prov);
1105
27
            return 0;
1106
27
        }
1107
37
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
1108
0
            ossl_provider_free(prov);
1109
0
            return 0;
1110
0
        }
1111
37
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
1112
37
        EVP_CIPHER_free(ctr->cipher_ecb);
1113
37
        EVP_CIPHER_free(ctr->cipher_ctr);
1114
        /*
1115
         * Try to fetch algorithms from our own provider code, fallback
1116
         * to generic fetch only if that fails
1117
         */
1118
37
        (void)ERR_set_mark();
1119
37
        ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
1120
37
        if (ctr->cipher_ctr == NULL) {
1121
0
            (void)ERR_pop_to_mark();
1122
0
            ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
1123
37
        } else {
1124
37
            (void)ERR_clear_last_mark();
1125
37
        }
1126
37
        (void)ERR_set_mark();
1127
37
        ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
1128
37
        if (ctr->cipher_ecb == NULL) {
1129
0
            (void)ERR_pop_to_mark();
1130
0
            ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
1131
37
        } else {
1132
37
            (void)ERR_clear_last_mark();
1133
37
        }
1134
37
        OPENSSL_free(ecb);
1135
37
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
1136
0
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
1137
0
            ossl_provider_free(prov);
1138
0
            return 0;
1139
0
        }
1140
37
        cipher_init = 1;
1141
37
    }
1142
37
    ossl_provider_free(prov);
1143
1144
37
    if (cipher_init && !drbg_ctr_init(ctx))
1145
0
        return 0;
1146
1147
37
    return ossl_drbg_set_ctx_params(ctx, p);
1148
37
}
1149
1150
#define drbg_ctr_set_ctx_params_st drbg_set_ctx_params_st
1151
1152
/* clang-format off */
1153
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
1154
#ifndef drbg_ctr_set_ctx_params_list
1155
static const OSSL_PARAM drbg_ctr_set_ctx_params_list[] = {
1156
    OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
1157
    OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
1158
    OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
1159
    OSSL_PARAM_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME, NULL, 0),
1160
    OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL),
1161
    OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL),
1162
    OSSL_PARAM_END
1163
};
1164
#endif
1165
1166
#ifndef drbg_ctr_set_ctx_params_st
1167
struct drbg_ctr_set_ctx_params_st {
1168
    OSSL_PARAM *cipher;
1169
    OSSL_PARAM *df;
1170
    OSSL_PARAM *propq;
1171
    OSSL_PARAM *prov;
1172
    OSSL_PARAM *reseed_req;
1173
    OSSL_PARAM *reseed_time;
1174
};
1175
#endif
1176
1177
#ifndef drbg_ctr_set_ctx_params_decoder
1178
static int drbg_ctr_set_ctx_params_decoder
1179
    (const OSSL_PARAM *p, struct drbg_ctr_set_ctx_params_st *r)
1180
70
{
1181
70
    const char *s;
1182
1183
70
    memset(r, 0, sizeof(*r));
1184
70
    if (p != NULL)
1185
464
        for (; (s = p->key) != NULL; p++)
1186
394
            switch(s[0]) {
1187
0
            default:
1188
0
                break;
1189
70
            case 'c':
1190
70
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
1191
                    /* OSSL_DRBG_PARAM_CIPHER */
1192
70
                    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
70
                    r->cipher = (OSSL_PARAM *)p;
1198
70
                }
1199
70
                break;
1200
114
            case 'p':
1201
114
                switch(s[1]) {
1202
0
                default:
1203
0
                    break;
1204
114
                case 'r':
1205
114
                    switch(s[2]) {
1206
0
                    default:
1207
0
                        break;
1208
114
                    case 'o':
1209
114
                        switch(s[3]) {
1210
0
                        default:
1211
0
                            break;
1212
44
                        case 'p':
1213
44
                            if (ossl_likely(strcmp("erties", s + 4) == 0)) {
1214
                                /* OSSL_DRBG_PARAM_PROPERTIES */
1215
44
                                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
44
                                r->propq = (OSSL_PARAM *)p;
1221
44
                            }
1222
44
                            break;
1223
70
                        case 'v':
1224
70
                            if (ossl_likely(strcmp("ider-name", s + 4) == 0)) {
1225
                                /* OSSL_PROV_PARAM_CORE_PROV_NAME */
1226
70
                                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
70
                                r->prov = (OSSL_PARAM *)p;
1232
70
                            }
1233
114
                        }
1234
114
                    }
1235
114
                }
1236
114
                break;
1237
140
            case 'r':
1238
140
                switch(s[1]) {
1239
0
                default:
1240
0
                    break;
1241
140
                case 'e':
1242
140
                    switch(s[2]) {
1243
0
                    default:
1244
0
                        break;
1245
140
                    case 's':
1246
140
                        switch(s[3]) {
1247
0
                        default:
1248
0
                            break;
1249
140
                        case 'e':
1250
140
                            switch(s[4]) {
1251
0
                            default:
1252
0
                                break;
1253
140
                            case 'e':
1254
140
                                switch(s[5]) {
1255
0
                                default:
1256
0
                                    break;
1257
140
                                case 'd':
1258
140
                                    switch(s[6]) {
1259
0
                                    default:
1260
0
                                        break;
1261
140
                                    case '_':
1262
140
                                        switch(s[7]) {
1263
0
                                        default:
1264
0
                                            break;
1265
70
                                        case 'r':
1266
70
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
1267
                                                /* OSSL_DRBG_PARAM_RESEED_REQUESTS */
1268
70
                                                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
70
                                                r->reseed_req = (OSSL_PARAM *)p;
1274
70
                                            }
1275
70
                                            break;
1276
70
                                        case 't':
1277
70
                                            if (ossl_likely(strcmp("ime_interval", s + 8) == 0)) {
1278
                                                /* OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL */
1279
70
                                                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
70
                                                r->reseed_time = (OSSL_PARAM *)p;
1285
70
                                            }
1286
140
                                        }
1287
140
                                    }
1288
140
                                }
1289
140
                            }
1290
140
                        }
1291
140
                    }
1292
140
                }
1293
140
                break;
1294
140
            case 'u':
1295
70
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1296
                    /* OSSL_DRBG_PARAM_USE_DF */
1297
70
                    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
70
                    r->df = (OSSL_PARAM *)p;
1303
70
                }
1304
394
            }
1305
70
    return 1;
1306
70
}
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
44
{
1313
44
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
1314
44
    struct drbg_set_ctx_params_st p;
1315
44
    int ret;
1316
1317
44
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
1318
0
        return 0;
1319
1320
44
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
1321
0
        return 0;
1322
1323
44
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
1324
1325
44
    if (drbg->lock != NULL)
1326
0
        CRYPTO_THREAD_unlock(drbg->lock);
1327
1328
44
    return ret;
1329
44
}
1330
1331
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
1332
    ossl_unused void *provctx)
1333
150
{
1334
150
    return drbg_ctr_set_ctx_params_list;
1335
150
}
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
};