Coverage Report

Created: 2026-08-17 07:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/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
528
{
73
528
    unsigned char *p = &ctr->V[0];
74
528
    uint32_t n = 16, c = 1;
75
76
8.44k
    do {
77
8.44k
        --n;
78
8.44k
        c += p[n];
79
8.44k
        p[n] = (uint8_t)c;
80
8.44k
        c >>= 8;
81
8.44k
    } while (n);
82
528
}
83
84
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
85
144
{
86
144
    size_t i, n;
87
88
144
    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
144
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
96
144
    if (!ossl_assert(n <= sizeof(ctr->K)))
97
0
        return;
98
4.75k
    for (i = 0; i < n; i++)
99
4.60k
        ctr->K[i] ^= in[i];
100
144
    if (inlen <= ctr->keylen)
101
0
        return;
102
103
144
    n = inlen - ctr->keylen;
104
144
    if (n > 16) {
105
        /* Should never happen */
106
0
        n = 16;
107
0
    }
108
2.44k
    for (i = 0; i < n; i++)
109
2.30k
        ctr->V[i] ^= in[i + ctr->keylen];
110
144
}
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
560
{
118
560
    int i, outlen = AES_BLOCK_SIZE;
119
120
27.4k
    for (i = 0; i < len; i++)
121
26.8k
        out[i] ^= in[i];
122
123
560
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
124
560
        || outlen != len)
125
0
        return 0;
126
560
    return 1;
127
560
}
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
448
{
134
448
    unsigned char in_tmp[48];
135
448
    unsigned char num_of_blk = 2;
136
137
448
    memcpy(in_tmp, in, 16);
138
448
    memcpy(in_tmp + 16, in, 16);
139
448
    if (ctr->keylen != 16) {
140
448
        memcpy(in_tmp + 32, in, 16);
141
448
        num_of_blk = 3;
142
448
    }
143
448
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
144
448
}
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
112
{
152
112
    unsigned char bltmp[48] = { 0 };
153
112
    unsigned char num_of_blk;
154
155
112
    memset(ctr->KX, 0, 48);
156
112
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
157
112
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
158
112
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
159
112
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
160
112
}
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
448
{
168
448
    if (in == NULL || inlen == 0)
169
160
        return 1;
170
171
    /* If we have partial block handle it first */
172
288
    if (ctr->bltmp_pos) {
173
240
        size_t left = 16 - ctr->bltmp_pos;
174
175
        /* If we now have a complete block process it */
176
240
        if (inlen >= left) {
177
176
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
178
176
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
179
0
                return 0;
180
176
            ctr->bltmp_pos = 0;
181
176
            inlen -= left;
182
176
            in += left;
183
176
        }
184
240
    }
185
186
    /* Process zero or more complete blocks */
187
448
    for (; inlen >= 16; in += 16, inlen -= 16) {
188
160
        if (!ctr_BCC_blocks(ctr, in))
189
0
            return 0;
190
160
    }
191
192
    /* Copy any remaining partial block to the temporary buffer */
193
288
    if (inlen > 0) {
194
240
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
195
240
        ctr->bltmp_pos += inlen;
196
240
    }
197
288
    return 1;
198
288
}
199
200
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
201
112
{
202
112
    if (ctr->bltmp_pos) {
203
112
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
204
112
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
205
0
            return 0;
206
112
    }
207
112
    return 1;
208
112
}
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
112
{
215
112
    static unsigned char c80 = 0x80;
216
112
    size_t inlen;
217
112
    unsigned char *p = ctr->bltmp;
218
112
    int outlen = AES_BLOCK_SIZE;
219
220
112
    if (!ctr_BCC_init(ctr))
221
0
        return 0;
222
112
    if (in1 == NULL)
223
0
        in1len = 0;
224
112
    if (in2 == NULL)
225
112
        in2len = 0;
226
112
    if (in3 == NULL)
227
48
        in3len = 0;
228
112
    inlen = in1len + in2len + in3len;
229
    /* Initialise L||N in temporary block */
230
112
    *p++ = (inlen >> 24) & 0xff;
231
112
    *p++ = (inlen >> 16) & 0xff;
232
112
    *p++ = (inlen >> 8) & 0xff;
233
112
    *p++ = inlen & 0xff;
234
235
    /* NB keylen is at most 32 bytes */
236
112
    *p++ = 0;
237
112
    *p++ = 0;
238
112
    *p++ = 0;
239
112
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
240
112
    ctr->bltmp_pos = 8;
241
112
    if (!ctr_BCC_update(ctr, in1, in1len)
242
112
        || !ctr_BCC_update(ctr, in2, in2len)
243
112
        || !ctr_BCC_update(ctr, in3, in3len)
244
112
        || !ctr_BCC_update(ctr, &c80, 1)
245
112
        || !ctr_BCC_final(ctr))
246
0
        return 0;
247
    /* Set up key K */
248
112
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
249
0
        return 0;
250
    /* X follows key K */
251
112
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
252
112
            AES_BLOCK_SIZE)
