Coverage Report

Created: 2026-09-12 06:55

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-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 "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
350k
{
66
350k
    unsigned char *p = &ctr->V[0];
67
350k
    u32 n = 16, c = 1;
68
69
5.60M
    do {
70
5.60M
        --n;
71
5.60M
        c += p[n];
72
5.60M
        p[n] = (u8)c;
73
5.60M
        c >>= 8;
74
5.60M
    } while (n);
75
350k
}
76
77
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
78
212
{
79
212
    size_t i, n;
80
81
212
    if (in == NULL || inlen == 0)
82
0
        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
212
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
89
212
    if (!ossl_assert(n <= sizeof(ctr->K)))
90
0
        return;
91
6.99k
    for (i = 0; i < n; i++)
92
6.78k
        ctr->K[i] ^= in[i];
93
212
    if (inlen <= ctr->keylen)
94
0
        return;
95
96
212
    n = inlen - ctr->keylen;
97
212
    if (n > 16) {
98
        /* Should never happen */
99
0
        n = 16;
100
0
    }
101
3.60k
    for (i = 0; i < n; i++)
102
3.39k
        ctr->V[i] ^= in[i + ctr->keylen];
103
212
}
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
684
{
111
684
    int i, outlen = AES_BLOCK_SIZE;
112
113
33.5k
    for (i = 0; i < len; i++)
114
32.8k
        out[i] ^= in[i];
115
116
684
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
117
684
        || outlen != len)
118
0
        return 0;
119
684
    return 1;
120
684
}
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
536
{
127
536
    unsigned char in_tmp[48];
128
536
    unsigned char num_of_blk = 2;
129
130
536
    memcpy(in_tmp, in, 16);
131
536
    memcpy(in_tmp + 16, in, 16);
132
536
    if (ctr->keylen != 16) {
133
536
        memcpy(in_tmp + 32, in, 16);
134
536
        num_of_blk = 3;
135
536
    }
136
536
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
137
536
}
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
148
{
145
148
    unsigned char bltmp[48] = { 0 };
146
148
    unsigned char num_of_blk;
147
148
148
    memset(ctr->KX, 0, 48);
149
148
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
150
148
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
151
148
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
152
148
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
153
148
}
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
592
{
161
592
    if (in == NULL || inlen == 0)
162
244
        return 1;
163
164
    /* If we have partial block handle it first */
165
348
    if (ctr->bltmp_pos) {
166
284
        size_t left = 16 - ctr->bltmp_pos;
167
168
        /* If we now have a complete block process it */
169
284
        if (inlen >= left) {
170
200
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
171
200
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
172
0
                return 0;
173
200
            ctr->bltmp_pos = 0;
174
200
            inlen -= left;
175
200
            in += left;
176
200
        }
177
284
    }
178
179
    /* Process zero or more complete blocks */
180
536
    for (; inlen >= 16; in += 16, inlen -= 16) {
181
188
        if (!ctr_BCC_blocks(ctr, in))
182
0
            return 0;
183
188
    }
184
185
    /* Copy any remaining partial block to the temporary buffer */
186
348
    if (inlen > 0) {
187
284
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
188
284
        ctr->bltmp_pos += inlen;
189
284
    }
190
348
    return 1;
191
348
}
192
193
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
194
148
{
195
148
    if (ctr->bltmp_pos) {
196
148
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
197
148
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
198
0
            return 0;
199
148
    }
200
148
    return 1;
201
148
}
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
148
{
208
148
    static unsigned char c80 = 0x80;
209
148
    size_t inlen;
210
148
    unsigned char *p = ctr->bltmp;
211
148
    int outlen = AES_BLOCK_SIZE;
212
213
148
    if (!ctr_BCC_init(ctr))
214
0
        return 0;
215
148
    if (in1 == NULL)
216
0
        in1len = 0;
217
148
    if (in2 == NULL)
218
148
        in2len = 0;
219
148
    if (in3 == NULL)
220
96
        in3len = 0;
221
148
    inlen = in1len + in2len + in3len;
222
    /* Initialise L||N in temporary block */
223
148
    *p++ = (inlen >> 24) & 0xff;
224
148
    *p++ = (inlen >> 16) & 0xff;
225
148
    *p++ = (inlen >> 8) & 0xff;
226
148
    *p++ = inlen & 0xff;
227
228
    /* NB keylen is at most 32 bytes */
229
148
    *p++ = 0;
230
148
    *p++ = 0;
231
148
    *p++ = 0;
232
148
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
233
148
    ctr->bltmp_pos = 8;
234
148
    if (!ctr_BCC_update(ctr, in1, in1len)
235
148
        || !ctr_BCC_update(ctr, in2, in2len)
236
148
        || !ctr_BCC_update(ctr, in3, in3len)
237
148
        || !ctr_BCC_update(ctr, &c80, 1)
238
148
        || !ctr_BCC_final(ctr))
239
0
        return 0;
240
    /* Set up key K */
241
148
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
242
0
        return 0;
243
    /* X follows key K */
244
148
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
245
148
            AES_BLOCK_SIZE)
