Coverage Report

Created: 2025-06-13 06:58

/src/openssl32/providers/implementations/rands/drbg_ctr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2011-2024 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
244k
{
63
244k
    unsigned char *p = &ctr->V[0];
64
244k
    u32 n = 16, c = 1;
65
66
3.91M
    do {
67
3.91M
        --n;
68
3.91M
        c += p[n];
69
3.91M
        p[n] = (u8)c;
70
3.91M
        c >>= 8;
71
3.91M
    } while (n);
72
244k
}
73
74
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
75
26.4k
{
76
26.4k
    size_t i, n;
77
78
26.4k
    if (in == NULL || inlen == 0)
79
26.3k
        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
61
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
86
61
    if (!ossl_assert(n <= sizeof(ctr->K)))
87
0
        return;
88
2.01k
    for (i = 0; i < n; i++)
89
1.94k
        ctr->K[i] ^= in[i];
90
61
    if (inlen <= ctr->keylen)
91
1
        return;
92
93
60
    n = inlen - ctr->keylen;
94
60
    if (n > 16) {
95
        /* Should never happen */
96
0
        n = 16;
97
0
    }
98
1.02k
    for (i = 0; i < n; i++)
99
960
        ctr->V[i] ^= in[i + ctr->keylen];
100
60
}
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
208
{
108
208
    int i, outlen = AES_BLOCK_SIZE;
109
110
10.1k
    for (i = 0; i < len; i++)
111
9.98k
        out[i] ^= in[i];
112
113
208
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
114
208
        || outlen != len)
115
0
        return 0;
116
208
    return 1;
117
208
}
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
163
{
125
163
    unsigned char in_tmp[48];
126
163
    unsigned char num_of_blk = 2;
127
128
163
    memcpy(in_tmp, in, 16);
129
163
    memcpy(in_tmp + 16, in, 16);
130
163
    if (ctr->keylen != 16) {
131
163
        memcpy(in_tmp + 32, in, 16);
132
163
        num_of_blk = 3;
133
163
    }
134
163
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
135
163
}
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
45
{
143
45
    unsigned char bltmp[48] = {0};
144
45
    unsigned char num_of_blk;
145
146
45
    memset(ctr->KX, 0, 48);
147
45
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
148
45
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
149
45
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
150
45
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
151
45
}
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
180
{
159
180
    if (in == NULL || inlen == 0)
160
74
        return 1;
161
162
    /* If we have partial block handle it first */
163
106
    if (ctr->bltmp_pos) {
164
86
        size_t left = 16 - ctr->bltmp_pos;
165
166
        /* If we now have a complete block process it */
167
86
        if (inlen >= left) {
168
61
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
169
61
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
170
0
                return 0;
171
61
            ctr->bltmp_pos = 0;
172
61
            inlen -= left;
173
61
            in += left;
174
61
        }
175
86
    }
176
177
    /* Process zero or more complete blocks */
178
163
    for (; inlen >= 16; in += 16, inlen -= 16) {
179
57
        if (!ctr_BCC_blocks(ctr, in))
180
0
            return 0;
181
57
    }
182
183
    /* Copy any remaining partial block to the temporary buffer */
184
106
    if (inlen > 0) {
185
86
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
186
86
        ctr->bltmp_pos += inlen;
187
86
    }
188
106
    return 1;
189
106
}
190
191
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
192
45
{
193
45
    if (ctr->bltmp_pos) {
194
45
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
195
45
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
196
0
            return 0;
197
45
    }
198
45
    return 1;
199
45
}
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
45
{
206
45
    static unsigned char c80 = 0x80;
207
45
    size_t inlen;
208
45
    unsigned char *p = ctr->bltmp;
209
45
    int outlen = AES_BLOCK_SIZE;
210
211
45
    if (!ctr_BCC_init(ctr))
212
0
        return 0;
213
45
    if (in1 == NULL)
214
0
        in1len = 0;
215
45
    if (in2 == NULL)
216
45
        in2len = 0;
217
45
    if (in3 == NULL)
218
29
        in3len = 0;
219
45
    inlen = in1len + in2len + in3len;
220
    /* Initialise L||N in temporary block */
221
45
    *p++ = (inlen >> 24) & 0xff;
222
45
    *p++ = (inlen >> 16) & 0xff;
223
45
    *p++ = (inlen >> 8) & 0xff;
224
45
    *p++ = inlen & 0xff;
225
226
    /* NB keylen is at most 32 bytes */
227
45
    *p++ = 0;
228
45
    *p++ = 0;
229
45
    *p++ = 0;
230
45
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
231
45
    ctr->bltmp_pos = 8;
232
45
    if (!ctr_BCC_update(ctr, in1, in1len)
233
45
        || !ctr_BCC_update(ctr, in2, in2len)
234
45
        || !ctr_BCC_update(ctr, in3, in3len)
235
45
        || !ctr_BCC_update(ctr, &c80, 1)
236
45
        || !ctr_BCC_final(ctr))
237
0
        return 0;
238
    /* Set up key K */
239
45
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
240
0
        return 0;
241
    /* X follows key K */
242
45
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
243
45
                          AES_BLOCK_SIZE)
