Coverage Report

Created: 2026-04-01 06:39

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
490k
{
72
490k
    unsigned char *p = &ctr->V[0];
73
490k
    u32 n = 16, c = 1;
74
75
7.85M
    do {
76
7.85M
        --n;
77
7.85M
        c += p[n];
78
7.85M
        p[n] = (u8)c;
79
7.85M
        c >>= 8;
80
7.85M
    } while (n);
81
490k
}
82
83
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
84
65.3k
{
85
65.3k
    size_t i, n;
86
87
65.3k
    if (in == NULL || inlen == 0)
88
65.1k
        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
163k
{
277
163k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
278
163k
    int outlen = AES_BLOCK_SIZE;
279
163k
    unsigned char V_tmp[48], out[48];
280
163k
    unsigned char len;
281
282
    /* correct key is already set up. */
283
163k
    memcpy(V_tmp, ctr->V, 16);
284
163k
    inc_128(ctr);
285
163k
    memcpy(V_tmp + 16, ctr->V, 16);
286
163k
    if (ctr->keylen == 16) {
287
0
        len = 32;
288
163k
    } else {
289
163k
        inc_128(ctr);
290
163k
        memcpy(V_tmp + 32, ctr->V, 16);
291
163k
        len = 48;
292
163k
    }
293
163k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
294
163k
        || outlen != len)
295
0
        return 0;
296
163k
    memcpy(ctr->K, out, ctr->keylen);
297
163k
    memcpy(ctr->V, out + ctr->keylen, 16);
298
299
163k
    if (ctr->use_df) {
300
        /* If no input reuse existing derived value */
301
131k
        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
131k
        if (in1len)
306
178
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
307
131k
    } else {
308
32.5k
        ctr_XOR(ctr, in1, in1len);
309
32.5k
        ctr_XOR(ctr, in2, in2len);
310
32.5k
    }
311
312
163k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
313
163k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
314
0
        return 0;
315
163k
    return 1;
316
163k
}
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
163k
{
407
163k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
408
163k
    unsigned int ctr32, blocks;
409
163k
    int outl, buflen;
410
411
163k
    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
163k
    } else {
422
163k
        adinlen = 0;
423
163k
    }
424
425
163k
    inc_128(ctr);
426
427
163k
    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
163k
    memset(out, 0, outlen);
436
437
163k
    do {
438
163k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
439
163k
                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
163k
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
450
163k
        blocks = (buflen + 15) / 16;
451
452
163k
        ctr32 = GETU32(ctr->V + 12) + blocks;
453
163k
        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
163k
        PUTU32(ctr->V + 12, ctr32);
463
464
163k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
465
163k
            || outl != buflen)
466
0
            return 0;
467
468
163k
        out += buflen;
469
163k
        outlen -= buflen;
470
163k
    } while (outlen);
471
472
163k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
473
0
        return 0;
474
163k
    return 1;
475
163k
}
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
163k
{
481
163k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482
483
163k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
484
163k
        prediction_resistance, adin, adin_len);
485
163k
}
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
199
{
540
199
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
541
199
    int res = 1;
542
543
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
544
199
    drbg->max_request = 1 << 16;
545
199
    if (ctr->use_df) {
546
198
        drbg->min_entropylen = 0;
547
198
        drbg->max_entropylen = DRBG_MAX_LENGTH;
548
198
        drbg->min_noncelen = 0;
549
198
        drbg->max_noncelen = DRBG_MAX_LENGTH;
550
198
        drbg->max_perslen = DRBG_MAX_LENGTH;
551
198
        drbg->max_adinlen = DRBG_MAX_LENGTH;
552
553
198
        if (ctr->keylen > 0) {
554
44
            drbg->min_entropylen = ctr->keylen;
555
44
            drbg->min_noncelen = drbg->min_entropylen / 2;
556
44
        }
557
198
    } 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
199
    return res;
569
199
}
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
154
{
634
154
    PROV_DRBG_CTR *ctr;
635
636
154
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
637
154
    if (ctr == NULL)
638
0
        return 0;
639
640
154
    ctr->use_df = 1;
641
154
    drbg->data = ctr;
642
154
    OSSL_FIPS_IND_INIT(drbg)
643
154
    return drbg_ctr_init_lengths(drbg);
644
154
}
645
646
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
647
    const OSSL_DISPATCH *parent_dispatch)
648
154
{
649
154
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
650
154
        &drbg_ctr_new, &drbg_ctr_free,
651
154
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
652
154
        &drbg_ctr_reseed, &drbg_ctr_generate);
