Coverage Report

Created: 2025-08-11 07:04

/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
152k
{
61
152k
    unsigned char *p = &ctr->V[0];
62
152k
    u32 n = 16, c = 1;
63
64
2.43M
    do {
65
2.43M
        --n;
66
2.43M
        c += p[n];
67
2.43M
        p[n] = (u8)c;
68
2.43M
        c >>= 8;
69
2.43M
    } while (n);
70
152k
}
71
72
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
73
46.1k
{
74
46.1k
    size_t i, n;
75
76
46.1k
    if (in == NULL || inlen == 0)
77
46.0k
        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
115
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
84
115
    if (!ossl_assert(n <= sizeof(ctr->K)))
85
0
        return;
86
3.78k
    for (i = 0; i < n; i++)
87
3.67k
        ctr->K[i] ^= in[i];
88
115
    if (inlen <= ctr->keylen)
89
2
        return;
90
91
113
    n = inlen - ctr->keylen;
92
113
    if (n > 16) {
93
        /* Should never happen */
94
0
        n = 16;
95
0
    }
96
1.92k
    for (i = 0; i < n; i++)
97
1.80k
        ctr->V[i] ^= in[i + ctr->keylen];
98
113
}
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
344
{
106
344
    int i, outlen = AES_BLOCK_SIZE;
107
108
16.8k
    for (i = 0; i < len; i++)
109
16.5k
        out[i] ^= in[i];
110
111
344
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
112
344
        || outlen != len)
113
0
        return 0;
114
344
    return 1;
115
344
}
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
269
{
123
269
    unsigned char in_tmp[48];
124
269
    unsigned char num_of_blk = 2;
125
126
269
    memcpy(in_tmp, in, 16);
127
269
    memcpy(in_tmp + 16, in, 16);
128
269
    if (ctr->keylen != 16) {
129
269
        memcpy(in_tmp + 32, in, 16);
130
269
        num_of_blk = 3;
131
269
    }
132
269
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
133
269
}
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
75
{
141
75
    unsigned char bltmp[48] = {0};
142
75
    unsigned char num_of_blk;
143
144
75
    memset(ctr->KX, 0, 48);
145
75
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
146
75
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
147
75
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
148
75
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
149
75
}
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
300
{
157
300
    if (in == NULL || inlen == 0)
158
124
        return 1;
159
160
    /* If we have partial block handle it first */
161
176
    if (ctr->bltmp_pos) {
162
142
        size_t left = 16 - ctr->bltmp_pos;
163
164
        /* If we now have a complete block process it */
165
142
        if (inlen >= left) {
166
101
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
167
101
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
168
0
                return 0;
169
101
            ctr->bltmp_pos = 0;
170
101
            inlen -= left;
171
101
            in += left;
172
101
        }
173
142
    }
174
175
    /* Process zero or more complete blocks */
176
269
    for (; inlen >= 16; in += 16, inlen -= 16) {
177
93
        if (!ctr_BCC_blocks(ctr, in))
178
0
            return 0;
179
93
    }
180
181
    /* Copy any remaining partial block to the temporary buffer */
182
176
    if (inlen > 0) {
183
142
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
184
142
        ctr->bltmp_pos += inlen;
185
142
    }
186
176
    return 1;
187
176
}
188
189
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
190
75
{
191
75
    if (ctr->bltmp_pos) {
192
75
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
193
75
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
194
0
            return 0;
195
75
    }
196
75
    return 1;
197
75
}
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
75
{
204
75
    static unsigned char c80 = 0x80;
205
75
    size_t inlen;
206
75
    unsigned char *p = ctr->bltmp;
207
75
    int outlen = AES_BLOCK_SIZE;
208
209
75
    if (!ctr_BCC_init(ctr))
210
0
        return 0;
211
75
    if (in1 == NULL)
212
0
        in1len = 0;
213
75
    if (in2 == NULL)
214
75
        in2len = 0;
215
75
    if (in3 == NULL)
216
49
        in3len = 0;
217
75
    inlen = in1len + in2len + in3len;
218
    /* Initialise L||N in temporary block */
219
75
    *p++ = (inlen >> 24) & 0xff;
220
75
    *p++ = (inlen >> 16) & 0xff;
221
75
    *p++ = (inlen >> 8) & 0xff;
222
75
    *p++ = inlen & 0xff;
223
224
    /* NB keylen is at most 32 bytes */
225
75
    *p++ = 0;
226
75
    *p++ = 0;
227
75
    *p++ = 0;
228
75
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
229
75
    ctr->bltmp_pos = 8;
230
75
    if (!ctr_BCC_update(ctr, in1, in1len)
231
75
        || !ctr_BCC_update(ctr, in2, in2len)
232
75
        || !ctr_BCC_update(ctr, in3, in3len)
233
75
        || !ctr_BCC_update(ctr, &c80, 1)
234
75
        || !ctr_BCC_final(ctr))
235
0
        return 0;
236
    /* Set up key K */
237
75
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
238
0
        return 0;
239
    /* X follows key K */
240
75
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
241
75
                          AES_BLOCK_SIZE)
