Coverage Report

Created: 2025-04-22 06:18

/src/openssl/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
39.8k
{
60
39.8k
    unsigned char *p = &ctr->V[0];
61
39.8k
    u32 n = 16, c = 1;
62
63
637k
    do {
64
637k
        --n;
65
637k
        c += p[n];
66
637k
        p[n] = (u8)c;
67
637k
        c >>= 8;
68
637k
    } while (n);
69
39.8k
}
70
71
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
72
42
{
73
42
    size_t i, n;
74
75
42
    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
42
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
83
1.38k
    for (i = 0; i < n; i++)
84
1.34k
        ctr->K[i] ^= in[i];
85
42
    if (inlen <= ctr->keylen)
86
0
        return;
87
88
42
    n = inlen - ctr->keylen;
89
42
    if (n > 16) {
90
        /* Should never happen */
91
0
        n = 16;
92
0
    }
93
714
    for (i = 0; i < n; i++)
94
672
        ctr->V[i] ^= in[i + ctr->keylen];
95
42
}
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
144
{
103
144
    int i, outlen = AES_BLOCK_SIZE;
104
105
7.05k
    for (i = 0; i < len; i++)
106
6.91k
        out[i] ^= in[i];
107
108
144
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
109
144
        || outlen != len)
110
0
        return 0;
111
144
    return 1;
112
144
}
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
114
{
120
114
    unsigned char in_tmp[48];
121
114
    unsigned char num_of_blk = 2;
122
123
114
    memcpy(in_tmp, in, 16);
124
114
    memcpy(in_tmp + 16, in, 16);
125
114
    if (ctr->keylen != 16) {
126
114
        memcpy(in_tmp + 32, in, 16);
127
114
        num_of_blk = 3;
128
114
    }
129
114
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
130
114
}
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
30
{
138
30
    unsigned char bltmp[48] = {0};
139
30
    unsigned char num_of_blk;
140
141
30
    memset(ctr->KX, 0, 48);
142
30
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
143
30
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
144
30
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
145
30
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
146
30
}
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
120
{
154
120
    if (in == NULL || inlen == 0)
155
48
        return 1;
156
157
    /* If we have partial block handle it first */
158
72
    if (ctr->bltmp_pos) {
159
60
        size_t left = 16 - ctr->bltmp_pos;
160
161
        /* If we now have a complete block process it */
162
60
        if (inlen >= left) {
163
42
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
164
42
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
165
0
                return 0;
166
42
            ctr->bltmp_pos = 0;
167
42
            inlen -= left;
168
42
            in += left;
169
42
        }
170
60
    }
171
172
    /* Process zero or more complete blocks */
173
114
    for (; inlen >= 16; in += 16, inlen -= 16) {
174
42
        if (!ctr_BCC_blocks(ctr, in))
175
0
            return 0;
176
42
    }
177
178
    /* Copy any remaining partial block to the temporary buffer */
179
72
    if (inlen > 0) {
180
60
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
181
60
        ctr->bltmp_pos += inlen;
182
60
    }
183
72
    return 1;
184
72
}
185
186
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
187
30
{
188
30
    if (ctr->bltmp_pos) {
189
30
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
190
30
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
191
0
            return 0;
192
30
    }
193
30
    return 1;
194
30
}
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
30
{
201
30
    static unsigned char c80 = 0x80;
202
30
    size_t inlen;
203
30
    unsigned char *p = ctr->bltmp;
204
30
    int outlen = AES_BLOCK_SIZE;
205
206
30
    if (!ctr_BCC_init(ctr))
207
0
        return 0;
208
30
    if (in1 == NULL)
209
0
        in1len = 0;
210
30
    if (in2 == NULL)
211
30
        in2len = 0;
212
30
    if (in3 == NULL)
213
18
        in3len = 0;
214
30
    inlen = in1len + in2len + in3len;
215
    /* Initialise L||N in temporary block */
216
30
    *p++ = (inlen >> 24) & 0xff;
217
30
    *p++ = (inlen >> 16) & 0xff;
218
30
    *p++ = (inlen >> 8) & 0xff;
219
30
    *p++ = inlen & 0xff;
220
221
    /* NB keylen is at most 32 bytes */
222
30
    *p++ = 0;
223
30
    *p++ = 0;
224
30
    *p++ = 0;
225
30
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
226
30
    ctr->bltmp_pos = 8;
227
30
    if (!ctr_BCC_update(ctr, in1, in1len)
228
30
        || !ctr_BCC_update(ctr, in2, in2len)
229
30
        || !ctr_BCC_update(ctr, in3, in3len)
230
30
        || !ctr_BCC_update(ctr, &c80, 1)
231
30
        || !ctr_BCC_final(ctr))
232
0
        return 0;
233
    /* Set up key K */
234
30
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
235
0
        return 0;
236
    /* X follows key K */
237
30
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
238
30
                          AES_BLOCK_SIZE)
239
30
        || outlen != AES_BLOCK_SIZE)
240
0
        return 0;