653
154
}
654
655
static void drbg_ctr_free(void *vdrbg)
656
138
{
657
138
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
658
138
    PROV_DRBG_CTR *ctr;
659
660
138
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
661
138
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
662
138
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
663
138
        EVP_CIPHER_CTX_free(ctr->ctx_df);
664
138
        EVP_CIPHER_free(ctr->cipher_ecb);
665
138
        EVP_CIPHER_free(ctr->cipher_ctr);
666
667
138
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
668
138
    }
669
138
    ossl_rand_drbg_free(drbg);
670
138
}
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
131k
{
727
131k
    const char *s;
728
729
131k
    memset(r, 0, sizeof(*r));
730
131k
    if (p != NULL)
731
262k
        for (; (s = p->key) != NULL; p++)
732
131k
            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
65.7k
            case 'm':
760
65.7k
                switch(s[1]) {
761
0
                default:
762
0
                    break;
763
65.7k
                case 'a':
764
65.7k
                    switch(s[2]) {
765
0
                    default:
766
0
                        break;
767
65.7k
                    case 'x':
768
65.7k
                        switch(s[3]) {
769
0
                        default:
770
0
                            break;
771
65.7k
                        case '_':
772
65.7k
                            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
65.7k
                            case 'r':
820
65.7k
                                if (ossl_likely(strcmp("equest", s + 5) == 0)) {
821
                                    /* OSSL_RAND_PARAM_MAX_REQUEST */
822
65.7k
                                    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
65.7k
                                    r->maxreq = (OSSL_PARAM *)p;
828
65.7k
                                }
829
65.7k
                            }
830
65.7k
                        }
831
65.7k
                    }
832
65.7k
                    break;
833
65.7k
                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
65.7k
                }
870
65.7k
                break;
871
65.7k
            case 'r':
872
65.7k
                switch(s[1]) {
873
0
                default:
874
0
                    break;
875
65.7k
                case 'e':
876
65.7k
                    switch(s[2]) {
877
0
                    default:
878
0
                        break;
879
65.7k
                    case 's':
880
65.7k
                        switch(s[3]) {
881
0
                        default:
882
0
                            break;
883
65.7k
                        case 'e':
884
65.7k
                            switch(s[4]) {
885
0
                            default:
886
0
                                break;
887
65.7k
                            case 'e':
888
65.7k
                                switch(s[5]) {
889
0
                                default:
890
0
                                    break;
891
65.7k
                                case 'd':
892
65.7k
                                    switch(s[6]) {
893
0
                                    default:
894
0
                                        break;
895
65.7k
                                    case '_':
896
65.7k
                                        switch(s[7]) {
897
0
                                        default:
898
0
                                            break;
899
65.7k
                                        case 'c':
900
65.7k
                                            if (ossl_likely(strcmp("ounter", s + 8) == 0)) {
901
                                                /* OSSL_DRBG_PARAM_RESEED_COUNTER */
902
65.7k
                                                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
65.7k
                                                r->reseed_cnt = (OSSL_PARAM *)p;
908
65.7k
                                            }
909
65.7k
                                            break;
910
65.7k
                                        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
65.7k
                                        }
960
65.7k
                                    }
961
65.7k
                                }
962
65.7k
                            }
963
65.7k
                        }
964
65.7k
                    }
965
65.7k
                }
966
65.7k
                break;
967
65.7k
            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
131k
            }
1010
131k
    return 1;
