Coverage Report

Created: 2025-08-28 06:41

/src/openssl/providers/implementations/rands/drbg_ctr.c
Line
Count
Source (jump to first uncovered line)
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
0
{
70
0
    unsigned char *p = &ctr->V[0];
71
0
    u32 n = 16, c = 1;
72
73
0
    do {
74
0
        --n;
75
0
        c += p[n];
76
0
        p[n] = (u8)c;
77
0
        c >>= 8;
78
0
    } while (n);
79
0
}
80
81
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
82
0
{
83
0
    size_t i, n;
84
85
0
    if (in == NULL || inlen == 0)
86
0
        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
0
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
93
0
    if (!ossl_assert(n <= sizeof(ctr->K)))
94
0
        return;
95
0
    for (i = 0; i < n; i++)
96
0
        ctr->K[i] ^= in[i];
97
0
    if (inlen <= ctr->keylen)
98
0
        return;
99
100
0
    n = inlen - ctr->keylen;
101
0
    if (n > 16) {
102
        /* Should never happen */
103
0
        n = 16;
104
0
    }
105
0
    for (i = 0; i < n; i++)
106
0
        ctr->V[i] ^= in[i + ctr->keylen];
107
0
}
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
0
{
115
0
    int i, outlen = AES_BLOCK_SIZE;
116
117
0
    for (i = 0; i < len; i++)
118
0
        out[i] ^= in[i];
119
120
0
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
121
0
        || outlen != len)
122
0
        return 0;
123
0
    return 1;
124
0
}
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
0
{
132
0
    unsigned char in_tmp[48];
133
0
    unsigned char num_of_blk = 2;
134
135
0
    memcpy(in_tmp, in, 16);
136
0
    memcpy(in_tmp + 16, in, 16);
137
0
    if (ctr->keylen != 16) {
138
0
        memcpy(in_tmp + 32, in, 16);
139
0
        num_of_blk = 3;
140
0
    }
141
0
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
142
0
}
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
0
{
150
0
    unsigned char bltmp[48] = {0};
151
0
    unsigned char num_of_blk;
152
153
0
    memset(ctr->KX, 0, 48);
154
0
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
155
0
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
156
0
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
157
0
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
158
0
}
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
0
{
166
0
    if (in == NULL || inlen == 0)
167
0
        return 1;
168
169
    /* If we have partial block handle it first */
170
0
    if (ctr->bltmp_pos) {
171
0
        size_t left = 16 - ctr->bltmp_pos;
172
173
        /* If we now have a complete block process it */
174
0
        if (inlen >= left) {
175
0
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
176
0
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
177
0
                return 0;
178
0
            ctr->bltmp_pos = 0;
179
0
            inlen -= left;
180
0
            in += left;
181
0
        }
182
0
    }
183
184
    /* Process zero or more complete blocks */
185
0
    for (; inlen >= 16; in += 16, inlen -= 16) {
186
0
        if (!ctr_BCC_blocks(ctr, in))
187
0
            return 0;
188
0
    }
189
190
    /* Copy any remaining partial block to the temporary buffer */
191
0
    if (inlen > 0) {
192
0
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
193
0
        ctr->bltmp_pos += inlen;
194
0
    }
195
0
    return 1;
196
0
}
197
198
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
199
0
{
200
0
    if (ctr->bltmp_pos) {
201
0
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
202
0
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
203
0
            return 0;
204
0
    }
205
0
    return 1;
206
0
}
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
0
{
213
0
    static unsigned char c80 = 0x80;
214
0
    size_t inlen;
215
0
    unsigned char *p = ctr->bltmp;
216
0
    int outlen = AES_BLOCK_SIZE;
217
218
0
    if (!ctr_BCC_init(ctr))
219
0
        return 0;
220
0
    if (in1 == NULL)
221
0
        in1len = 0;
222
0
    if (in2 == NULL)
223
0
        in2len = 0;
224
0
    if (in3 == NULL)
225
0
        in3len = 0;
226
0
    inlen = in1len + in2len + in3len;
227
    /* Initialise L||N in temporary block */
228
0
    *p++ = (inlen >> 24) & 0xff;
229
0
    *p++ = (inlen >> 16) & 0xff;
230
0
    *p++ = (inlen >> 8) & 0xff;
231
0
    *p++ = inlen & 0xff;
232
233
    /* NB keylen is at most 32 bytes */
234
0
    *p++ = 0;
235
0
    *p++ = 0;
236
0
    *p++ = 0;
237
0
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
238
0
    ctr->bltmp_pos = 8;
239
0
    if (!ctr_BCC_update(ctr, in1, in1len)
240
0
        || !ctr_BCC_update(ctr, in2, in2len)
241
0
        || !ctr_BCC_update(ctr, in3, in3len)
242
0
        || !ctr_BCC_update(ctr, &c80, 1)
243
0
        || !ctr_BCC_final(ctr))
244
0
        return 0;
245
    /* Set up key K */
246
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
247
0
        return 0;
248
    /* X follows key K */
249
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
250
0
                          AES_BLOCK_SIZE)