244
45
        || outlen != AES_BLOCK_SIZE)
245
0
        return 0;
246
45
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
247
45
                          AES_BLOCK_SIZE)
248
45
        || outlen != AES_BLOCK_SIZE)
249
0
        return 0;
250
45
    if (ctr->keylen != 16)
251
45
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
252
45
                              ctr->KX + 16, AES_BLOCK_SIZE)
253
45
            || outlen != AES_BLOCK_SIZE)
254
0
            return 0;
255
45
    return 1;
256
45
}
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
81.6k
{
269
81.6k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
270
81.6k
    int outlen = AES_BLOCK_SIZE;
271
81.6k
    unsigned char V_tmp[48], out[48];
272
81.6k
    unsigned char len;
273
274
    /* correct key is already set up. */
275
81.6k
    memcpy(V_tmp, ctr->V, 16);
276
81.6k
    inc_128(ctr);
277
81.6k
    memcpy(V_tmp + 16, ctr->V, 16);
278
81.6k
    if (ctr->keylen == 16) {
279
0
        len = 32;
280
81.6k
    } else {
281
81.6k
        inc_128(ctr);
282
81.6k
        memcpy(V_tmp + 32, ctr->V, 16);
283
81.6k
        len = 48;
284
81.6k
    }
285
81.6k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
286
81.6k
            || outlen != len)
287
0
        return 0;
288
81.6k
    memcpy(ctr->K, out, ctr->keylen);
289
81.6k
    memcpy(ctr->V, out + ctr->keylen, 16);
290
291
81.6k
    if (ctr->use_df) {
292
        /* If no input reuse existing derived value */
293
68.4k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
294
45
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
295
0
                return 0;
296
        /* If this a reuse input in1len != 0 */
297
68.4k
        if (in1len)
298
65
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
299
68.4k
    } else {
300
13.1k
        ctr_XOR(ctr, in1, in1len);
301
13.1k
        ctr_XOR(ctr, in2, in2len);
302
13.1k
    }
303
304
81.6k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
305
81.6k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
306
0
        return 0;
307
81.6k
    return 1;
308
81.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
17
{
315
17
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
316
317
17
    if (entropy == NULL)
318
0
        return 0;
319
320
17
    memset(ctr->K, 0, sizeof(ctr->K));
321
17
    memset(ctr->V, 0, sizeof(ctr->V));
322
17
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
323
0
        return 0;
324
325
17
    inc_128(ctr);
326
17
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
327
0
        return 0;
328
17
    return 1;
329
17
}
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
13
{
337
13
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
338
13
    int ret = 0;
339
340
13
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
341
0
        return 0;
342
343
13
    if (!ossl_prov_is_running()
344
13
            || !drbg_ctr_set_ctx_params_locked(drbg, params))
345
0
        goto err;
346
13
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
347
13
                                     pstr, pstr_len);
348
13
 err:
349
13
    if (drbg->lock != NULL)
350
0
        CRYPTO_THREAD_unlock(drbg->lock);
351
13
    return ret;