242
75
        || outlen != AES_BLOCK_SIZE)
243
0
        return 0;
244
75
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
245
75
                          AES_BLOCK_SIZE)
246
75
        || outlen != AES_BLOCK_SIZE)
247
0
        return 0;
248
75
    if (ctr->keylen != 16)
249
75
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
250
75
                              ctr->KX + 16, AES_BLOCK_SIZE)
251
75
            || outlen != AES_BLOCK_SIZE)
252
0
            return 0;
253
75
    return 1;
254
75
}
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
50.7k
{
267
50.7k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
268
50.7k
    int outlen = AES_BLOCK_SIZE;
269
50.7k
    unsigned char V_tmp[48], out[48];
270
50.7k
    unsigned char len;
271
272
    /* correct key is already set up. */
273
50.7k
    memcpy(V_tmp, ctr->V, 16);
274
50.7k
    inc_128(ctr);
275
50.7k
    memcpy(V_tmp + 16, ctr->V, 16);
276
50.7k
    if (ctr->keylen == 16) {
277
0
        len = 32;
278
50.7k
    } else {
279
50.7k
        inc_128(ctr);
280
50.7k
        memcpy(V_tmp + 32, ctr->V, 16);
281
50.7k
        len = 48;
282
50.7k
    }
283
50.7k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
284
50.7k
            || outlen != len)
285
0
        return 0;
286
50.7k
    memcpy(ctr->K, out, ctr->keylen);
287
50.7k
    memcpy(ctr->V, out + ctr->keylen, 16);
288
289
50.7k
    if (ctr->use_df) {
290
        /* If no input reuse existing derived value */
291
27.7k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
292
75
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
293
0
                return 0;
294
        /* If this a reuse input in1len != 0 */
295
27.7k
        if (in1len)
296
109
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
297
27.7k
    } else {
298
23.0k
        ctr_XOR(ctr, in1, in1len);
299
23.0k
        ctr_XOR(ctr, in2, in2len);
300
23.0k
    }
301
302
50.7k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
303
50.7k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
304
0
        return 0;
305
50.7k
    return 1;
306
50.7k
}
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
28
{
313
28
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
314
315
28
    if (entropy == NULL)
316
0
        return 0;
317
318
28
    memset(ctr->K, 0, sizeof(ctr->K));
319
28
    memset(ctr->V, 0, sizeof(ctr->V));
320
28
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
321
0
        return 0;
322
323
28
    inc_128(ctr);
324
28
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
325
0
        return 0;
326
28
    return 1;
327
28
}
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
17
{
347
17
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
348
349
17
    if (entropy == NULL)
350
0
        return 0;
351
352
17
    inc_128(ctr);
353
17
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
354
0
        return 0;
355
17
    return 1;
356
17
}
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
50.6k
{
384
50.6k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
385
50.6k
    unsigned int ctr32, blocks;
386
50.6k
    int outl, buflen;
387
388
50.6k
    if (adin != NULL && adinlen != 0) {
389
34
        inc_128(ctr);
390
391
34
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
392
0
            return 0;
393
        /* This means we reuse derived value */
394
34
        if (ctr->use_df) {
395
34
            adin = NULL;
396
34
            adinlen = 1;
397
34
        }
398
50.6k
    } else {
399
50.6k
        adinlen = 0;
400
50.6k
    }
401
402
50.6k
    inc_128(ctr);
403
404
50.6k
    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
50.6k
    memset(out, 0, outlen);
413
414
50.6k
    do {
415
50.6k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
416
50.6k
                               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
50.6k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
427
50.6k
        blocks = (buflen + 15) / 16;
428
429
50.6k
        ctr32 = GETU32(ctr->V + 12) + blocks;
430
50.6k
        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
50.6k
        PUTU32(ctr->V + 12, ctr32);
440
441
50.6k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
442
50.6k
            || outl != buflen)
443
0
            return 0;
444
445
50.6k
        out += buflen;
446
50.6k
        outlen -= buflen;
447
50.6k
    } while (outlen);
