Coverage Report

Created: 2025-08-11 07:04

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