241
30
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
242
30
                          AES_BLOCK_SIZE)
243
30
        || outlen != AES_BLOCK_SIZE)
244
0
        return 0;
245
30
    if (ctr->keylen != 16)
246
30
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
247
30
                              ctr->KX + 16, AES_BLOCK_SIZE)
248
30
            || outlen != AES_BLOCK_SIZE)
249
0
            return 0;
250
30
    return 1;
251
30
}
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
13.2k
{
264
13.2k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
265
13.2k
    int outlen = AES_BLOCK_SIZE;
266
13.2k
    unsigned char V_tmp[48], out[48];
267
13.2k
    unsigned char len;
268
269
    /* correct key is already set up. */
270
13.2k
    memcpy(V_tmp, ctr->V, 16);
271
13.2k
    inc_128(ctr);
272
13.2k
    memcpy(V_tmp + 16, ctr->V, 16);
273
13.2k
    if (ctr->keylen == 16) {
274
0
        len = 32;
275
13.2k
    } else {
276
13.2k
        inc_128(ctr);
277
13.2k
        memcpy(V_tmp + 32, ctr->V, 16);
278
13.2k
        len = 48;
279
13.2k
    }
280
13.2k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
281
13.2k
            || outlen != len)
282
0
        return 0;
283
13.2k
    memcpy(ctr->K, out, ctr->keylen);
284
13.2k
    memcpy(ctr->V, out + ctr->keylen, 16);
285
286
13.2k
    if (ctr->use_df) {
287
        /* If no input reuse existing derived value */
288
13.2k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
289
30
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
290
0
                return 0;
291
        /* If this a reuse input in1len != 0 */
292
13.2k
        if (in1len)
293
42
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
294
13.2k
    } else {
295
0
        ctr_XOR(ctr, in1, in1len);
296
0
        ctr_XOR(ctr, in2, in2len);
297
0
    }
298
299
13.2k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
300
13.2k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
301
0
        return 0;
302
13.2k
    return 1;
303
13.2k
}
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
12
{
310
12
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
311
312
12
    if (entropy == NULL)
313
0
        return 0;
314
315
12
    memset(ctr->K, 0, sizeof(ctr->K));
316
12
    memset(ctr->V, 0, sizeof(ctr->V));
317
12
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
318
0
        return 0;
319
320
12
    inc_128(ctr);
321
12
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
322
0
        return 0;
323
12
    return 1;
324
12
}
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
12
{
332
12
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
333
334
12
    if (!ossl_prov_is_running() || !drbg_ctr_set_ctx_params(drbg, params))
335
0
        return 0;
336
12
    return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
337
12
                                      pstr, pstr_len);
338
12
}
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
6
{
344
6
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
345
346
6
    if (entropy == NULL)
347
0
        return 0;
348
349
6
    inc_128(ctr);
350
6
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
351
0
        return 0;
352
6
    return 1;
353
6
}
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
13.2k
{
381
13.2k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
382
13.2k
    unsigned int ctr32, blocks;
383
13.2k
    int outl, buflen;
384
385
13.2k
    if (adin != NULL && adinlen != 0) {
386
12
        inc_128(ctr);
387
388
12
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
389
0
            return 0;
390
        /* This means we reuse derived value */
391
12
        if (ctr->use_df) {
392
12
            adin = NULL;
393
12
            adinlen = 1;
394
12
        }
395
13.2k
    } else {
396
13.2k
        adinlen = 0;
397
13.2k
    }
398
399
13.2k
    inc_128(ctr);
400
401
13.2k
    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
13.2k
    memset(out, 0, outlen);
410
411
13.2k
    do {
412
13.2k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
413
13.2k
                               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
13.2k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
424
13.2k
        blocks = (buflen + 15) / 16;
425
426
13.2k
        ctr32 = GETU32(ctr->V + 12) + blocks;
427
13.2k
        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
13.2k
        PUTU32(ctr->V + 12, ctr32);
437
438
13.2k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
439
13.2k
            || outl != buflen)
440
0
            return 0;
441
442
13.2k
        out += buflen;
443
13.2k
        outlen -= buflen;
444
13.2k
    } while (outlen);
445
446
13.2k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
447
0
        return 0;
448
13.2k
    return 1;
449
13.2k
}
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
13.2k
{
456
13.2k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
457
458
13.2k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
459
13.2k
                                   prediction_resistance, adin, adin_len);