352
13
}
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
10
{
358
10
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
359
360
10
    if (entropy == NULL)
361
0
        return 0;
362
363
10
    inc_128(ctr);
364
10
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
365
0
        return 0;
366
10
    return 1;
367
10
}
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
81.6k
{
395
81.6k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
396
81.6k
    unsigned int ctr32, blocks;
397
81.6k
    int outl, buflen;
398
399
81.6k
    if (adin != NULL && adinlen != 0) {
400
20
        inc_128(ctr);
401
402
20
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
403
0
            return 0;
404
        /* This means we reuse derived value */
405
20
        if (ctr->use_df) {
406
20
            adin = NULL;
407
20
            adinlen = 1;
408
20
        }
409
81.5k
    } else {
410
81.5k
        adinlen = 0;
411
81.5k
    }
412
413
81.6k
    inc_128(ctr);
414
415
81.6k
    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
81.6k
    memset(out, 0, outlen);
424
425
81.6k
    do {
426
81.6k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
427
81.6k
                               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
81.6k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
438
81.6k
        blocks = (buflen + 15) / 16;
439
440
81.6k
        ctr32 = GETU32(ctr->V + 12) + blocks;
441
81.6k
        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
81.6k
        PUTU32(ctr->V + 12, ctr32);
451
452
81.6k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
453
81.6k
            || outl != buflen)
454
0
            return 0;
455
456
81.6k
        out += buflen;
457
81.6k
        outlen -= buflen;
458
81.6k
    } while (outlen);
459
460
81.6k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
461
0
        return 0;
462
81.6k
    return 1;
463
81.6k
}
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
81.5k
{
470
81.5k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
471
472
81.5k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
473
81.5k
                                   prediction_resistance, adin, adin_len);
474
81.5k
}
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
62
{
529
62
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
530
62
    int res = 1;
531
532
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
533
62
    drbg->max_request = 1 << 16;
534
62
    if (ctr->use_df) {
535
61
        drbg->min_entropylen = 0;
536
61
        drbg->max_entropylen = DRBG_MAX_LENGTH;
537
61
        drbg->min_noncelen = 0;
538
61
        drbg->max_noncelen = DRBG_MAX_LENGTH;
539
61
        drbg->max_perslen = DRBG_MAX_LENGTH;
540
61
        drbg->max_adinlen = DRBG_MAX_LENGTH;
541
542
61
        if (ctr->keylen > 0) {
543
16
            drbg->min_entropylen = ctr->keylen;
544
16
            drbg->min_noncelen = drbg->min_entropylen / 2;
545
16
        }
546
61
    } else {
547
1
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
548
549
1
        drbg->min_entropylen = len;
550
1
        drbg->max_entropylen = len;
551
        /* Nonce not used */
552
1
        drbg->min_noncelen = 0;
553
1
        drbg->max_noncelen = 0;
554
1
        drbg->max_perslen = len;
555
1
        drbg->max_adinlen = len;
556
1
    }
557
62
    return res;
558
62
}
559
560
static int drbg_ctr_init(PROV_DRBG *drbg)
561
17
{
562
17
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
563
17
    size_t keylen;
564
565
17
    if (ctr->cipher_ctr == NULL) {
566
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
567
0
        return 0;
568
0
    }
569
17
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
570
17
    if (ctr->ctx_ecb == NULL)
571
17
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
572
17
    if (ctr->ctx_ctr == NULL)
573
17
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
574
17
    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
17
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
580
17
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
581
17
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
582
17
                              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
17
    drbg->strength = keylen * 8;
588
17
    drbg->seedlen = keylen + 16;
589
590
17
    if (ctr->use_df) {
591
        /* df initialisation */
592
16
        static const unsigned char df_key[32] = {
593
16
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
594
16
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
595
16
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
596
16
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
597
16
        };
598
599
16
        if (ctr->ctx_df == NULL)
600
16
            ctr->ctx_df = EVP_CIPHER_CTX_new();
601
16
        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
16
        if (!EVP_CipherInit_ex(ctr->ctx_df,
607
16
                               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
16
    }
612
17
    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
17
}
620
621
static int drbg_ctr_new(PROV_DRBG *drbg)
622
45
{
623
45
    PROV_DRBG_CTR *ctr;
624
625
45
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
626
45
    if (ctr == NULL)
627
0
        return 0;
628
629
45
    ctr->use_df = 1;
630
45
    drbg->data = ctr;
631
45
    return drbg_ctr_init_lengths(drbg);
632
45
}
633
634
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
635
                                   const OSSL_DISPATCH *parent_dispatch)
636
45
{
637
45
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
638
45
                              &drbg_ctr_new, &drbg_ctr_free,
639
45
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
640
45
                              &drbg_ctr_reseed, &drbg_ctr_generate);
641
45
}
642
643
static void drbg_ctr_free(void *vdrbg)
644
45
{
645
45
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
646
45
    PROV_DRBG_CTR *ctr;
647
648
45
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
649
45
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
650
45
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
651
45
        EVP_CIPHER_CTX_free(ctr->ctx_df);
652
45
        EVP_CIPHER_free(ctr->cipher_ecb);
653
45
        EVP_CIPHER_free(ctr->cipher_ctr);
654
655
45
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
656
45
    }
