Coverage Report

Created: 2026-05-24 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/providers/implementations/rands/drbg_ctr.c
Line
Count
Source
1
/*
2
 * Copyright 2011-2026 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
#include <stdlib.h>
11
#include <string.h>
12
#include <openssl/crypto.h>
13
#include <openssl/err.h>
14
#include <openssl/rand.h>
15
#include <openssl/aes.h>
16
#include <openssl/proverr.h>
17
#include "crypto/modes.h"
18
#include "internal/thread_once.h"
19
#include "prov/implementations.h"
20
#include "prov/providercommon.h"
21
#include "prov/provider_ctx.h"
22
#include "prov/drbg.h"
23
#include "crypto/evp.h"
24
#include "crypto/evp/evp_local.h"
25
#include "internal/provider.h"
26
#include "internal/common.h"
27
#include "internal/fips.h"
28
29
#define drbg_ctr_get_ctx_params_st drbg_get_ctx_params_st
30
#define drbg_ctr_set_ctx_params_st drbg_set_ctx_params_st
31
32
#include "providers/implementations/rands/drbg_ctr.inc"
33
34
static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
35
static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
36
static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper;
37
static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper;
38
static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper;
39
static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper;
40
static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params;
41
static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params;
42
static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
43
static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
44
static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;
45
46
static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *drbg,
47
    const struct drbg_set_ctx_params_st *p);
48
49
/*
50
 * The state of a DRBG AES-CTR.
51
 */
52
typedef struct rand_drbg_ctr_st {
53
    EVP_CIPHER_CTX *ctx_ecb;
54
    EVP_CIPHER_CTX *ctx_ctr;
55
    EVP_CIPHER_CTX *ctx_df;
56
    EVP_CIPHER *cipher_ecb;
57
    EVP_CIPHER *cipher_ctr;
58
    size_t keylen;
59
    int use_df;
60
    unsigned char K[32];
61
    unsigned char V[16];
62
    /* Temporary block storage used by ctr_df */
63
    unsigned char bltmp[16];
64
    size_t bltmp_pos;
65
    unsigned char KX[48];
66
} PROV_DRBG_CTR;
67
68
/*
69
 * Implementation of NIST SP 800-90A CTR DRBG.
70
 */
71
static void inc_128(PROV_DRBG_CTR *ctr)
72
631k
{
73
631k
    unsigned char *p = &ctr->V[0];
74
631k
    u32 n = 16, c = 1;
75
76
10.1M
    do {
77
10.1M
        --n;
78
10.1M
        c += p[n];
79
10.1M
        p[n] = (u8)c;
80
10.1M
        c >>= 8;
81
10.1M
    } while (n);
82
631k
}
83
84
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
85
95.5k
{
86
95.5k
    size_t i, n;
87
88
95.5k
    if (in == NULL || inlen == 0)
89
95.3k
        return;
90
91
    /*
92
     * Any zero padding will have no effect on the result as we
93
     * are XORing. So just process however much input we have.
94
     */
95
181
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
96
181
    if (!ossl_assert(n <= sizeof(ctr->K)))
97
0
        return;
98
5.97k
    for (i = 0; i < n; i++)
99
5.78k
        ctr->K[i] ^= in[i];
100
181
    if (inlen <= ctr->keylen)
101
1
        return;
102
103
180
    n = inlen - ctr->keylen;
104
180
    if (n > 16) {
105
        /* Should never happen */
106
0
        n = 16;
107
0
    }
108
3.06k
    for (i = 0; i < n; i++)
109
2.88k
        ctr->V[i] ^= in[i + ctr->keylen];
110
180
}
111
112
/*
113
 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
114
 */
115
__owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out,
116
    const unsigned char *in, int len)
117
574
{
118
574
    int i, outlen = AES_BLOCK_SIZE;
119
120
28.1k
    for (i = 0; i < len; i++)
121
27.5k
        out[i] ^= in[i];
122
123
574
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
124
574
        || outlen != len)
