Coverage Report

Created: 2025-12-31 06:58

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