253
112
        || outlen != AES_BLOCK_SIZE)
254
0
        return 0;
255
112
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
256
112
            AES_BLOCK_SIZE)
257
112
        || outlen != AES_BLOCK_SIZE)
258
0
        return 0;
259
112
    if (ctr->keylen != 16)
260
112
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
261
112
                ctr->KX + 16, AES_BLOCK_SIZE)
262
112
            || outlen != AES_BLOCK_SIZE)
263
0
            return 0;
264
112
    return 1;
265
112
}
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
176
{
278
176
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
279
176
    int outlen = AES_BLOCK_SIZE;
280
176
    unsigned char V_tmp[48], out[48];
281
176
    unsigned char len;
282
283
    /* correct key is already set up. */
284
176
    memcpy(V_tmp, ctr->V, 16);
285
176
    inc_128(ctr);
286
176
    memcpy(V_tmp + 16, ctr->V, 16);
287
176
    if (ctr->keylen == 16) {
288
0
        len = 32;
289
176
    } else {
290
176
        inc_128(ctr);
291
176
        memcpy(V_tmp + 32, ctr->V, 16);
292
176
        len = 48;
293
176
    }
294
176
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
295
176
        || outlen != len)
296
0
        return 0;
297
176
    memcpy(ctr->K, out, ctr->keylen);
298
176
    memcpy(ctr->V, out + ctr->keylen, 16);
299
300
176
    if (ctr->use_df) {
301
        /* If no input reuse existing derived value */
302
176
        if (in1 != NULL || nonce != NULL || in2 != NULL)
303
112
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
304
0
                return 0;
305
        /* If this a reuse input in1len != 0 */
306
176
        if (in1len)
307
144
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
308
176
    } else {
309
0
        ctr_XOR(ctr, in1, in1len);
310
0
        ctr_XOR(ctr, in2, in2len);
311
0
    }
312
313
176
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
314
176
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
315
0
        return 0;
316
176
    return 1;
317
176
}
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
32
{
324
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
325
326
32
    if (entropy == NULL)
327
0
        return 0;
328
329
32
    memset(ctr->K, 0, sizeof(ctr->K));
330
32
    memset(ctr->V, 0, sizeof(ctr->V));
331
32
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
332
0
        return 0;
333
334
32
    inc_128(ctr);
335
32
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
336
0
        return 0;
337
32
    return 1;
338
32
}
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
32
{
346
32
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
347
32
    struct drbg_set_ctx_params_st p;
348
32
    int ret = 0;
349
350
32
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
351
0
        return 0;
352
353
32
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
354
0
        return 0;
355
356
32
    if (!ossl_prov_is_running()
357
32
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
358
0
        goto err;
359
32
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
360
32
        pstr, pstr_len);
361
32
err:
362
32
    if (drbg->lock != NULL)
363
0
        CRYPTO_THREAD_unlock(drbg->lock);
364
32
    return ret;
365
32
}
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
48
{
371
48
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
372
373
48
    if (entropy == NULL)
374
0
        return 0;
375
376
48
    inc_128(ctr);
377
48
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
378
0
        return 0;
379
48
    return 1;
380
48
}
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
32
{
386
32
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
387
388
32
    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
389
32
        adin, adin_len);