125
0
        return 0;
126
574
    return 1;
127
574
}
128
129
/*
130
 * Handle several BCC operations for as much data as we need for K and X
131
 */
132
__owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
133
450
{
134
450
    unsigned char in_tmp[48];
135
450
    unsigned char num_of_blk = 2;
136
137
450
    memcpy(in_tmp, in, 16);
138
450
    memcpy(in_tmp + 16, in, 16);
139
450
    if (ctr->keylen != 16) {
140
450
        memcpy(in_tmp + 32, in, 16);
141
450
        num_of_blk = 3;
142
450
    }
143
450
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
144
450
}
145
146
/*
147
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
148
 * see 10.3.1 stage 7.
149
 */
150
__owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
151
124
{
152
124
    unsigned char bltmp[48] = { 0 };
153
124
    unsigned char num_of_blk;
154
155
124
    memset(ctr->KX, 0, 48);
156
124
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
157
124
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
158
124
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
159
124
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
160
124
}
161
162
/*
163
 * Process several blocks into BCC algorithm, some possibly partial
164
 */
165
__owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
166
    const unsigned char *in, size_t inlen)
167
496
{
168
496
    if (in == NULL || inlen == 0)
169
204
        return 1;
170
171
    /* If we have partial block handle it first */
172
292
    if (ctr->bltmp_pos) {
173
238
        size_t left = 16 - ctr->bltmp_pos;
174
175
        /* If we now have a complete block process it */
176
238
        if (inlen >= left) {
177
168
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
178
168
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
179
0
                return 0;
180
168
            ctr->bltmp_pos = 0;
181
168
            inlen -= left;
182
168
            in += left;
183
168
        }
184
238
    }
185
186
    /* Process zero or more complete blocks */
187
450
    for (; inlen >= 16; in += 16, inlen -= 16) {
188
158
        if (!ctr_BCC_blocks(ctr, in))
189
0
            return 0;
190
158
    }
191
192
    /* Copy any remaining partial block to the temporary buffer */
193
292
    if (inlen > 0) {
194
238
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
195
238
        ctr->bltmp_pos += inlen;
196
238
    }
197
292
    return 1;
198
292
}
199
200
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
201
124
{
202
124
    if (ctr->bltmp_pos) {
203
124
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
204
124
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
205
0
            return 0;
206
124
    }
207
124
    return 1;
208
124
}
209
210
__owur static int ctr_df(PROV_DRBG_CTR *ctr,
211
    const unsigned char *in1, size_t in1len,
212
    const unsigned char *in2, size_t in2len,
213
    const unsigned char *in3, size_t in3len)
214
124
{
215
124
    static unsigned char c80 = 0x80;
216
124
    size_t inlen;
217
124
    unsigned char *p = ctr->bltmp;
218
124
    int outlen = AES_BLOCK_SIZE;
219
220
124
    if (!ctr_BCC_init(ctr))
221
0
        return 0;
222
124
    if (in1 == NULL)
223
0
        in1len = 0;
224
124
    if (in2 == NULL)
225
124
        in2len = 0;
226
124
    if (in3 == NULL)
227
80
        in3len = 0;
228
124
    inlen = in1len + in2len + in3len;
229
    /* Initialise L||N in temporary block */
230
124
    *p++ = (inlen >> 24) & 0xff;
231
124
    *p++ = (inlen >> 16) & 0xff;
232
124
    *p++ = (inlen >> 8) & 0xff;
233
124
    *p++ = inlen & 0xff;
234
235
    /* NB keylen is at most 32 bytes */
236
124
    *p++ = 0;
237
124
    *p++ = 0;
238
124
    *p++ = 0;
239
124
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
240
124
    ctr->bltmp_pos = 8;
241
124
    if (!ctr_BCC_update(ctr, in1, in1len)
242
124
        || !ctr_BCC_update(ctr, in2, in2len)
243
124
        || !ctr_BCC_update(ctr, in3, in3len)
244
124
        || !ctr_BCC_update(ctr, &c80, 1)
245
124
        || !ctr_BCC_final(ctr))
246
0
        return 0;
247
    /* Set up key K */
248
124
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
249
0
        return 0;
250
    /* X follows key K */
251
124
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
252
124
            AES_BLOCK_SIZE)