448
449
50.6k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
450
0
        return 0;
451
50.6k
    return 1;
452
50.6k
}
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
50.6k
{
459
50.6k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
460
461
50.6k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
462
50.6k
                                   prediction_resistance, adin, adin_len);
463
50.6k
}
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
146
{
498
146
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
499
146
    int res = 1;
500
501
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
502
146
    drbg->max_request = 1 << 16;
503
146
    if (ctr->use_df) {
504
144
        drbg->min_entropylen = 0;
505
144
        drbg->max_entropylen = DRBG_MAX_LENGTH;
506
144
        drbg->min_noncelen = 0;
507
144
        drbg->max_noncelen = DRBG_MAX_LENGTH;
508
144
        drbg->max_perslen = DRBG_MAX_LENGTH;
509
144
        drbg->max_adinlen = DRBG_MAX_LENGTH;
510
511
144
        if (ctr->keylen > 0) {
512
26
            drbg->min_entropylen = ctr->keylen;
513
26
            drbg->min_noncelen = drbg->min_entropylen / 2;
514
26
        }
515
144
    } 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
146
    return res;
527
146
}
528
529
static int drbg_ctr_init(PROV_DRBG *drbg)
530
28
{
531
28
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
532
28
    size_t keylen;
533
534
28
    if (ctr->cipher_ctr == NULL) {
535
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
536
0
        return 0;
537
0
    }
538
28
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
539
28
    if (ctr->ctx_ecb == NULL)
540
28
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
541
28
    if (ctr->ctx_ctr == NULL)
542
28
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
543
28
    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
28
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
549
28
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
550
28
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
551
28
                              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
28
    drbg->strength = keylen * 8;
557
28
    drbg->seedlen = keylen + 16;
558
559
28
    if (ctr->use_df) {
560
        /* df initialisation */
561
26
        static const unsigned char df_key[32] = {
562
26
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
563
26
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
564
26
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
565
26
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
566
26
        };
567
568
26
        if (ctr->ctx_df == NULL)
569
26
            ctr->ctx_df = EVP_CIPHER_CTX_new();
570
26
        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
26
        if (!EVP_CipherInit_ex(ctr->ctx_df,
576
26
                               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
26
    }
581
28
    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
28
}
589
590
static int drbg_ctr_new(PROV_DRBG *drbg)
591
118
{
592
118
    PROV_DRBG_CTR *ctr;
593
594
118
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
595
118
    if (ctr == NULL) {
596
0
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
597
0
        return 0;
598
0
    }
599
600
118
    ctr->use_df = 1;
601
118
    drbg->data = ctr;
602
118
    return drbg_ctr_init_lengths(drbg);
603
118
}
604
605
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
606
                                   const OSSL_DISPATCH *parent_dispatch)
607
118
{
608
118
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
609
118
                              &drbg_ctr_new, &drbg_ctr_free,
610
118
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
611
118
                              &drbg_ctr_reseed, &drbg_ctr_generate);
612
118
}
613
614
static void drbg_ctr_free(void *vdrbg)
615
117
{
616
117
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
617
117
    PROV_DRBG_CTR *ctr;
618
619
117
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
620
117
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
621
117
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
622
117
        EVP_CIPHER_CTX_free(ctr->ctx_df);
623
117
        EVP_CIPHER_free(ctr->cipher_ecb);
624
117
        EVP_CIPHER_free(ctr->cipher_ctr);
625
626
117
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
627
117
    }
628
117
    ossl_rand_drbg_free(drbg);
629
117
}
630
631
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
632
22.0k
{
633
22.0k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
634
22.0k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
635
22.0k
    OSSL_PARAM *p;
636
637
22.0k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
638
22.0k
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
639
0
        return 0;
640
641
22.0k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
642
22.0k
    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
22.0k
    return ossl_drbg_get_ctx_params(drbg, params);
650
22.0k
}
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
116
{
726
116
    static const OSSL_PARAM known_settable_ctx_params[] = {
727
116
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
728
116
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
729
116
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
730
116
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
731
116
        OSSL_PARAM_END
732
116
    };
733
116
    return known_settable_ctx_params;
734
116
}
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
};