251
0
        || outlen != AES_BLOCK_SIZE)
252
0
        return 0;
253
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
254
0
                          AES_BLOCK_SIZE)
255
0
        || outlen != AES_BLOCK_SIZE)
256
0
        return 0;
257
0
    if (ctr->keylen != 16)
258
0
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
259
0
                              ctr->KX + 16, AES_BLOCK_SIZE)
260
0
            || outlen != AES_BLOCK_SIZE)
261
0
            return 0;
262
0
    return 1;
263
0
}
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
0
{
276
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
277
0
    int outlen = AES_BLOCK_SIZE;
278
0
    unsigned char V_tmp[48], out[48];
279
0
    unsigned char len;
280
281
    /* correct key is already set up. */
282
0
    memcpy(V_tmp, ctr->V, 16);
283
0
    inc_128(ctr);
284
0
    memcpy(V_tmp + 16, ctr->V, 16);
285
0
    if (ctr->keylen == 16) {
286
0
        len = 32;
287
0
    } else {
288
0
        inc_128(ctr);
289
0
        memcpy(V_tmp + 32, ctr->V, 16);
290
0
        len = 48;
291
0
    }
292
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
293
0
            || outlen != len)
294
0
        return 0;
295
0
    memcpy(ctr->K, out, ctr->keylen);
296
0
    memcpy(ctr->V, out + ctr->keylen, 16);
297
298
0
    if (ctr->use_df) {
299
        /* If no input reuse existing derived value */
300
0
        if (in1 != NULL || nonce != NULL || in2 != NULL)
301
0
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
302
0
                return 0;
303
        /* If this a reuse input in1len != 0 */
304
0
        if (in1len)
305
0
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
306
0
    } else {
307
0
        ctr_XOR(ctr, in1, in1len);
308
0
        ctr_XOR(ctr, in2, in2len);
309
0
    }
310
311
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
312
0
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
313
0
        return 0;
314
0
    return 1;
315
0
}
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
0
{
322
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
323
324
0
    if (entropy == NULL)
325
0
        return 0;
326
327
0
    memset(ctr->K, 0, sizeof(ctr->K));
328
0
    memset(ctr->V, 0, sizeof(ctr->V));
329
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
330
0
        return 0;
331
332
0
    inc_128(ctr);
333
0
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
334
0
        return 0;
335
0
    return 1;
336
0
}
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
0
{
344
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
345
0
    struct drbg_set_ctx_params_st p;
346
0
    int ret = 0;
347
348
0
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
349
0
        return 0;
350
351
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
352
0
        return 0;
353
354
0
    if (!ossl_prov_is_running()
355
0
            || !drbg_ctr_set_ctx_params_locked(drbg, &p))
356
0
        goto err;
357
0
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
358
0
                                     pstr, pstr_len);
359
0
 err:
360
0
    if (drbg->lock != NULL)
361
0
        CRYPTO_THREAD_unlock(drbg->lock);
362
0
    return ret;
