Coverage Report

Created: 2025-08-28 07:07

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