657
45
    ossl_rand_drbg_free(drbg);
658
45
}
659
660
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
661
71.4k
{
662
71.4k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
663
71.4k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
664
71.4k
    OSSL_PARAM *p;
665
71.4k
    int ret = 0, complete = 0;
666
667
71.4k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
668
0
        return 0;
669
670
71.4k
    if (complete)
671
71.3k
        return 1;
672
673
24
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
674
0
        return 0;
675
676
24
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
677
24
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
678
0
        goto err;
679
680
24
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
681
24
    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
24
    ret = ossl_drbg_get_ctx_params(drbg, params);
689
24
 err:
690
24
    if (drbg->lock != NULL)
691
24
        CRYPTO_THREAD_unlock(drbg->lock);
692
693
24
    return ret;
694
24
}
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
2
{
710
2
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
711
2
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
712
2
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
713
2
    const OSSL_PARAM *p;
714
2
    char *ecb;
715
2
    const char *propquery = NULL;
716
2
    int i, cipher_init = 0;
717
718
2
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
719
2
            && OSSL_PARAM_get_int(p, &i)) {
720
        /* FIPS errors out in the drbg_ctr_init() call later */
721
2
        ctr->use_df = i != 0;
722
2
        cipher_init = 1;
723
2
    }
724
725
2
    if ((p = OSSL_PARAM_locate_const(params,
726
2
                                     OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
727
0
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
728
0
            return 0;
729
0
        propquery = (const char *)p->data;
730
0
    }
731
732
2
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
733
2
        const char *base = (const char *)p->data;
734
2
        size_t ctr_str_len = sizeof("CTR") - 1;
735
2
        size_t ecb_str_len = sizeof("ECB") - 1;
736
737
2
        if (p->data_type != OSSL_PARAM_UTF8_STRING
738
2
                || p->data_size < ctr_str_len)
739
0
            return 0;
740
2
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
741
0
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
742
0
            return 0;
743
0
        }
744
2
        if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
745
0
            return 0;
746
2
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
747
2
        EVP_CIPHER_free(ctr->cipher_ecb);
748
2
        EVP_CIPHER_free(ctr->cipher_ctr);
749
2
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
750
2
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
751
2
        OPENSSL_free(ecb);
752
2
        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
2
        cipher_init = 1;
757
2
    }
758
759
2
    if (cipher_init && !drbg_ctr_init(ctx))
760
0
        return 0;
761
762
2
    return ossl_drbg_set_ctx_params(ctx, params);
763
2
}
764
765
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
766
28
{
767
28
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
768
28
    int ret;
769
770
28
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
771
0
        return 0;
772
773
28
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
774
775
28
    if (drbg->lock != NULL)
776
0
        CRYPTO_THREAD_unlock(drbg->lock);
777
778
28
    return ret;
779
28
}
780
781
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
782
                                                      ossl_unused void *provctx)
783
41
{
784
41
    static const OSSL_PARAM known_settable_ctx_params[] = {
785
41
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
786
41
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
787
41
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
788
41
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
789
41
        OSSL_PARAM_END
790
41
    };
791
41
    return known_settable_ctx_params;
792
41
}
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
};