Coverage Report

Created: 2026-04-01 06:39

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
490k
{
66
490k
    unsigned char *p = &ctr->V[0];
67
490k
    u32 n = 16, c = 1;
68
69
7.85M
    do {
70
7.85M
        --n;
71
7.85M
        c += p[n];
72
7.85M
        p[n] = (u8)c;
73
7.85M
        c >>= 8;
74
7.85M
    } while (n);
75
490k
}
76
77
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
78
65.3k
{
79
65.3k
    size_t i, n;
80
81
65.3k
    if (in == NULL || inlen == 0)
82
65.1k
        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
163k
{
271
163k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
272
163k
    int outlen = AES_BLOCK_SIZE;
273
163k
    unsigned char V_tmp[48], out[48];
274
163k
    unsigned char len;
275
276
    /* correct key is already set up. */
277
163k
    memcpy(V_tmp, ctr->V, 16);
278
163k
    inc_128(ctr);
279
163k
    memcpy(V_tmp + 16, ctr->V, 16);
280
163k
    if (ctr->keylen == 16) {
281
0
        len = 32;
282
163k
    } else {
283
163k
        inc_128(ctr);
284
163k
        memcpy(V_tmp + 32, ctr->V, 16);
285
163k
        len = 48;
286
163k
    }
287
163k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
288
163k
        || outlen != len)
289
0
        return 0;
290
163k
    memcpy(ctr->K, out, ctr->keylen);
291
163k
    memcpy(ctr->V, out + ctr->keylen, 16);
292
293
163k
    if (ctr->use_df) {
294
        /* If no input reuse existing derived value */
295
131k
        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
131k
        if (in1len)
300
178
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
301
131k
    } else {
302
32.5k
        ctr_XOR(ctr, in1, in1len);
303
32.5k
        ctr_XOR(ctr, in2, in2len);
304
32.5k
    }
305
306
163k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
307
163k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
308
0
        return 0;
309
163k
    return 1;
310
163k
}
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
163k
{
397
163k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
398
163k
    unsigned int ctr32, blocks;
399
163k
    int outl, buflen;
400
401
163k
    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
163k
    } else {
412
163k
        adinlen = 0;
413
163k
    }
414
415
163k
    inc_128(ctr);
416
417
163k
    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
163k
    memset(out, 0, outlen);
426
427
163k
    do {
428
163k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
429
163k
                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
163k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
440
163k
        blocks = (buflen + 15) / 16;
441
442
163k
        ctr32 = GETU32(ctr->V + 12) + blocks;
443
163k
        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
163k
        PUTU32(ctr->V + 12, ctr32);
453
454
163k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
455
163k
            || outl != buflen)
456
0
            return 0;
457
458
163k
        out += buflen;
459
163k
        outlen -= buflen;
460
163k
    } while (outlen);
461
462
163k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
463
0
        return 0;
464
163k
    return 1;
465
163k
}
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
163k
{
471
163k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
472
473
163k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
474
163k
        prediction_resistance, adin, adin_len);
475
163k
}
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
199
{
530
199
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
531
199
    int res = 1;
532
533
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
534
199
    drbg->max_request = 1 << 16;
535
199
    if (ctr->use_df) {
536
198
        drbg->min_entropylen = 0;
537
198
        drbg->max_entropylen = DRBG_MAX_LENGTH;
538
198
        drbg->min_noncelen = 0;
539
198
        drbg->max_noncelen = DRBG_MAX_LENGTH;
540
198
        drbg->max_perslen = DRBG_MAX_LENGTH;
541
198
        drbg->max_adinlen = DRBG_MAX_LENGTH;
542
543
198
        if (ctr->keylen > 0) {
544
44
            drbg->min_entropylen = ctr->keylen;
545
44
            drbg->min_noncelen = drbg->min_entropylen / 2;
546
44
        }
547
198
    } 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
199
    return res;
559
199
}
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
154
{
624
154
    PROV_DRBG_CTR *ctr;
625
626
154
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
627
154
    if (ctr == NULL)
628
0
        return 0;
629
630
154
    ctr->use_df = 1;
631
154
    drbg->data = ctr;
632
154
    OSSL_FIPS_IND_INIT(drbg)
633
154
    return drbg_ctr_init_lengths(drbg);
634
154
}
635
636
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
637
    const OSSL_DISPATCH *parent_dispatch)
