Coverage Report

Created: 2025-12-04 06:33

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