253
124
        || outlen != AES_BLOCK_SIZE)
254
0
        return 0;
255
124
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
256
124
            AES_BLOCK_SIZE)
257
124
        || outlen != AES_BLOCK_SIZE)
258
0
        return 0;
259
124
    if (ctr->keylen != 16)
260
124
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
261
124
                ctr->KX + 16, AES_BLOCK_SIZE)
262
124
            || outlen != AES_BLOCK_SIZE)
263
0
            return 0;
264
124
    return 1;
265
124
}
266
267
/*
268
 * NB the no-df Update in SP800-90A specifies a constant input length
269
 * of seedlen, however other uses of this algorithm pad the input with
270
 * zeroes if necessary and have up to two parameters XORed together,
271
 * so we handle both cases in this function instead.
272
 */
273
__owur static int ctr_update(PROV_DRBG *drbg,
274
    const unsigned char *in1, size_t in1len,
275
    const unsigned char *in2, size_t in2len,
276
    const unsigned char *nonce, size_t noncelen)
277
210k
{
278
210k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
279
210k
    int outlen = AES_BLOCK_SIZE;
280
210k
    unsigned char V_tmp[48], out[48];
281
210k
    unsigned char len;
282
283
    /* correct key is already set up. */
284
210k
    memcpy(V_tmp, ctr->V, 16);
285
210k
    inc_128(ctr);
286
210k
    memcpy(V_tmp + 16, ctr->V, 16);
287
210k
    if (ctr->keylen == 16) {
288
0
        len = 32;
289
210k
    } else {
290
210k
        inc_128(ctr);
291
210k
        memcpy(V_tmp + 32, ctr->V, 16);
292
210k
        len = 48;
293
210k
    }
294
210k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
295
210k
        || outlen != len)
296
0
        return 0;
297
210k
    memcpy(ctr->K, out, ctr->keylen);
298
210k
    memcpy(ctr->V, out + ctr->keylen, 16);
299
300
210k
    if (ctr->use_df) {
301
        /* If no input reuse existing derived value */
302
162k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
303
124
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
304
0
                return 0;
305
        /* If this a reuse input in1len != 0 */
306
162k
        if (in1len)
307
178
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
308
162k
    } else {
309
47.6k
        ctr_XOR(ctr, in1, in1len);
310
47.6k
        ctr_XOR(ctr, in2, in2len);
311
47.6k
    }
312
313
210k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
314
210k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
315
0
        return 0;
316
210k
    return 1;
317
210k
}
318
319
static int drbg_ctr_instantiate(PROV_DRBG *drbg,
320
    const unsigned char *entropy, size_t entropylen,
321
    const unsigned char *nonce, size_t noncelen,
322
    const unsigned char *pers, size_t perslen)
323
45
{
324
45
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
325
326
45
    if (entropy == NULL)
327
0
        return 0;
328
329
45
    memset(ctr->K, 0, sizeof(ctr->K));
330
45
    memset(ctr->V, 0, sizeof(ctr->V));
331
45
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
332
0
        return 0;
333
334
45
    inc_128(ctr);
335
45
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
336
0
        return 0;
337
45
    return 1;
338
45
}
339
340
static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
341
    int prediction_resistance,
342
    const unsigned char *pstr,
343
    size_t pstr_len,
344
    const OSSL_PARAM params[])
