Coverage Report

Created: 2026-04-09 06:50

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