Coverage Report

Created: 2025-10-28 06:56

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