Coverage Report

Created: 2026-09-12 06:55

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