Coverage Report

Created: 2026-10-28 06:28

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
455k
{
66
455k
    unsigned char *p = &ctr->V[0];
67
455k
    u32 n = 16, c = 1;
68
69
7.28M
    do {
70
7.28M
        --n;
71
7.28M
        c += p[n];
72
7.28M
        p[n] = (u8)c;
73
7.28M
        c >>= 8;
74
7.28M
    } while (n);
75
455k
}
76
77
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
78
278
{
79
278
    size_t i, n;
80
81
278
    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
278
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
89
278
    if (!ossl_assert(n <= sizeof(ctr->K)))
90
0
        return;
91
9.17k
    for (i = 0; i < n; i++)
92
8.89k
        ctr->K[i] ^= in[i];
93
278
    if (inlen <= ctr->keylen)
94
0
        return;
95
96
278
    n = inlen - ctr->keylen;
97
278
    if (n > 16) {
98
        /* Should never happen */
99
0
        n = 16;
100
0
    }
101
4.72k
    for (i = 0; i < n; i++)
102
4.44k
        ctr->V[i] ^= in[i + ctr->keylen];
103
278
}
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
896
{
111
896
    int i, outlen = AES_BLOCK_SIZE;
112
113
43.9k
    for (i = 0; i < len; i++)
114
43.0k
        out[i] ^= in[i];
115
116
896
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
117
896
        || outlen != len)
118
0
        return 0;
119
896
    return 1;
120
896
}
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
702
{
127
702
    unsigned char in_tmp[48];
128
702
    unsigned char num_of_blk = 2;
129
130
702
    memcpy(in_tmp, in, 16);
131
702
    memcpy(in_tmp + 16, in, 16);
132
702
    if (ctr->keylen != 16) {
133
702
        memcpy(in_tmp + 32, in, 16);
134
702
        num_of_blk = 3;
135
702
    }
136
702
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
137
702
}
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
194
{
145
194
    unsigned char bltmp[48] = { 0 };
146
194
    unsigned char num_of_blk;
147
148
194
    memset(ctr->KX, 0, 48);
149
194
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
150
194
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
151
194
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
152
194
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
153
194
}
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
776
{
161
776
    if (in == NULL || inlen == 0)
162
320
        return 1;
163
164
    /* If we have partial block handle it first */
165
456
    if (ctr->bltmp_pos) {
166
372
        size_t left = 16 - ctr->bltmp_pos;
167
168
        /* If we now have a complete block process it */
169
372
        if (inlen >= left) {
170
262
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
171
262
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
172
0
                return 0;
173
262
            ctr->bltmp_pos = 0;
174
262
            inlen -= left;
175
262
            in += left;
176
262
        }
177
372
    }
178
179
    /* Process zero or more complete blocks */
180
702
    for (; inlen >= 16; in += 16, inlen -= 16) {
181
246
        if (!ctr_BCC_blocks(ctr, in))
182
0
            return 0;
183
246
    }
184
185
    /* Copy any remaining partial block to the temporary buffer */
186
456
    if (inlen > 0) {
187
372
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
188
372
        ctr->bltmp_pos += inlen;
189
372
    }
190
456
    return 1;
191
456
}
192
193
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
194
194
{
195
194
    if (ctr->bltmp_pos) {
196
194
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
197
194
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
198
0
            return 0;
199
194
    }
200
194
    return 1;
201
194
}
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
194
{
208
194
    static unsigned char c80 = 0x80;
209
194
    size_t inlen;
210
194
    unsigned char *p = ctr->bltmp;
211
194
    int outlen = AES_BLOCK_SIZE;
212
213
194
    if (!ctr_BCC_init(ctr))
214
0
        return 0;
215
194
    if (in1 == NULL)
216
0
        in1len = 0;
217
194
    if (in2 == NULL)
218
194
        in2len = 0;
219
194
    if (in3 == NULL)
220
126
        in3len = 0;
221
194
    inlen = in1len + in2len + in3len;
222
    /* Initialise L||N in temporary block */
223
194
    *p++ = (inlen >> 24) & 0xff;
224
194
    *p++ = (inlen >> 16) & 0xff;
225
194
    *p++ = (inlen >> 8) & 0xff;
226
194
    *p++ = inlen & 0xff;
227
228
    /* NB keylen is at most 32 bytes */
229
194
    *p++ = 0;
230
194
    *p++ = 0;
231
194
    *p++ = 0;
232
194
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
233
194
    ctr->bltmp_pos = 8;
234
194
    if (!ctr_BCC_update(ctr, in1, in1len)
235
194
        || !ctr_BCC_update(ctr, in2, in2len)
236
194
        || !ctr_BCC_update(ctr, in3, in3len)
237
194
        || !ctr_BCC_update(ctr, &c80, 1)
238
194
        || !ctr_BCC_final(ctr))
239
0
        return 0;
240
    /* Set up key K */
241
194
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
242
0
        return 0;
243
    /* X follows key K */
244
194
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
245
194
            AES_BLOCK_SIZE)
