Coverage Report

Created: 2024-09-08 06:32

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