390
32
}
391
392
static void ctr96_inc(unsigned char *counter)
393
0
{
394
0
    uint32_t n = 12, c = 1;
395
396
0
    do {
397
0
        --n;
398
0
        c += counter[n];
399
0
        counter[n] = (uint8_t)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
64
{
408
64
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
409
64
    unsigned int ctr32, blocks;
410
64
    int outl, buflen;
411
412
64
    if (adin != NULL && adinlen != 0) {
413
32
        inc_128(ctr);
414
415
32
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
416
0
            return 0;
417
        /* This means we reuse derived value */
418
32
        if (ctr->use_df) {
419
32
            adin = NULL;
420
32
            adinlen = 1;
421
32
        }
422
32
    } else {
423
32
        adinlen = 0;
424
32
    }
425
426
64
    inc_128(ctr);
427
428
64
    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
64
    memset(out, 0, outlen);
437
438
64
    do {
439
64
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
440
64
                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
64
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
451
64
        blocks = (buflen + 15) / 16;
452
453
64
        ctr32 = GETU32(ctr->V + 12) + blocks;
454
64
        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
64
        PUTU32(ctr->V + 12, ctr32);
464
465
64
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
466
64
            || outl != buflen)
467
0
            return 0;
468
469
64
        out += buflen;
470
64
        outlen -= buflen;
471
64
    } while (outlen);
472
473
64
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
474
0
        return 0;
475
64
    return 1;
476
64
}
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
32
{
482
32
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
483
484
32
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
485
32
        prediction_resistance, adin, adin_len);
486
32
}
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
64
{
541
64
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
542
64
    int res = 1;
543
544
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
545
64
    drbg->max_request = 1 << 16;
546
64
    if (ctr->use_df) {
547
64
        drbg->min_entropylen = 0;
548
64
        drbg->max_entropylen = DRBG_MAX_LENGTH;
549
64
        drbg->min_noncelen = 0;
550
64
        drbg->max_noncelen = DRBG_MAX_LENGTH;
551
64
        drbg->max_perslen = DRBG_MAX_LENGTH;
552
64
        drbg->max_adinlen = DRBG_MAX_LENGTH;
553
554
64
        if (ctr->keylen > 0) {
555
32
            drbg->min_entropylen = ctr->keylen;
556
32
            drbg->min_noncelen = drbg->min_entropylen / 2;
557
32
        }
558
64
    } 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
64
    return res;
570
64
}
571
572
static int drbg_ctr_init(PROV_DRBG *drbg)
573
32
{
574
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
575
32
    size_t keylen;
576
577
32
    if (ctr->cipher_ctr == NULL) {
578
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
579
0
        return 0;
580
0
    }
581
32
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
582
32
    if (ctr->ctx_ecb == NULL)
583
32
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
584
32
    if (ctr->ctx_ctr == NULL)
585
32
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
586
32
    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
32
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
592
32
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
593
32
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
594
32
            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
32
    drbg->strength = (unsigned int)(keylen * 8);
600
32
    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
32
    if (ctr->use_df) {
615
        /* df initialisation */
616
32
        static const unsigned char df_key[32] = {
617
32
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
618
32
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
619
32
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
620
32
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
621
32
        };
622
623
32
        if (ctr->ctx_df == NULL)
624
32
            ctr->ctx_df = EVP_CIPHER_CTX_new();
625
32
        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
32
        if (!EVP_CipherInit_ex(ctr->ctx_df,
631
32
                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
32
    }
636
32
    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
32
}
644
645
static int drbg_ctr_new(PROV_DRBG *drbg)
646
32
{
647
32
    PROV_DRBG_CTR *ctr;
648
649
32
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
650
32
    if (ctr == NULL)
651
0
        return 0;
652
653
32
    ctr->use_df = 1;
654
32
    drbg->data = ctr;
655
32
    OSSL_FIPS_IND_INIT(drbg)
656
32
    return drbg_ctr_init_lengths(drbg);
657
32
}
658
659
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
660
    const OSSL_DISPATCH *parent_dispatch)
661
32
{
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
32
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
669
32
        &drbg_ctr_new, &drbg_ctr_free,
670
32
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
671
32
        &drbg_ctr_reseed, &drbg_ctr_generate);
672
32
}
673
674
static void drbg_ctr_free(void *vdrbg)
675
0
{
676
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
677
0
    PROV_DRBG_CTR *ctr;
678
679
0
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
680
0
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
681
0
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
682
0
        EVP_CIPHER_CTX_free(ctr->ctx_df);
683
0
        EVP_CIPHER_free(ctr->cipher_ecb);
684
0
        EVP_CIPHER_free(ctr->cipher_ctr);
685
686
0
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
687
0
    }