638
154
{
639
154
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
640
154
        &drbg_ctr_new, &drbg_ctr_free,
641
154
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
642
154
        &drbg_ctr_reseed, &drbg_ctr_generate);
643
154
}
644
645
static void drbg_ctr_free(void *vdrbg)
646
138
{
647
138
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
648
138
    PROV_DRBG_CTR *ctr;
649
650
138
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
651
138
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
652
138
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
653
138
        EVP_CIPHER_CTX_free(ctr->ctx_df);
654
138
        EVP_CIPHER_free(ctr->cipher_ecb);
655
138
        EVP_CIPHER_free(ctr->cipher_ctr);
656
657
138
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
658
138
    }
659
138
    ossl_rand_drbg_free(drbg);
660
138
}
661
662
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
663
168k
{
664
168k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
665
168k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
666
168k
    OSSL_PARAM *p;
667
168k
    int ret = 0, complete = 0;
668
669
168k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
670
0
        return 0;
671
672
168k
    if (complete)
673
168k
        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
123
{
713
123
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
714
123
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
715
123
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
716
123
    OSSL_PROVIDER *prov = NULL;
717
123
    const OSSL_PARAM *p;
718
123
    char *ecb;
719
123
    const char *propquery = NULL;
720
123
    int i, cipher_init = 0;
721
722
123
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
723
123
        && OSSL_PARAM_get_int(p, &i)) {
724
        /* FIPS errors out in the drbg_ctr_init() call later */
725
123
        ctr->use_df = i != 0;
726
123
        cipher_init = 1;
727
123
    }
728
729
123
    if ((p = OSSL_PARAM_locate_const(params,
730
123
             OSSL_DRBG_PARAM_PROPERTIES))
731
123
        != NULL) {
732
86
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
733
0
            return 0;
734
86
        propquery = (const char *)p->data;
735
86
    }
736
737
123
    if ((p = OSSL_PARAM_locate_const(params,
738
123
             OSSL_PROV_PARAM_CORE_PROV_NAME))
739
123
        != NULL) {
740
92
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
741
0
            return 0;
742
92
        if ((prov = ossl_provider_find(libctx,
743
92
                 (const char *)p->data, 1))
744
92
            == NULL)
745
46
            return 0;
746
92
    }
747
748
77
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
749
77
        const char *base = (const char *)p->data;
750
77
        size_t ctr_str_len = sizeof("CTR") - 1;
751
77
        size_t ecb_str_len = sizeof("ECB") - 1;
752
753
77
        if (p->data_type != OSSL_PARAM_UTF8_STRING
754
77
            || p->data_size < ctr_str_len) {
755
17
            ossl_provider_free(prov);
756
17
            return 0;
757
17
        }
758
60
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
759
23
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
760
23
            ossl_provider_free(prov);
761
23
            return 0;
762
23
        }
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
54
{
808
54
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
809
54
    int ret;
810
811
54
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
812
0
        return 0;
813
814
54
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
815
816
54
    if (drbg->lock != NULL)
817
0
        CRYPTO_THREAD_unlock(drbg->lock);
818
819
54
    return ret;
820
54
}
821
822
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
823
    ossl_unused void *provctx)
824
152
{
825
152
    static const OSSL_PARAM known_settable_ctx_params[] = {
826
152
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
827
152
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
828
152
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
829
152
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
830
        OSSL_PARAM_END
831
152
    };
832
152
    return known_settable_ctx_params;
833
152
}
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
};