246
148
        || outlen != AES_BLOCK_SIZE)
247
0
        return 0;
248
148
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
249
148
            AES_BLOCK_SIZE)
250
148
        || outlen != AES_BLOCK_SIZE)
251
0
        return 0;
252
148
    if (ctr->keylen != 16)
253
148
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
254
148
                ctr->KX + 16, AES_BLOCK_SIZE)
255
148
            || outlen != AES_BLOCK_SIZE)
256
0
            return 0;
257
148
    return 1;
258
148
}
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
116k
{
271
116k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
272
116k
    int outlen = AES_BLOCK_SIZE;
273
116k
    unsigned char V_tmp[48], out[48];
274
116k
    unsigned char len;
275
276
    /* correct key is already set up. */
277
116k
    memcpy(V_tmp, ctr->V, 16);
278
116k
    inc_128(ctr);
279
116k
    memcpy(V_tmp + 16, ctr->V, 16);
280
116k
    if (ctr->keylen == 16) {
281
0
        len = 32;
282
116k
    } else {
283
116k
        inc_128(ctr);
284
116k
        memcpy(V_tmp + 32, ctr->V, 16);
285
116k
        len = 48;
286
116k
    }
287
116k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
288
116k
        || outlen != len)
289
0
        return 0;
290
116k
    memcpy(ctr->K, out, ctr->keylen);
291
116k
    memcpy(ctr->V, out + ctr->keylen, 16);
292
293
116k
    if (ctr->use_df) {
294
        /* If no input reuse existing derived value */
295
116k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
296
148
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
297
0
                return 0;
298
        /* If this a reuse input in1len != 0 */
299
116k
        if (in1len)
300
212
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
301
116k
    } else {
302
0
        ctr_XOR(ctr, in1, in1len);
303
0
        ctr_XOR(ctr, in2, in2len);
304
0
    }
305
306
116k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
307
116k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
308
0
        return 0;
309
116k
    return 1;
310
116k
}
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
52
{
317
52
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
318
319
52
    if (entropy == NULL)
320
0
        return 0;
321
322
52
    memset(ctr->K, 0, sizeof(ctr->K));
323
52
    memset(ctr->V, 0, sizeof(ctr->V));
324
52
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
325
0
        return 0;
326
327
52
    inc_128(ctr);
328
52
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
329
0
        return 0;
330
52
    return 1;
331
52
}
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
15
{
339
15
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
340
15
    int ret = 0;
341
342
15
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
343
0
        return 0;
344
345
15
    if (!ossl_prov_is_running()
346
15
        || !drbg_ctr_set_ctx_params_locked(drbg, params))
347
0
        goto err;
348
15
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
349
15
        pstr, pstr_len);