460
13.2k
}
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
24
{
495
24
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
496
24
    int res = 1;
497
498
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
499
24
    drbg->max_request = 1 << 16;
500
24
    if (ctr->use_df) {
501
24
        drbg->min_entropylen = 0;
502
24
        drbg->max_entropylen = DRBG_MAX_LENGTH;
503
24
        drbg->min_noncelen = 0;
504
24
        drbg->max_noncelen = DRBG_MAX_LENGTH;
505
24
        drbg->max_perslen = DRBG_MAX_LENGTH;
506
24
        drbg->max_adinlen = DRBG_MAX_LENGTH;
507
508
24
        if (ctr->keylen > 0) {
509
12
            drbg->min_entropylen = ctr->keylen;
510
12
            drbg->min_noncelen = drbg->min_entropylen / 2;
511
12
        }
512
24
    } else {
513
0
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
514
515
0
        drbg->min_entropylen = len;
516
0
        drbg->max_entropylen = len;
517
        /* Nonce not used */
518
0
        drbg->min_noncelen = 0;
519
0
        drbg->max_noncelen = 0;
520
0
        drbg->max_perslen = len;
521
0
        drbg->max_adinlen = len;
522
0
    }
523
24
    return res;
524
24
}
525
526
static int drbg_ctr_init(PROV_DRBG *drbg)
527
12
{
528
12
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
529
12
    size_t keylen;
530
531
12
    if (ctr->cipher_ctr == NULL) {
532
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
533
0
        return 0;
534
0
    }
535
12
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
536
12
    if (ctr->ctx_ecb == NULL)
537
12
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
538
12
    if (ctr->ctx_ctr == NULL)
539
12
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
540
12
    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
12
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
546
12
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
547
12
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
548
12
                              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
12
    drbg->strength = keylen * 8;
554
12
    drbg->seedlen = keylen + 16;
555
556
12
    if (ctr->use_df) {
557
        /* df initialisation */
558
12
        static const unsigned char df_key[32] = {
559
12
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
560
12
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
561
12
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
562
12
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
563
12
        };
564
565
12
        if (ctr->ctx_df == NULL)
566
12
            ctr->ctx_df = EVP_CIPHER_CTX_new();
567
12
        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
12
        if (!EVP_CipherInit_ex(ctr->ctx_df,
573
12
                               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
12
    }
578
12
    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
12
}
586
587
static int drbg_ctr_new(PROV_DRBG *drbg)
588
12
{
589
12
    PROV_DRBG_CTR *ctr;
590
591
12
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
592
12
    if (ctr == NULL) {
593
0
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
594
0
        return 0;
595
0
    }
596
597
12
    ctr->use_df = 1;
598
12
    drbg->data = ctr;
599
12
    return drbg_ctr_init_lengths(drbg);
600
12
}
601
602
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
603
                                   const OSSL_DISPATCH *parent_dispatch)
604
12
{
605
12
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
606
12
                              &drbg_ctr_new, &drbg_ctr_free,
607
12
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
608
12
                              &drbg_ctr_reseed, &drbg_ctr_generate);
609
12
}
610
611
static void drbg_ctr_free(void *vdrbg)
612
12
{
613
12
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
614
12
    PROV_DRBG_CTR *ctr;
615
616
12
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
617
12
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
618
12
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
619
12
        EVP_CIPHER_CTX_free(ctr->ctx_df);
620
12
        EVP_CIPHER_free(ctr->cipher_ecb);
621
12
        EVP_CIPHER_free(ctr->cipher_ctr);
622
623
12
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
624
12
    }
625
12
    ossl_rand_drbg_free(drbg);
626
12
}
627
628
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
629
26.5k
{
630
26.5k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
631
26.5k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
632
26.5k
    OSSL_PARAM *p;
633
634
26.5k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
635
26.5k
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
636
0
        return 0;
637
638
26.5k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
639
26.5k
    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
26.5k
    return ossl_drbg_get_ctx_params(drbg, params);
647
26.5k
}
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
12
{
663
12
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
664
12
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
665
12
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
666
12
    const OSSL_PARAM *p;
667
12
    char *ecb;
668
12
    const char *propquery = NULL;
669
12
    int i, cipher_init = 0;
670
671
12
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
672
12
            && 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
12
    if ((p = OSSL_PARAM_locate_const(params,
679
12
                                     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
12
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
686
12
        const char *base = (const char *)p->data;
687
12
        size_t ctr_str_len = sizeof("CTR") - 1;
688
12
        size_t ecb_str_len = sizeof("ECB") - 1;
689
690
12
        if (p->data_type != OSSL_PARAM_UTF8_STRING
691
12
                || p->data_size < ctr_str_len)
692
0
            return 0;
693
12
        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
12
        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
12
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
702
12
        EVP_CIPHER_free(ctr->cipher_ecb);
703
12
        EVP_CIPHER_free(ctr->cipher_ctr);
704
12
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
705
12
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
706
12
        OPENSSL_free(ecb);
707
12
        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
12
        cipher_init = 1;
712
12
    }
713
714
12
    if (cipher_init && !drbg_ctr_init(ctx))
715
0
        return 0;
716
717
12
    return ossl_drbg_set_ctx_params(ctx, params);
718
12
}
719
720
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
721
                                                      ossl_unused void *provctx)
722
0
{
723
0
    static const OSSL_PARAM known_settable_ctx_params[] = {
724
0
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
725
0
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
726
0
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
727
0
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
728
0
        OSSL_PARAM_END
729
0
    };
730
0
    return known_settable_ctx_params;
731
0
}
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
};