345
26
{
346
26
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
347
26
    struct drbg_set_ctx_params_st p;
348
26
    int ret = 0;
349
350
26
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
351
0
        return 0;
352
353
26
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
354
0
        return 0;
355
356
26
    if (!ossl_prov_is_running()
357
26
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
358
0
        goto err;
359
26
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
360
26
        pstr, pstr_len);
361
26
err:
362
26
    if (drbg->lock != NULL)
363
0
        CRYPTO_THREAD_unlock(drbg->lock);
364
26
    return ret;
365
26
}
366
367
static int drbg_ctr_reseed(PROV_DRBG *drbg,
368
    const unsigned char *entropy, size_t entropylen,
369
    const unsigned char *adin, size_t adinlen)
370
27
{
371
27
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
372
373
27
    if (entropy == NULL)
374
0
        return 0;
375
376
27
    inc_128(ctr);
377
27
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
378
0
        return 0;
379
27
    return 1;
380
27
}
381
382
static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
383
    const unsigned char *ent, size_t ent_len,
384
    const unsigned char *adin, size_t adin_len)
385
0
{
386
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
387
388
0
    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
389
0
        adin, adin_len);
390
0
}
391
392
static void ctr96_inc(unsigned char *counter)
393
0
{
394
0
    u32 n = 12, c = 1;
395
396
0
    do {
397
0
        --n;
398
0
        c += counter[n];
399
0
        counter[n] = (u8)c;
400
0
        c >>= 8;
401
0
    } while (n);
402
0
}
403
404
static int drbg_ctr_generate(PROV_DRBG *drbg,
405
    unsigned char *out, size_t outlen,
406
    const unsigned char *adin, size_t adinlen)
407
210k
{
408
210k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
409
210k
    unsigned int ctr32, blocks;
410
210k
    int outl, buflen;
411
412
210k
    if (adin != NULL && adinlen != 0) {
413
54
        inc_128(ctr);
414
415
54
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
416
0
            return 0;
417
        /* This means we reuse derived value */
418
54
        if (ctr->use_df) {
419
54
            adin = NULL;
420
54
            adinlen = 1;
421
54
        }
422
210k
    } else {
423
210k
        adinlen = 0;
424
210k
    }
425
426
210k
    inc_128(ctr);
427
428
210k
    if (outlen == 0) {
429
0
        inc_128(ctr);
430
431
0
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
432
0
            return 0;
433
0
        return 1;
434
0
    }
435
436
210k
    memset(out, 0, outlen);
437
438
210k
    do {
439
210k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
440
210k
                NULL, NULL, NULL, ctr->V, -1))
441
0
            return 0;
442
443
        /*-
444
         * outlen has type size_t while EVP_CipherUpdate takes an
445
         * int argument and thus cannot be guaranteed to process more
446
         * than 2^31-1 bytes at a time. We process such huge generate
447
         * requests in 2^30 byte chunks, which is the greatest multiple
448
         * of AES block size lower than or equal to 2^31-1.
449
         */
450
210k
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
451
210k
        blocks = (buflen + 15) / 16;
452
453
210k
        ctr32 = GETU32(ctr->V + 12) + blocks;
454
210k
        if (ctr32 < blocks) {
455
            /* 32-bit counter overflow into V. */
456
0
            if (ctr32 != 0) {
457
0
                blocks -= ctr32;
458
0
                buflen = blocks * 16;
459
0
                ctr32 = 0;
460
0
            }
461
0
            ctr96_inc(ctr->V);
462
0
        }
463
210k
        PUTU32(ctr->V + 12, ctr32);
464
465
210k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
466
210k
            || outl != buflen)
467
0
            return 0;
468
469
210k
        out += buflen;
470
210k
        outlen -= buflen;
471
210k
    } while (outlen);
472
473
210k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
474
0
        return 0;
475
210k
    return 1;
476
210k
}
477
478
static int drbg_ctr_generate_wrapper(void *vdrbg, unsigned char *out, size_t outlen,
479
    unsigned int strength, int prediction_resistance,
480
    const unsigned char *adin, size_t adin_len)
