Coverage Report

Created: 2026-02-14 07:20

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