Coverage Report

Created: 2025-12-04 06:33

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