481
210k
{
482
210k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
483
484
210k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
485
210k
        prediction_resistance, adin, adin_len);
486
210k
}
487
488
static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
489
0
{
490
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
491
492
0
    OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
493
0
    OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
494
0
    OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
495
0
    OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
496
0
    ctr->bltmp_pos = 0;
497
0
    return ossl_prov_drbg_uninstantiate(drbg);
498
0
}
499
500
static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
501
0
{
502
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
503
0
    int ret;
504
505
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
506
0
        return 0;
507
508
0
    ret = drbg_ctr_uninstantiate(drbg);
509
510
0
    if (drbg->lock != NULL)
511
0
        CRYPTO_THREAD_unlock(drbg->lock);
512
513
0
    return ret;
514
0
}
515
516
static int drbg_ctr_verify_zeroization(void *vdrbg)
517
0
{
518
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
519
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
520
0
    int ret = 0;
521
522
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
523
0
        return 0;
524
525
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->K);
526
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->V);
527
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp);
528
0
    PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX);
529
0
    if (ctr->bltmp_pos != 0)
530
0
        goto err;
531
532
0
    ret = 1;
533
0
err:
534
0
    if (drbg->lock != NULL)
535
0
        CRYPTO_THREAD_unlock(drbg->lock);
536
0
    return ret;
537
0
}
538
539
static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
540
199
{
541
199
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
542
199
    int res = 1;
543
544
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
545
199
    drbg->max_request = 1 << 16;
546
199
    if (ctr->use_df) {
547
198
        drbg->min_entropylen = 0;
548
198
        drbg->max_entropylen = DRBG_MAX_LENGTH;
549
198
        drbg->min_noncelen = 0;
550
198
        drbg->max_noncelen = DRBG_MAX_LENGTH;
551
198
        drbg->max_perslen = DRBG_MAX_LENGTH;
552
198
        drbg->max_adinlen = DRBG_MAX_LENGTH;
553
554
198
        if (ctr->keylen > 0) {
555
44
            drbg->min_entropylen = ctr->keylen;
556
44
            drbg->min_noncelen = drbg->min_entropylen / 2;
557
44
        }
558
198
    } else {
559
1
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
560
561
1
        drbg->min_entropylen = len;
562
1
        drbg->max_entropylen = len;
563
        /* Nonce not used */
564
1
        drbg->min_noncelen = 0;
565
1
        drbg->max_noncelen = 0;
566
1
        drbg->max_perslen = len;
567
1
        drbg->max_adinlen = len;
568
1
    }
569
199
    return res;
570
199
}
571
572
static int drbg_ctr_init(PROV_DRBG *drbg)
573
45
{
574
45
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
575
45
    size_t keylen;
576
577
45
    if (ctr->cipher_ctr == NULL) {
578
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
579
0
        return 0;
580
0
    }
581
45
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
582
45
    if (ctr->ctx_ecb == NULL)
583
45
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
584
45
    if (ctr->ctx_ctr == NULL)
585
45
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
586
45
    if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
587
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
588
0
        goto err;
589
0
    }
590
591
45
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
592
45
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
593
45
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
594
45
            ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
595
0
        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
596
0
        goto err;
597
0
    }
598
599
45
    drbg->strength = (unsigned int)(keylen * 8);
600
45
    drbg->seedlen = keylen + 16;