350
15
err:
351
15
    if (drbg->lock != NULL)
352
0
        CRYPTO_THREAD_unlock(drbg->lock);
353
15
    return ret;
354
15
}
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
32
{
360
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
361
362
32
    if (entropy == NULL)
363
0
        return 0;
364
365
32
    inc_128(ctr);
366
32
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
367
0
        return 0;
368
32
    return 1;
369
32
}
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
116k
{
397
116k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
398
116k
    unsigned int ctr32, blocks;
399
116k
    int outl, buflen;
400
401
116k
    if (adin != NULL && adinlen != 0) {
402
64
        inc_128(ctr);
403
404
64
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
405
0
            return 0;
406
        /* This means we reuse derived value */
407
64
        if (ctr->use_df) {
408
64
            adin = NULL;
409
64
            adinlen = 1;
410
64
        }
411
116k
    } else {
412
116k
        adinlen = 0;
413
116k
    }
414
415
116k
    inc_128(ctr);
416
417
116k
    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
116k
    memset(out, 0, outlen);
426
427
116k
    do {
428
116k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
429
116k
                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
116k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
440
116k
        blocks = (buflen + 15) / 16;
441
442
116k
        ctr32 = GETU32(ctr->V + 12) + blocks;
443
116k
        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
116k
        PUTU32(ctr->V + 12, ctr32);
453
454
116k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
455
116k
            || outl != buflen)
456
0
            return 0;
457
458
116k
        out += buflen;
459
116k
        outlen -= buflen;
460
116k
    } while (outlen);
461
462
116k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
463
0
        return 0;
464
116k
    return 1;
465
116k
}
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
116k
{
471
116k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
472
473
116k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
474
116k
        prediction_resistance, adin, adin_len);
475
116k
}
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
234
{
530
234
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
531
234
    int res = 1;
532
533
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
534
234
    drbg->max_request = 1 << 16;
535
234
    if (ctr->use_df) {
536
234
        drbg->min_entropylen = 0;
537
234
        drbg->max_entropylen = DRBG_MAX_LENGTH;
538
234
        drbg->min_noncelen = 0;
539
234
        drbg->max_noncelen = DRBG_MAX_LENGTH;
540
234
        drbg->max_perslen = DRBG_MAX_LENGTH;
541
234
        drbg->max_adinlen = DRBG_MAX_LENGTH;
542
543
234
        if (ctr->keylen > 0) {
544
52
            drbg->min_entropylen = ctr->keylen;
545
52
            drbg->min_noncelen = drbg->min_entropylen / 2;
546
52
        }
547
234
    } else {
548
0
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
549
550
0
        drbg->min_entropylen = len;
551
0
        drbg->max_entropylen = len;
552
        /* Nonce not used */
553
0
        drbg->min_noncelen = 0;
554
0
        drbg->max_noncelen = 0;
555
0
        drbg->max_perslen = len;
556
0
        drbg->max_adinlen = len;
557
0
    }
558
234
    return res;
559
234
}
560
561
static int drbg_ctr_init(PROV_DRBG *drbg)
562
52
{
563
52
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
564
52
    size_t keylen;
565
566
52
    if (ctr->cipher_ctr == NULL) {
567
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
568
0
        return 0;
569
0
    }
570
52
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
571
52
    if (ctr->ctx_ecb == NULL)
572
52
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
573
52
    if (ctr->ctx_ctr == NULL)
574
52
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
575
52
    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
52
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
581
52
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
582
52
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
583
52
            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
52
    drbg->strength = keylen * 8;
589
52
    drbg->seedlen = keylen + 16;
590
591
#ifdef FIPS_MODULE
592
    /*
593
     * FIPS requires that we use a derivation function since our
594
     * entropy source is outside the fips boundary
595
     */
596
    if (ctr->use_df == 0) {
597
        ERR_raise_data(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED,
598
            "FIPS requires the use of a derivation function");
599
        goto err;
600
    }
601
#endif
602
603
52
    if (ctr->use_df) {
604
        /* df initialisation */
605
52
        static const unsigned char df_key[32] = {
606
52
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
607
52
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
608
52
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
609
52
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
610
52
        };
611
612
52
        if (ctr->ctx_df == NULL)
613
52
            ctr->ctx_df = EVP_CIPHER_CTX_new();
614
52
        if (ctr->ctx_df == NULL) {
615
0
            ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
616
0
            goto err;
617
0
        }
618
        /* Set key schedule for df_key */
619
52
        if (!EVP_CipherInit_ex(ctr->ctx_df,
620
52
                ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
621
0
            ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
622
0
            goto err;
623
0
        }
624
52
    }
625
52
    return drbg_ctr_init_lengths(drbg);
626
627
0
err:
628
0
    EVP_CIPHER_CTX_free(ctr->ctx_ecb);
629
0
    EVP_CIPHER_CTX_free(ctr->ctx_ctr);
630
0
    ctr->ctx_ecb = ctr->ctx_ctr = NULL;
631
0
    return 0;
632
52
}
633
634
static int drbg_ctr_new(PROV_DRBG *drbg)
635
182
{
636
182
    PROV_DRBG_CTR *ctr;
637
638
182
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
639
182
    if (ctr == NULL)
640
0
        return 0;
641
642
182
    ctr->use_df = 1;
643
182
    drbg->data = ctr;
644
182
    OSSL_FIPS_IND_INIT(drbg)
645
182
    return drbg_ctr_init_lengths(drbg);
646
182
}
647
648
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
649
    const OSSL_DISPATCH *parent_dispatch)