688
0
    ossl_rand_drbg_free(drbg);
689
0
}
690
691
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
692
144
{
693
144
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
694
144
    PROV_DRBG_CTR *ctr;
695
144
    struct drbg_ctr_get_ctx_params_st p;
696
144
    int ret = 0, complete = 0;
697
698
144
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
699
0
        return 0;
700
701
144
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
702
0
        return 0;
703
704
144
    if (complete)
705
80
        return 1;
706
707
64
    ctr = (PROV_DRBG_CTR *)drbg->data;
708
709
64
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
710
0
        return 0;
711
712
64
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
713
0
        goto err;
714
715
64
    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
64
    ret = ossl_drbg_get_ctx_params(drbg, &p);
723
64
err:
724
64
    if (drbg->lock != NULL)
725
64
        CRYPTO_THREAD_unlock(drbg->lock);
726
727
64
    return ret;
728
64
}
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
32
{
739
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
740
32
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
741
32
    char *ecb;
742
32
    const char *propquery = NULL;
743
32
    int i, cipher_init = 0;
744
745
32
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
746
        /* FIPS errors out in the drbg_ctr_init() call later */
747
32
        ctr->use_df = i != 0;
748
32
        cipher_init = 1;
749
32
    }
750
751
32
#ifndef FIPS_MODULE
752
32
    propquery = "provider=default";
753
32
    if (p->propq != NULL
754
0
        && p->propq->data_type == OSSL_PARAM_UTF8_STRING)
755
0
        propquery = (const char *)p->propq->data;
756
32
#endif
757
758
32
    if (p->cipher != NULL) {
759
32
        const char *base = (const char *)p->cipher->data;
760
32
        size_t ctr_str_len = sizeof("CTR") - 1;
761
32
        size_t ecb_str_len = sizeof("ECB") - 1;
762
763
32
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
764
32
            || p->cipher->data_size < ctr_str_len) {
765
0
            return 0;
766
0
        }
767
32
        if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) {
768
0
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
769
0
            return 0;
770
0
        }
771
32
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
772
0
            return 0;
773
0
        }
774
32
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
775
32
        EVP_CIPHER_free(ctr->cipher_ecb);
776
32
        EVP_CIPHER_free(ctr->cipher_ctr);
777
32
        ctr->cipher_ctr = NULL;
778
32
        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
32
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
784
32
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
785
32
        OPENSSL_free(ecb);
786
32
        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
32
        cipher_init = 1;
791
32
    }
792
793
32
    if (cipher_init && !drbg_ctr_init(ctx))
794
0
        return 0;
795
796
32
    return ossl_drbg_set_ctx_params(ctx, p);
797
32
}
798
799
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
800
0
{
801
0
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
802
0
    struct drbg_set_ctx_params_st p;
803
0
    int ret;
804
805
0
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
806
0
        return 0;
807
808
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
809
0
        return 0;
810
811
0
    ret = drbg_ctr_set_ctx_params_locked(drbg, &p);
812
813
0
    if (drbg->lock != NULL)
814
0
        CRYPTO_THREAD_unlock(drbg->lock);
815
816
0
    return ret;
817
0
}
818
819
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
820
    ossl_unused void *provctx)
821
32
{
822
32
    return drbg_ctr_set_ctx_params_list;
823
32
}
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
};