601
602
45
    if (ctr->use_df) {
603
        /* df initialisation */
604
44
        static const unsigned char df_key[32] = {
605
44
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
606
44
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
607
44
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
608
44
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
609
44
        };
610
611
44
        if (ctr->ctx_df == NULL)
612
44
            ctr->ctx_df = EVP_CIPHER_CTX_new();
613
44
        if (ctr->ctx_df == NULL) {
614
0
            ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
615
0
            goto err;
616
0
        }
617
        /* Set key schedule for df_key */
618
44
        if (!EVP_CipherInit_ex(ctr->ctx_df,
619
44
                ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
620
0
            ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
621
0
            goto err;
622
0
        }
623
44
    }
624
45
    return drbg_ctr_init_lengths(drbg);
625
626
0
err:
627
0
    EVP_CIPHER_CTX_free(ctr->ctx_ecb);
628
0
    EVP_CIPHER_CTX_free(ctr->ctx_ctr);
629
0
    ctr->ctx_ecb = ctr->ctx_ctr = NULL;
630
0
    return 0;
631
45
}
632
633
static int drbg_ctr_new(PROV_DRBG *drbg)
634
154
{
635
154
    PROV_DRBG_CTR *ctr;
636
637
154
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
638
154
    if (ctr == NULL)
639
0
        return 0;
640
641
154
    ctr->use_df = 1;
642
154
    drbg->data = ctr;
643
154
    OSSL_FIPS_IND_INIT(drbg)
644
154
    return drbg_ctr_init_lengths(drbg);
645
154
}
646
647
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
648
    const OSSL_DISPATCH *parent_dispatch)
649
154
{
650
#ifdef FIPS_MODULE
651
    if (!ossl_deferred_self_test(PROV_LIBCTX_OF(provctx),
652
            ST_ID_DRBG_CTR))
653
        return NULL;
654
#endif
655
656
154
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
657
154
        &drbg_ctr_new, &drbg_ctr_free,
658
154
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
659
154
        &drbg_ctr_reseed, &drbg_ctr_generate);
660
154
}
661
662
static void drbg_ctr_free(void *vdrbg)
663
138
{
664
138
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
665
138
    PROV_DRBG_CTR *ctr;
666
667
138
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
668
138
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
669
138
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
670
138
        EVP_CIPHER_CTX_free(ctr->ctx_df);
671
138
        EVP_CIPHER_free(ctr->cipher_ecb);
672
138
        EVP_CIPHER_free(ctr->cipher_ctr);
673
674
138
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
675
138
    }
676
138
    ossl_rand_drbg_free(drbg);
677
138
}
678
679
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
680
198k
{
681
198k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
682
198k
    PROV_DRBG_CTR *ctr;
683
198k
    struct drbg_ctr_get_ctx_params_st p;
684
198k
    int ret = 0, complete = 0;
685
686
198k
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
687
0
        return 0;
688
689
198k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
690
0
        return 0;
691
692
198k
    if (complete)
693
198k
        return 1;
694
695
48
    ctr = (PROV_DRBG_CTR *)drbg->data;
696
697
48
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
698
0
        return 0;
699
700
48
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
701
0
        goto err;
702
703
48
    if (p.cipher != NULL) {
704
0
        if (ctr->cipher_ctr == NULL
705
0
            || !OSSL_PARAM_set_utf8_string(p.cipher,
706
0
                EVP_CIPHER_get0_name(ctr->cipher_ctr)))
707
0
            goto err;
708
0
    }
709
710
48
    ret = ossl_drbg_get_ctx_params(drbg, &p);
711
48
err:
712
48
    if (drbg->lock != NULL)
713
48
        CRYPTO_THREAD_unlock(drbg->lock);
714
715
48
    return ret;
716
48
}
717
718
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
719
    ossl_unused void *provctx)
720
0
{
721
0
    return drbg_ctr_get_ctx_params_list;
722
0
}
723
724
static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx,
725
    const struct drbg_set_ctx_params_st *p)
726
113
{
727
113
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
728
113
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
729
113
    OSSL_PROVIDER *prov = NULL;
730
113
    char *ecb;
731
113
    const char *propquery = NULL;
732
113
    int i, cipher_init = 0;
733
734
113
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
735
        /* FIPS errors out in the drbg_ctr_init() call later */
736
113
        ctr->use_df = i != 0;
737
113
        cipher_init = 1;
738
113
    }
739
740
113
    if (p->propq != NULL) {
741
76
        if (p->propq->data_type != OSSL_PARAM_UTF8_STRING)
742
0
            return 0;
743
76
        propquery = (const char *)p->propq->data;
744
76
    }