650
182
{
651
182
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
652
182
        &drbg_ctr_new, &drbg_ctr_free,
653
182
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
654
182
        &drbg_ctr_reseed, &drbg_ctr_generate);
655
182
}
656
657
static void drbg_ctr_free(void *vdrbg)
658
155
{
659
155
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
660
155
    PROV_DRBG_CTR *ctr;
661
662
155
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
663
155
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
664
155
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
665
155
        EVP_CIPHER_CTX_free(ctr->ctx_df);
666
155
        EVP_CIPHER_free(ctr->cipher_ecb);
667
155
        EVP_CIPHER_free(ctr->cipher_ctr);
668
669
155
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
670
155
    }
671
155
    ossl_rand_drbg_free(drbg);
672
155
}
673
674
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
675
60.2k
{
676
60.2k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
677
60.2k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
678
60.2k
    OSSL_PARAM *p;
679
60.2k
    int ret = 0, complete = 0;
680
681
60.2k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
682
0
        return 0;
683
684
60.2k
    if (complete)
685
60.1k
        return 1;
686
687
27
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
688
0
        return 0;
689
690
27
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
691
27
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
692
0
        goto err;
693
694
27
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
695
27
    if (p != NULL) {
696
0
        if (ctr->cipher_ctr == NULL
697
0
            || !OSSL_PARAM_set_utf8_string(p,
698
0
                EVP_CIPHER_get0_name(ctr->cipher_ctr)))
699
0
            goto err;
700
0
    }
701
702
27
    ret = ossl_drbg_get_ctx_params(drbg, params);
703
27
err:
704
27
    if (drbg->lock != NULL)
705
27
        CRYPTO_THREAD_unlock(drbg->lock);
706
707
27
    return ret;
708
27
}
709
710
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
711
    ossl_unused void *provctx)
712
0
{
713
0
    static const OSSL_PARAM known_gettable_ctx_params[] = {
714
0
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
715
0
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
716
0
        OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
717
0
        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
718
0
            OSSL_PARAM_END
719
0
    };
720
0
    return known_gettable_ctx_params;
721
0
}
722
723
static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
724
44
{
725
44
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
726
44
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
727
44
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
728
44
    const OSSL_PARAM *p;
729
44
    char *ecb;
730
44
    const char *propquery = NULL;
731
44
    int i, cipher_init = 0;
732
733
44
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
734
44
        && OSSL_PARAM_get_int(p, &i)) {
735
        /* FIPS errors out in the drbg_ctr_init() call later */
736
44
        ctr->use_df = i != 0;
737
44
        cipher_init = 1;
738
44
    }
