Coverage Report

Created: 2025-06-13 06:58

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