745
746
113
    if (p->prov != NULL) {
747
74
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
748
0
            return 0;
749
74
        if ((prov = ossl_provider_find(libctx,
750
74
                 (const char *)p->prov->data, 1))
751
74
            == NULL)
752
29
            return 0;
753
74
    }
754
755
84
    if (p->cipher != NULL) {
756
84
        const char *base = (const char *)p->cipher->data;
757
84
        size_t ctr_str_len = sizeof("CTR") - 1;
758
84
        size_t ecb_str_len = sizeof("ECB") - 1;
759
760
84
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
761
84
            || p->cipher->data_size < ctr_str_len) {
762
17
            ossl_provider_free(prov);
763
17
            return 0;
764
17
        }
765
67
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
766
30
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
767
30
            ossl_provider_free(prov);
768
30
            return 0;
769
30
        }
770
37
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
771
0
            ossl_provider_free(prov);
772
0
            return 0;
773
0
        }
774
37
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
775
37
        EVP_CIPHER_free(ctr->cipher_ecb);
776
37
        EVP_CIPHER_free(ctr->cipher_ctr);
777
        /*
778
         * Try to fetch algorithms from our own provider code, fallback
779
         * to generic fetch only if that fails
780
         */
781
37
        (void)ERR_set_mark();
782
37
        ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
783
37
        if (ctr->cipher_ctr == NULL) {
784
0
            (void)ERR_pop_to_mark();
785
0
            ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
786
37
        } else {
787
37
            (void)ERR_clear_last_mark();
788
37
        }
789
37
        (void)ERR_set_mark();
790
37
        ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
791
37
        if (ctr->cipher_ecb == NULL) {
792
0
            (void)ERR_pop_to_mark();
793
0
            ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
794
37
        } else {
795
37
            (void)ERR_clear_last_mark();
796
37
        }
797
37
        OPENSSL_free(ecb);
798
37
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
799
0
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
800
0
            ossl_provider_free(prov);
801
0
            return 0;
802
0
        }
803
37
        cipher_init = 1;
804
37
    }
805
37
    ossl_provider_free(prov);
806
807
37
    if (cipher_init && !drbg_ctr_init(ctx))
808
0
        return 0;
809
810
37
    return ossl_drbg_set_ctx_params(ctx, p);
811
37
}
812
813
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
814
37
{
815
37
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
816
37
    struct drbg_set_ctx_params_st p;
817
37
    int ret;
818
819
37
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
820
0
        return 0;
821
822
37
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
823
0
        return 0;
824
825
37
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
826
827
37
    if (drbg->lock != NULL)
828
0
        CRYPTO_THREAD_unlock(drbg->lock);
829
830
37
    return ret;
831
37
}
832
833
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
834
    ossl_unused void *provctx)
835
152
{
836
152
    return drbg_ctr_set_ctx_params_list;
837
152
}
838
839
const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
840
    { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_ctr_new_wrapper },
841
    { OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_ctr_free },
842
    { OSSL_FUNC_RAND_INSTANTIATE,
843
        (void (*)(void))drbg_ctr_instantiate_wrapper },
844
    { OSSL_FUNC_RAND_UNINSTANTIATE,
845
        (void (*)(void))drbg_ctr_uninstantiate_wrapper },
846
    { OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_ctr_generate_wrapper },
847
    { OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_ctr_reseed_wrapper },
848
    { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },
849
    { OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },
850
    { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },
851
    { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
852
        (void (*)(void))drbg_ctr_settable_ctx_params },
853
    { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_ctr_set_ctx_params },
854
    { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
855
        (void (*)(void))drbg_ctr_gettable_ctx_params },
856
    { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_ctr_get_ctx_params },
857
    { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
858
        (void (*)(void))drbg_ctr_verify_zeroization },
859
    { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },
860
    { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },
861
    OSSL_DISPATCH_END
862
};