739
740
44
    if ((p = OSSL_PARAM_locate_const(params,
741
44
             OSSL_DRBG_PARAM_PROPERTIES))
742
44
        != NULL) {
743
33
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
744
0
            return 0;
745
33
    }
746
747
44
#ifndef FIPS_MODULE
748
44
    propquery = "provider=default";
749
44
    if (p != NULL
750
33
        && p->data_type == OSSL_PARAM_UTF8_STRING)
751
33
        propquery = (const char *)p->data;
752
44
#endif
753
754
44
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
755
44
        const char *base = (const char *)p->data;
756
44
        size_t ctr_str_len = sizeof("CTR") - 1;
757
44
        size_t ecb_str_len = sizeof("ECB") - 1;
758
759
44
        if (p->data_type != OSSL_PARAM_UTF8_STRING
760
44
            || p->data_size < ctr_str_len) {
761
13
            return 0;
762
13
        }
763
31
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
764
20
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
765
20
            return 0;
766
20
        }
767
11
        if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
768
0
            return 0;
769
0
        }
770
11
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
771
11
        EVP_CIPHER_free(ctr->cipher_ecb);
772
11
        EVP_CIPHER_free(ctr->cipher_ctr);
773
11
        ctr->cipher_ctr = NULL;
774
11
        ctr->cipher_ecb = NULL;
775
        /*
776
         * Try to fetch algorithms from our own provider code, fallback
777
         * to generic fetch only if that fails
778
         */
779
11
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
780
11
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
781
11
        OPENSSL_free(ecb);
782
11
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
783
0
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
784
0
            return 0;
785
0
        }
786
11
        cipher_init = 1;
787
11
    }
788
789
11
    if (cipher_init && !drbg_ctr_init(ctx))
790
0
        return 0;
791
792
11
    return ossl_drbg_set_ctx_params(ctx, params);
793
11
}
794
795
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
796
62
{
797
62
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
798
62
    int ret;
799
800
62
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
801
0
        return 0;
802
803
62
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
804
805
62
    if (drbg->lock != NULL)
806
0
        CRYPTO_THREAD_unlock(drbg->lock);
807
808
62
    return ret;
809
62
}
810
811
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
812
    ossl_unused void *provctx)
813
182
{
814
182
    static const OSSL_PARAM known_settable_ctx_params[] = {
815
182
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
816
182
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
817
182
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
818
182
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
819
        OSSL_PARAM_END
820
182
    };
821
182
    return known_settable_ctx_params;
822
182
}
823
824
const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
825
    { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_ctr_new_wrapper },
826
    { OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_ctr_free },
827
    { OSSL_FUNC_RAND_INSTANTIATE,
828
        (void (*)(void))drbg_ctr_instantiate_wrapper },
829
    { OSSL_FUNC_RAND_UNINSTANTIATE,
830
        (void (*)(void))drbg_ctr_uninstantiate_wrapper },
831
    { OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_ctr_generate_wrapper },
832
    { OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_ctr_reseed_wrapper },
833
    { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },
834
    { OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },
835
    { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },
836
    { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
837
        (void (*)(void))drbg_ctr_settable_ctx_params },
838
    { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_ctr_set_ctx_params },
839
    { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
840
        (void (*)(void))drbg_ctr_gettable_ctx_params },
841
    { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_ctr_get_ctx_params },
842
    { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
843
        (void (*)(void))drbg_ctr_verify_zeroization },
844
    { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },
845
    { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },
846
    OSSL_DISPATCH_END
847
};