Coverage Report

Created: 2025-12-31 06:58

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