363
0
}
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
0
{
369
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
370
371
0
    if (entropy == NULL)
372
0
        return 0;
373
374
0
    inc_128(ctr);
375
0
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
376
0
        return 0;
377
0
    return 1;
378
0
}
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
0
{
406
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
407
0
    unsigned int ctr32, blocks;
408
0
    int outl, buflen;
409
410
0
    if (adin != NULL && adinlen != 0) {
411
0
        inc_128(ctr);
412
413
0
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
414
0
            return 0;
415
        /* This means we reuse derived value */
416
0
        if (ctr->use_df) {
417
0
            adin = NULL;
418
0
            adinlen = 1;
419
0
        }
420
0
    } else {
421
0
        adinlen = 0;
422
0
    }
423
424
0
    inc_128(ctr);
425
426
0
    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
0
    memset(out, 0, outlen);
435
436
0
    do {
437
0
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
438
0
                               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
0
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
449
0
        blocks = (buflen + 15) / 16;
450
451
0
        ctr32 = GETU32(ctr->V + 12) + blocks;
452
0
        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
0
        PUTU32(ctr->V + 12, ctr32);
462
463
0
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
464
0
            || outl != buflen)
465
0
            return 0;
466
467
0
        out += buflen;
468
0
        outlen -= buflen;
469
0
    } while (outlen);
470
471
0
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
472
0
        return 0;
473
0
    return 1;
474
0
}
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
0
{
481
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
482
483
0
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
484
0
                                   prediction_resistance, adin, adin_len);
485
0
}
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
0
{
540
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
541
0
    int res = 1;
542
543
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
544
0
    drbg->max_request = 1 << 16;
545
0
    if (ctr->use_df) {
546
0
        drbg->min_entropylen = 0;
547
0
        drbg->max_entropylen = DRBG_MAX_LENGTH;
548
0
        drbg->min_noncelen = 0;
549
0
        drbg->max_noncelen = DRBG_MAX_LENGTH;
550
0
        drbg->max_perslen = DRBG_MAX_LENGTH;
551
0
        drbg->max_adinlen = DRBG_MAX_LENGTH;
552
553
0
        if (ctr->keylen > 0) {
554
0
            drbg->min_entropylen = ctr->keylen;
555
0
            drbg->min_noncelen = drbg->min_entropylen / 2;
556
0
        }
557
0
    } else {
558
0
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
559
560
0
        drbg->min_entropylen = len;
561
0
        drbg->max_entropylen = len;
562
        /* Nonce not used */
563
0
        drbg->min_noncelen = 0;
564
0
        drbg->max_noncelen = 0;
565
0
        drbg->max_perslen = len;
566
0
        drbg->max_adinlen = len;
567
0
    }
568
0
    return res;
569
0
}
570
571
static int drbg_ctr_init(PROV_DRBG *drbg)
572
0
{
573
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
574
0
    size_t keylen;
575
576
0
    if (ctr->cipher_ctr == NULL) {
577
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
578
0
        return 0;
579
0
    }
580
0
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
581
0
    if (ctr->ctx_ecb == NULL)
582
0
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
583
0
    if (ctr->ctx_ctr == NULL)
584
0
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
585
0
    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
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
591
0
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
592
0
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
593
0
                              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
0
    drbg->strength = (unsigned int)(keylen * 8);
599
0
    drbg->seedlen = keylen + 16;
600
601
0
    if (ctr->use_df) {
602
        /* df initialisation */
603
0
        static const unsigned char df_key[32] = {
604
0
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
605
0
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
606
0
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
607
0
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
608
0
        };
609
610
0
        if (ctr->ctx_df == NULL)
611
0
            ctr->ctx_df = EVP_CIPHER_CTX_new();
612
0
        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
0
        if (!EVP_CipherInit_ex(ctr->ctx_df,
618
0
                               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
0
    }
623
0
    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
0
}
631
632
static int drbg_ctr_new(PROV_DRBG *drbg)
633
0
{
634
0
    PROV_DRBG_CTR *ctr;
635
636
0
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
637
0
    if (ctr == NULL)
638
0
        return 0;
639
640
0
    ctr->use_df = 1;
641
0
    drbg->data = ctr;
642
0
    OSSL_FIPS_IND_INIT(drbg)
643
0
    return drbg_ctr_init_lengths(drbg);
644
0
}
645
646
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
647
                                   const OSSL_DISPATCH *parent_dispatch)
648
0
{
649
0
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
650
0
                              &drbg_ctr_new, &drbg_ctr_free,
651
0
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
652
0
                              &drbg_ctr_reseed, &drbg_ctr_generate);
653
0
}
654
655
static void drbg_ctr_free(void *vdrbg)
656
0
{
657
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
658
0
    PROV_DRBG_CTR *ctr;
659
660
0
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
661
0
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
662
0
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
663
0
        EVP_CIPHER_CTX_free(ctr->ctx_df);
664
0
        EVP_CIPHER_free(ctr->cipher_ecb);
665
0
        EVP_CIPHER_free(ctr->cipher_ctr);
666
667
0
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
668
0
    }
