Coverage Report

Created: 2025-08-25 06:30

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