1011
131k
}
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
131k
{
1018
131k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
1019
131k
    PROV_DRBG_CTR *ctr;
1020
131k
    struct drbg_ctr_get_ctx_params_st p;
1021
131k
    int ret = 0, complete = 0;
1022
1023
131k
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
1024
0
        return 0;
1025
1026
131k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
1027
0
        return 0;
1028
1029
131k
    if (complete)
1030
131k
        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
123
{
1064
123
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
1065
123
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
1066
123
    OSSL_PROVIDER *prov = NULL;
1067
123
    char *ecb;
1068
123
    const char *propquery = NULL;
1069
123
    int i, cipher_init = 0;
1070
1071
123
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
1072
        /* FIPS errors out in the drbg_ctr_init() call later */
1073
123
        ctr->use_df = i != 0;
1074
123
        cipher_init = 1;
1075
123
    }
1076
1077
123
    if (p->propq != NULL) {
1078
86
        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
1079
0
            return 0;
1080
86
        propquery = (const char *)p->propq->data;
1081
86
    }
1082
1083
123
    if (p->prov != NULL) {
1084
92
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
1085
0
            return 0;
1086
92
        if ((prov = ossl_provider_find(libctx,
1087
92
                 (const char *)p->prov->data, 1))
1088
92
            == NULL)
1089
46
            return 0;
1090
92
    }
1091
1092
77
    if (p->cipher != NULL) {
1093
77
        const char *base = (const char *)p->cipher->data;
1094
77
        size_t ctr_str_len = sizeof("CTR") - 1;
1095
77
        size_t ecb_str_len = sizeof("ECB") - 1;
1096
1097
77
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
1098
77
            || p->cipher->data_size < ctr_str_len) {
1099
17
            ossl_provider_free(prov);
1100
17
            return 0;
1101
17
        }
1102
60
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
1103
23
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
1104
23
            ossl_provider_free(prov);
1105
23
            return 0;
1106
23
        }
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
81
{
1181
81
    const char *s;
1182
1183
81
    memset(r, 0, sizeof(*r));
1184
81
    if (p != NULL)
1185
541
        for (; (s = p->key) != NULL; p++)
1186
460
            switch(s[0]) {
1187
0
            default:
1188
0
                break;
1189
81
            case 'c':
1190
81
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
1191
                    /* OSSL_DRBG_PARAM_CIPHER */
1192
81
                    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
81
                    r->cipher = (OSSL_PARAM *)p;
1198
81
                }
1199
81
                break;
1200
136
            case 'p':
1201
136
                switch(s[1]) {
1202
0
                default:
1203
0
                    break;
1204
136
                case 'r':
1205
136
                    switch(s[2]) {
1206
0
                    default:
1207
0
                        break;
1208
136
                    case 'o':
1209
136
                        switch(s[3]) {
1210
0
                        default:
1211
0
                            break;
1212
55
                        case 'p':
1213
55
                            if (ossl_likely(strcmp("erties", s + 4) == 0)) {
1214
                                /* OSSL_DRBG_PARAM_PROPERTIES */
1215
55
                                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
55
                                r->propq = (OSSL_PARAM *)p;
1221
55
                            }
1222
55
                            break;
1223
81
                        case 'v':
1224
81
                            if (ossl_likely(strcmp("ider-name", s + 4) == 0)) {
1225
                                /* OSSL_PROV_PARAM_CORE_PROV_NAME */
1226
81
                                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
81
                                r->prov = (OSSL_PARAM *)p;
1232
81
                            }
1233
136
                        }
1234
136
                    }
1235
136
                }
1236
136
                break;
1237
162
            case 'r':
1238
162
                switch(s[1]) {
1239
0
                default:
1240
0
                    break;
1241
162
                case 'e':
1242
162
                    switch(s[2]) {
1243
0
                    default:
1244
0
                        break;
1245
162
                    case 's':
1246
162
                        switch(s[3]) {
1247
0
                        default:
1248
0
                            break;
1249
162
                        case 'e':
1250
162
                            switch(s[4]) {
1251
0
                            default:
1252
0
                                break;
1253
162
                            case 'e':
1254
162
                                switch(s[5]) {
1255
0
                                default:
1256
0
                                    break;
1257
162
                                case 'd':
1258
162
                                    switch(s[6]) {
1259
0
                                    default:
1260
0
                                        break;
1261
162
                                    case '_':
1262
162
                                        switch(s[7]) {
1263
0
                                        default:
1264
0
                                            break;
1265
81
                                        case 'r':
1266
81
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
1267
                                                /* OSSL_DRBG_PARAM_RESEED_REQUESTS */
1268
81
                                                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
81
                                                r->reseed_req = (OSSL_PARAM *)p;
1274
81
                                            }
1275
81
                                            break;
1276
81
                                        case 't':
1277
81
                                            if (ossl_likely(strcmp("ime_interval", s + 8) == 0)) {
1278
                                                /* OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL */
1279
81
                                                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
81
                                                r->reseed_time = (OSSL_PARAM *)p;
1285
81
                                            }
1286
162
                                        }
1287
162
                                    }
1288
162
                                }
1289
162
                            }
1290
162
                        }
1291
162
                    }
1292
162
                }
1293
162
                break;
1294
162
            case 'u':
1295
81
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1296
                    /* OSSL_DRBG_PARAM_USE_DF */
1297
81
                    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
81
                    r->df = (OSSL_PARAM *)p;
1303
81
                }
1304
460
            }
1305
81
    return 1;
1306
81
}
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
55
{
1313
55
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
1314
55
    struct drbg_set_ctx_params_st p;
1315
55
    int ret;
1316
1317
55
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
1318
0
        return 0;
1319
1320
55
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
1321
0
        return 0;
1322
1323
55
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
1324
1325
55
    if (drbg->lock != NULL)
1326
0
        CRYPTO_THREAD_unlock(drbg->lock);
1327
1328
55
    return ret;
1329
55
}
1330
1331
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
1332
    ossl_unused void *provctx)
1333
152
{
1334
152
    return drbg_ctr_set_ctx_params_list;
1335
152
}
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
};