669
0
    ossl_rand_drbg_free(drbg);
670
0
}
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
0
{
726
0
    const char *s;
727
728
0
    memset(r, 0, sizeof(*r));
729
0
    if (p != NULL)
730
0
        for (; (s = p->key) != NULL; p++)
731
0
            switch(s[0]) {
732
0
            default:
733
0
                break;
734
0
            case 'c':
735
0
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
736
                    /* 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
                    /* 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
0
            case 'm':
759
0
                switch(s[1]) {
760
0
                default:
761
0
                    break;
762
0
                case 'a':
763
0
                    switch(s[2]) {
764
0
                    default:
765
0
                        break;
766
0
                    case 'x':
767
0
                        switch(s[3]) {
768
0
                        default:
769
0
                            break;
770
0
                        case '_':
771
0
                            switch(s[4]) {
772
0
                            default:
773
0
                                break;
774
0
                            case 'a':
775
0
                                if (ossl_likely(strcmp("dinlen", s + 5) == 0)) {
776
                                    /* 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
                                    /* 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
                                    /* 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
                                    /* 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
0
                            case 'r':
819
0
                                if (ossl_likely(strcmp("equest", s + 5) == 0)) {
820
                                    /* RAND_PARAM_MAX_REQUEST */
821
0
                                    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
0
                                    r->maxreq = (OSSL_PARAM *)p;
827
0
                                }
828
0
                            }
829
0
                        }
830
0
                    }
831
0
                    break;
832
0
                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
                                    /* 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
                                    /* 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
0
                }
869
0
                break;
870
0
            case 'r':
871
0
                switch(s[1]) {
872
0
                default:
873
0
                    break;
874
0
                case 'e':
875
0
                    switch(s[2]) {
876
0
                    default:
877
0
                        break;
878
0
                    case 's':
879
0
                        switch(s[3]) {
880
0
                        default:
881
0
                            break;
882
0
                        case 'e':
883
0
                            switch(s[4]) {
884
0
                            default:
885
0
                                break;
886
0
                            case 'e':
887
0
                                switch(s[5]) {
888
0
                                default:
889
0
                                    break;
890
0
                                case 'd':
891
0
                                    switch(s[6]) {
892
0
                                    default:
893
0
                                        break;
894
0
                                    case '_':
895
0
                                        switch(s[7]) {
896
0
                                        default:
897
0
                                            break;
898
0
                                        case 'c':
899
0
                                            if (ossl_likely(strcmp("ounter", s + 8) == 0)) {
900
                                                /* DRBG_PARAM_RESEED_COUNTER */
901
0
                                                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
0
                                                r->reseed_cnt = (OSSL_PARAM *)p;
907
0
                                            }
908
0
                                            break;
909
0
                                        case 'r':
910
0
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
911
                                                /* 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
                                                                /* 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
0
                                        }
959
0
                                    }
960
0
                                }
961
0
                            }
962
0
                        }
963
0
                    }
964
0
                }
965
0
                break;
966
0
            case 's':
967
0
                switch(s[1]) {
968
0
                default:
969
0
                    break;
970
0
                case 't':
971
0
                    switch(s[2]) {
972
0
                    default:
973
0
                        break;
974
0
                    case 'a':
975
0
                        if (ossl_likely(strcmp("te", s + 3) == 0)) {
976
                            /* 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
0
                    case 'r':
986
0
                        if (ossl_likely(strcmp("ength", s + 3) == 0)) {
987
                            /* RAND_PARAM_STRENGTH */
988
0
                            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
0
                            r->str = (OSSL_PARAM *)p;
994
0
                        }