246
194
        || outlen != AES_BLOCK_SIZE)
247
0
        return 0;
248
194
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
249
194
            AES_BLOCK_SIZE)
250
194
        || outlen != AES_BLOCK_SIZE)
251
0
        return 0;
252
194
    if (ctr->keylen != 16)
253
194
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
254
194
                ctr->KX + 16, AES_BLOCK_SIZE)
255
194
            || outlen != AES_BLOCK_SIZE)
256
0
            return 0;
257
194
    return 1;
258
194
}
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
151k
{
271
151k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
272
151k
    int outlen = AES_BLOCK_SIZE;
273
151k
    unsigned char V_tmp[48], out[48];
274
151k
    unsigned char len;
275
276
    /* correct key is already set up. */
277
151k
    memcpy(V_tmp, ctr->V, 16);
278
151k
    inc_128(ctr);
279
151k
    memcpy(V_tmp + 16, ctr->V, 16);
280
151k
    if (ctr->keylen == 16) {
281
0
        len = 32;
282
151k
    } else {
283
151k
        inc_128(ctr);
284
151k
        memcpy(V_tmp + 32, ctr->V, 16);
285
151k
        len = 48;
286
151k
    }
287
151k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
288
151k
        || outlen != len)
289
0
        return 0;
290
151k
    memcpy(ctr->K, out, ctr->keylen);
291
151k
    memcpy(ctr->V, out + ctr->keylen, 16);
292
293
151k
    if (ctr->use_df) {
294
        /* If no input reuse existing derived value */
295
151k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
296
194
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
297
0
                return 0;
298
        /* If this a reuse input in1len != 0 */
299
151k
        if (in1len)
300
278
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
301
151k
    } else {
302
0
        ctr_XOR(ctr, in1, in1len);
303
0
        ctr_XOR(ctr, in2, in2len);
304
0
    }
305
306
151k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
307
151k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
308
0
        return 0;
309
151k
    return 1;
310
151k
}
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
68
{
317
68
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
318
319
68
    if (entropy == NULL)
320
0
        return 0;
321
322
68
    memset(ctr->K, 0, sizeof(ctr->K));
323
68
    memset(ctr->V, 0, sizeof(ctr->V));
324
68
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
325
0
        return 0;
326
327
68
    inc_128(ctr);
328
68
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
329
0
        return 0;
330
68
    return 1;
331
68
}
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
42
{
360
42
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
361
362
42
    if (entropy == NULL)
363
0
        return 0;
364
365
42
    inc_128(ctr);
366
42
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
367
0
        return 0;
368
42
    return 1;
369
42
}
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
151k
{
397
151k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
398
151k
    unsigned int ctr32, blocks;
399
151k
    int outl, buflen;
400
401
151k
    if (adin != NULL && adinlen != 0) {
402
84
        inc_128(ctr);
403
404
84
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
405
0
            return 0;
406
        /* This means we reuse derived value */
407
84
        if (ctr->use_df) {
408
84
            adin = NULL;
409
84
            adinlen = 1;
410
84
        }
411
151k
    } else {
412
151k
        adinlen = 0;
413
151k
    }
414
415
151k
    inc_128(ctr);
416
417
151k
    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
151k
    memset(out, 0, outlen);
426
427
151k
    do {
428
151k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
429
151k
                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
151k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
440
151k
        blocks = (buflen + 15) / 16;
441
442
151k
        ctr32 = GETU32(ctr->V + 12) + blocks;
443
151k
        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
151k
        PUTU32(ctr->V + 12, ctr32);
453
454
151k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
455
151k
            || outl != buflen)
456
0
            return 0;
457
458
151k
        out += buflen;
459
151k
        outlen -= buflen;
460
151k
    } while (outlen);
461
462
151k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
463
0
        return 0;
464
151k
    return 1;
465
151k
}
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
151k
{
471
151k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
472
473
151k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
474
151k
        prediction_resistance, adin, adin_len);
