Coverage Report

Created: 2026-04-01 06:39

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