995
0
                    }
996
0
                }
997
0
                break;
998
0
            case 'u':
999
0
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1000
                    /* 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
0
            }
1009
0
    return 1;
1010
0
}
1011
#endif
1012
/* End of machine generated */
1013
1014
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
1015
0
{
1016
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
1017
0
    PROV_DRBG_CTR *ctr;
1018
0
    struct drbg_ctr_get_ctx_params_st p;
1019
0
    int ret = 0, complete = 0;
1020
1021
0
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
1022
0
        return 0;
1023
1024
0
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
1025
0
        return 0;
1026
1027
0
    if (complete)
1028
0
        return 1;
1029
1030
0
    ctr = (PROV_DRBG_CTR *)drbg->data;
1031
1032
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
1033
0
        return 0;
1034
1035
0
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
1036
0
        goto err;
1037
1038
0
    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
0
    ret = ossl_drbg_get_ctx_params(drbg, &p);
1046
0
 err:
1047
0
    if (drbg->lock != NULL)
1048
0
        CRYPTO_THREAD_unlock(drbg->lock);
1049
1050
0
    return ret;
1051
0
}
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
0
{
1062
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
1063
0
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
1064
0
    OSSL_PROVIDER *prov = NULL;
1065
0
    char *ecb;
1066
0
    const char *propquery = NULL;
1067
0
    int i, cipher_init = 0;
1068
1069
0
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
1070
        /* FIPS errors out in the drbg_ctr_init() call later */
1071
0
        ctr->use_df = i != 0;
1072
0
        cipher_init = 1;
1073
0
    }
1074
1075
0
    if (p->propq != NULL) {
1076
0
        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
1077
0
            return 0;
1078
0
        propquery = (const char *)p->propq->data;
1079
0
    }
1080
1081
0
    if (p->prov != NULL) {
1082
0
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
1083
0
            return 0;
1084
0
        if ((prov = ossl_provider_find(libctx,
1085
0
                                       (const char *)p->prov->data, 1)) == NULL)
1086
0
            return 0;
1087
0
    }
1088
1089
0
    if (p->cipher != NULL) {
1090
0
        const char *base = (const char *)p->cipher->data;
1091
0
        size_t ctr_str_len = sizeof("CTR") - 1;
1092
0
        size_t ecb_str_len = sizeof("ECB") - 1;
1093
1094
0
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
1095
0
                || p->cipher->data_size < ctr_str_len) {
1096
0
            ossl_provider_free(prov);
1097
0
            return 0;
1098
0
        }
1099
0
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
1100
0
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
1101
0
            ossl_provider_free(prov);
1102
0
            return 0;
1103
0
        }
1104
0
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
1105
0
            ossl_provider_free(prov);
1106
0
            return 0;
1107
0
        }
1108
0
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
1109
0
        EVP_CIPHER_free(ctr->cipher_ecb);
1110
0
        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
0
        (void)ERR_set_mark();
1116
0
        ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
1117
0
        if (ctr->cipher_ctr == NULL) {
1118
0
            (void)ERR_pop_to_mark();
1119
0
            ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
1120
0
        } else {
1121
0
            (void)ERR_clear_last_mark();
1122
0
        }
1123
0
        (void)ERR_set_mark();
1124
0
        ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
1125
0
        if (ctr->cipher_ecb == NULL) {
1126
0
            (void)ERR_pop_to_mark();
1127
0
            ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
1128
0
        } else {
1129
0
            (void)ERR_clear_last_mark();
1130
0
        }
1131
0
        OPENSSL_free(ecb);
1132
0
        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
0
        cipher_init = 1;
1138
0
    }
1139
0
    ossl_provider_free(prov);
1140
1141
0
    if (cipher_init && !drbg_ctr_init(ctx))
1142
0
        return 0;
1143
1144
0
    return ossl_drbg_set_ctx_params(ctx, p);