475
151k
}
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
330
{
530
330
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
531
330
    int res = 1;
532
533
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
534
330
    drbg->max_request = 1 << 16;
535
330
    if (ctr->use_df) {
536
330
        drbg->min_entropylen = 0;
537
330
        drbg->max_entropylen = DRBG_MAX_LENGTH;
538
330
        drbg->min_noncelen = 0;
539
330
        drbg->max_noncelen = DRBG_MAX_LENGTH;
540
330
        drbg->max_perslen = DRBG_MAX_LENGTH;
541
330
        drbg->max_adinlen = DRBG_MAX_LENGTH;
542
543
330
        if (ctr->keylen > 0) {
544
68
            drbg->min_entropylen = ctr->keylen;
545
68
            drbg->min_noncelen = drbg->min_entropylen / 2;
546
68
        }
547
330
    } 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
330
    return res;
559
330
}
560
561
static int drbg_ctr_init(PROV_DRBG *drbg)
562
68
{
563
68
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
564
68
    size_t keylen;
565
566
68
    if (ctr->cipher_ctr == NULL) {
567
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
568
0
        return 0;
569
0
    }
570
68
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
571
68
    if (ctr->ctx_ecb == NULL)
572
68
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
573
68
    if (ctr->ctx_ctr == NULL)
574
68
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
575
68
    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
68
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
581
68
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
582
68
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
583
68
            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
68
    drbg->strength = keylen * 8;
589
68
    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
68
    if (ctr->use_df) {
604
        /* df initialisation */
605
68
        static const unsigned char df_key[32] = {
606
68
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
607
68
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
608
68
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
609
68
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
610
68
        };
611
612
68
        if (ctr->ctx_df == NULL)
613
68
            ctr->ctx_df = EVP_CIPHER_CTX_new();
614
68
        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
68
        if (!EVP_CipherInit_ex(ctr->ctx_df,
620
68
                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
68
    }
625
68
    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
68
}
633
634
static int drbg_ctr_new(PROV_DRBG *drbg)
635
262
{
636
262
    PROV_DRBG_CTR *ctr;
637
638
262
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
639
262
    if (ctr == NULL)
640
0
        return 0;
641
642
262
    ctr->use_df = 1;
643
262
    drbg->data = ctr;
644
262
    OSSL_FIPS_IND_INIT(drbg)
645
262
    return drbg_ctr_init_lengths(drbg);
646
262
}
647
648
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
649
    const OSSL_DISPATCH *parent_dispatch)
650
262
{
651
262
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
652
262
        &drbg_ctr_new, &drbg_ctr_free,
653
262
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
654
262
        &drbg_ctr_reseed, &drbg_ctr_generate);
655
262
}
656
657
static void drbg_ctr_free(void *vdrbg)
658
219
{
659
219
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
660
219
    PROV_DRBG_CTR *ctr;
661
662
219
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
663
219
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
664
219
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
665
219
        EVP_CIPHER_CTX_free(ctr->ctx_df);
666
219
        EVP_CIPHER_free(ctr->cipher_ecb);
667
219
        EVP_CIPHER_free(ctr->cipher_ctr);
668
669
219
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
670
219
    }
671
219
    ossl_rand_drbg_free(drbg);
672
219
}
673
674
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
675
61.5k
{
676
61.5k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
677
61.5k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
678
61.5k
    OSSL_PARAM *p;
679
61.5k
    int ret = 0, complete = 0;
680
681
61.5k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
682
0
        return 0;
683
684
61.5k
    if (complete)
685
61.5k
        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
41
{
725
41
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
726
41
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
727
41
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
728
41
    const OSSL_PARAM *p;
729
41
    char *ecb;
730
41
    const char *propquery = NULL;
731
41
    int i, cipher_init = 0;
732
733
41
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
734
41
        && OSSL_PARAM_get_int(p, &i)) {
735
        /* FIPS errors out in the drbg_ctr_init() call later */
736
41
        ctr->use_df = i != 0;
737
41
        cipher_init = 1;
738
41
    }
739
740
41
    if ((p = OSSL_PARAM_locate_const(params,
741
41
             OSSL_DRBG_PARAM_PROPERTIES))
742
41
        != NULL) {
743
30
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
744
0
            return 0;
745
30
    }
746
747
41
#ifndef FIPS_MODULE
748
41
    propquery = "provider=default";
749
41
    if (p != NULL
750
30
        && p->data_type == OSSL_PARAM_UTF8_STRING)
751
30
        propquery = (const char *)p->data;
752
41
#endif
753
754
41
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
755
41
        const char *base = (const char *)p->data;
756
41
        size_t ctr_str_len = sizeof("CTR") - 1;
757
41
        size_t ecb_str_len = sizeof("ECB") - 1;
758
759
41
        if (p->data_type != OSSL_PARAM_UTF8_STRING
760
41
            || p->data_size < ctr_str_len) {
761
12
            return 0;
762
12
        }
763
29
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
764
18
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
765
18
            return 0;
766
18
        }
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
67
{
797
67
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
798
67
    int ret;
799
800
67
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
801
0
        return 0;
802
803
67
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
804
805
67
    if (drbg->lock != NULL)
806
0
        CRYPTO_THREAD_unlock(drbg->lock);
807
808
67
    return ret;
809
67
}
810
811
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
812
    ossl_unused void *provctx)
813
262
{
814
262
    static const OSSL_PARAM known_settable_ctx_params[] = {
815
262
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
816
262
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
817
262
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
818
262
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
819
        OSSL_PARAM_END
820
262
    };
821
262
    return known_settable_ctx_params;
822
262
}
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
};