Coverage Report

Created: 2025-06-13 06:58

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