1145
0
}
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
0
{
1177
0
    const char *s;
1178
1179
0
    memset(r, 0, sizeof(*r));
1180
0
    if (p != NULL)
1181
0
        for (; (s = p->key) != NULL; p++)
1182
0
            switch(s[0]) {
1183
0
            default:
1184
0
                break;
1185
0
            case 'c':
1186
0
                if (ossl_likely(strcmp("ipher", s + 1) == 0)) {
1187
                    /* DRBG_PARAM_CIPHER */
1188
0
                    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
0
                    r->cipher = (OSSL_PARAM *)p;
1194
0
                }
1195
0
                break;
1196
0
            case 'p':
1197
0
                switch(s[1]) {
1198
0
                default:
1199
0
                    break;
1200
0
                case 'r':
1201
0
                    switch(s[2]) {
1202
0
                    default:
1203
0
                        break;
1204
0
                    case 'o':
1205
0
                        switch(s[3]) {
1206
0
                        default:
1207
0
                            break;
1208
0
                        case 'p':
1209
0
                            if (ossl_likely(strcmp("erties", s + 4) == 0)) {
1210
                                /* DRBG_PARAM_PROPERTIES */
1211
0
                                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
0
                                r->propq = (OSSL_PARAM *)p;
1217
0
                            }
1218
0
                            break;
1219
0
                        case 'v':
1220
0
                            if (ossl_likely(strcmp("ider-name", s + 4) == 0)) {
1221
                                /* PROV_PARAM_CORE_PROV_NAME */
1222
0
                                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
0
                                r->prov = (OSSL_PARAM *)p;
1228
0
                            }
1229
0
                        }
1230
0
                    }
1231
0
                }
1232
0
                break;
1233
0
            case 'r':
1234
0
                switch(s[1]) {
1235
0
                default:
1236
0
                    break;
1237
0
                case 'e':
1238
0
                    switch(s[2]) {
1239
0
                    default:
1240
0
                        break;
1241
0
                    case 's':
1242
0
                        switch(s[3]) {
1243
0
                        default:
1244
0
                            break;
1245
0
                        case 'e':
1246
0
                            switch(s[4]) {
1247
0
                            default:
1248
0
                                break;
1249
0
                            case 'e':
1250
0
                                switch(s[5]) {
1251
0
                                default:
1252
0
                                    break;
1253
0
                                case 'd':
1254
0
                                    switch(s[6]) {
1255
0
                                    default:
1256
0
                                        break;
1257
0
                                    case '_':
1258
0
                                        switch(s[7]) {
1259
0
                                        default:
1260
0
                                            break;
1261
0
                                        case 'r':
1262
0
                                            if (ossl_likely(strcmp("equests", s + 8) == 0)) {
1263
                                                /* DRBG_PARAM_RESEED_REQUESTS */
1264
0
                                                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
0
                                                r->reseed_req = (OSSL_PARAM *)p;
1270
0
                                            }
1271
0
                                            break;
1272
0
                                        case 't':
1273
0
                                            if (ossl_likely(strcmp("ime_interval", s + 8) == 0)) {
1274
                                                /* DRBG_PARAM_RESEED_TIME_INTERVAL */
1275
0
                                                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
0
                                                r->reseed_time = (OSSL_PARAM *)p;
1281
0
                                            }
1282
0
                                        }
1283
0
                                    }
1284
0
                                }
1285
0
                            }
1286
0
                        }
1287
0
                    }
1288
0
                }
1289
0
                break;
1290
0
            case 'u':
1291
0
                if (ossl_likely(strcmp("se_derivation_function", s + 1) == 0)) {
1292
                    /* DRBG_PARAM_USE_DF */
1293
0
                    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
0
                    r->df = (OSSL_PARAM *)p;
1299
0
                }
1300
0
            }
1301
0
    return 1;
1302
0
}
1303
#endif
1304
/* End of machine generated */
1305
1306
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
1307
0
{
1308
0
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
1309
0
    struct drbg_set_ctx_params_st p;
1310
0
    int ret;
1311
1312
0
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
1313
0
        return 0;
1314
1315
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
1316
0
        return 0;
1317
1318
0
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
1319
1320
0
    if (drbg->lock != NULL)
1321
0
        CRYPTO_THREAD_unlock(drbg->lock);
1322
1323
0
    return ret;
1324
0
}
1325
1326
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
1327
                                                      ossl_unused void *provctx)
1328
0
{
1329
0
    return drbg_ctr_set_ctx_params_list;
1330
0
}
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
};