Coverage Report

Created: 2024-05-21 06:52

/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
501k
{
62
501k
    unsigned char *p = &ctr->V[0];
63
501k
    u32 n = 16, c = 1;
64
65
8.03M
    do {
66
8.03M
        --n;
67
8.03M
        c += p[n];
68
8.03M
        p[n] = (u8)c;
69
8.03M
        c >>= 8;
70
8.03M
    } while (n);
71
501k
}
72
73
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
74
334k
{
75
334k
    size_t i, n;
76
77
334k
    if (in == NULL || inlen == 0)
78
334k
        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
183
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
85
5.96k
    for (i = 0; i < n; i++)
86
5.78k
        ctr->K[i] ^= in[i];
87
183
    if (inlen <= ctr->keylen)
88
24
        return;
89
90
159
    n = inlen - ctr->keylen;
91
159
    if (n > 16) {
92
        /* Should never happen */
93
0
        n = 16;
94
0
    }
95
2.70k
    for (i = 0; i < n; i++)
96
2.54k
        ctr->V[i] ^= in[i + ctr->keylen];
97
159
}
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
249
{
105
249
    int i, outlen = AES_BLOCK_SIZE;
106
107
12.2k
    for (i = 0; i < len; i++)
108
11.9k
        out[i] ^= in[i];
109
110
249
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
111
249
        || outlen != len)
112
0
        return 0;
113
249
    return 1;
114
249
}
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
186
{
122
186
    unsigned char in_tmp[48];
123
186
    unsigned char num_of_blk = 2;
124
125
186
    memcpy(in_tmp, in, 16);
126
186
    memcpy(in_tmp + 16, in, 16);
127
186
    if (ctr->keylen != 16) {
128
186
        memcpy(in_tmp + 32, in, 16);
129
186
        num_of_blk = 3;
130
186
    }
131
186
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
132
186
}
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
63
{
140
63
    unsigned char bltmp[48] = {0};
141
63
    unsigned char num_of_blk;
142
143
63
    memset(ctr->KX, 0, 48);
144
63
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
145
63
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
146
63
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
147
63
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
148
63
}
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
252
{
156
252
    if (in == NULL || inlen == 0)
157
111
        return 1;
158
159
    /* If we have partial block handle it first */
160
141
    if (ctr->bltmp_pos) {
161
93
        size_t left = 16 - ctr->bltmp_pos;
162
163
        /* If we now have a complete block process it */
164
93
        if (inlen >= left) {
165
78
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
166
78
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
167
0
                return 0;
168
78
            ctr->bltmp_pos = 0;
169
78
            inlen -= left;
170
78
            in += left;
171
78
        }
172
93
    }
173
174
    /* Process zero or more complete blocks */
175
186
    for (; inlen >= 16; in += 16, inlen -= 16) {
176
45
        if (!ctr_BCC_blocks(ctr, in))
177
0
            return 0;
178
45
    }
179
180
    /* Copy any remaining partial block to the temporary buffer */
181
141
    if (inlen > 0) {
182
93
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
183
93
        ctr->bltmp_pos += inlen;
184
93
    }
185
141
    return 1;
186
141
}
187
188
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
189
63
{
190
63
    if (ctr->bltmp_pos) {
191
63
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
192
63
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
193
0
            return 0;
194
63
    }
195
63
    return 1;
196
63
}
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
63
{
203
63
    static unsigned char c80 = 0x80;
204
63
    size_t inlen;
205
63
    unsigned char *p = ctr->bltmp;
206
63
    int outlen = AES_BLOCK_SIZE;
207
208
63
    if (!ctr_BCC_init(ctr))
209
0
        return 0;
210
63
    if (in1 == NULL)
211
0
        in1len = 0;
212
63
    if (in2 == NULL)
213
63
        in2len = 0;
214
63
    if (in3 == NULL)
215
48
        in3len = 0;
216
63
    inlen = in1len + in2len + in3len;
217
    /* Initialise L||N in temporary block */
218
63
    *p++ = (inlen >> 24) & 0xff;
219
63
    *p++ = (inlen >> 16) & 0xff;
220
63
    *p++ = (inlen >> 8) & 0xff;
221
63
    *p++ = inlen & 0xff;
222
223
    /* NB keylen is at most 32 bytes */
224
63
    *p++ = 0;
225
63
    *p++ = 0;
226
63
    *p++ = 0;
227
63
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
228
63
    ctr->bltmp_pos = 8;
229
63
    if (!ctr_BCC_update(ctr, in1, in1len)
230
63
        || !ctr_BCC_update(ctr, in2, in2len)
231
63
        || !ctr_BCC_update(ctr, in3, in3len)
232
63
        || !ctr_BCC_update(ctr, &c80, 1)
233
63
        || !ctr_BCC_final(ctr))
234
0
        return 0;
235
    /* Set up key K */
236
63
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
237
0
        return 0;
238
    /* X follows key K */
239
63
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
240
63
                          AES_BLOCK_SIZE)
241
63
        || outlen != AES_BLOCK_SIZE)
242
0
        return 0;
243
63
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
244
63
                          AES_BLOCK_SIZE)
245
63
        || outlen != AES_BLOCK_SIZE)
246
0
        return 0;
247
63
    if (ctr->keylen != 16)
248
63
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
249
63
                              ctr->KX + 16, AES_BLOCK_SIZE)
250
63
            || outlen != AES_BLOCK_SIZE)
251
0
            return 0;
252
63
    return 1;
253
63
}
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
167k
{
266
167k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
267
167k
    int outlen = AES_BLOCK_SIZE;
268
167k
    unsigned char V_tmp[48], out[48];
269
167k
    unsigned char len;
270
271
    /* correct key is already set up. */
272
167k
    memcpy(V_tmp, ctr->V, 16);
273
167k
    inc_128(ctr);
274
167k
    memcpy(V_tmp + 16, ctr->V, 16);
275
167k
    if (ctr->keylen == 16) {
276
0
        len = 32;
277
167k
    } else {
278
167k
        inc_128(ctr);
279
167k
        memcpy(V_tmp + 32, ctr->V, 16);
280
167k
        len = 48;
281
167k
    }
282
167k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
283
167k
            || outlen != len)
284
0
        return 0;
285
167k
    memcpy(ctr->K, out, ctr->keylen);
286
167k
    memcpy(ctr->V, out + ctr->keylen, 16);
287
288
167k
    if (ctr->use_df) {
289
        /* If no input reuse existing derived value */
290
111
        if (in1 != NULL || nonce != NULL || in2 != NULL)
291
63
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
292
0
                return 0;
293
        /* If this a reuse input in1len != 0 */
294
111
        if (in1len)
295
111
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
296
167k
    } else {
297
167k
        ctr_XOR(ctr, in1, in1len);
298
167k
        ctr_XOR(ctr, in2, in2len);
299
167k
    }
300
301
167k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
302
167k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
303
0
        return 0;
304
167k
    return 1;
305
167k
}
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
39
{
312
39
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
313
314
39
    if (entropy == NULL)
315
0
        return 0;
316
317
39
    memset(ctr->K, 0, sizeof(ctr->K));
318
39
    memset(ctr->V, 0, sizeof(ctr->V));
319
39
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
320
0
        return 0;
321
322
39
    inc_128(ctr);
323
39
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
324
0
        return 0;
325
39
    return 1;
326
39
}
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
39
{
334
39
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
335
39
    int ret = 0;
336
337
39
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
338
0
        return 0;
339
340
39
    if (!ossl_prov_is_running()
341
39
            || !drbg_ctr_set_ctx_params_locked(drbg, params))
342
0
        goto err;
343
39
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
344
39
                                     pstr, pstr_len);
345
39
 err:
346
39
    if (drbg->lock != NULL)
347
0
        CRYPTO_THREAD_unlock(drbg->lock);
348
39
    return ret;
349
39
}
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
24
{
355
24
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
356
357
24
    if (entropy == NULL)
358
0
        return 0;
359
360
24
    inc_128(ctr);
361
24
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
362
0
        return 0;
363
24
    return 1;
364
24
}
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
167k
{
392
167k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
393
167k
    unsigned int ctr32, blocks;
394
167k
    int outl, buflen;
395
396
167k
    if (adin != NULL && adinlen != 0) {
397
48
        inc_128(ctr);
398
399
48
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
400
0
            return 0;
401
        /* This means we reuse derived value */
402
48
        if (ctr->use_df) {
403
48
            adin = NULL;
404
48
            adinlen = 1;
405
48
        }
406
167k
    } else {
407
167k
        adinlen = 0;
408
167k
    }
409
410
167k
    inc_128(ctr);
411
412
167k
    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
167k
    memset(out, 0, outlen);
421
422
167k
    do {
423
167k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
424
167k
                               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
167k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
435
167k
        blocks = (buflen + 15) / 16;
436
437
167k
        ctr32 = GETU32(ctr->V + 12) + blocks;
438
167k
        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
167k
        PUTU32(ctr->V + 12, ctr32);
448
449
167k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
450
167k
            || outl != buflen)
451
0
            return 0;
452
453
167k
        out += buflen;
454
167k
        outlen -= buflen;
455
167k
    } while (outlen);
456
457
167k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
458
0
        return 0;
459
167k
    return 1;
460
167k
}
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
167k
{
467
167k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
468
469
167k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
470
167k
                                   prediction_resistance, adin, adin_len);
471
167k
}
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
78
{
526
78
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
527
78
    int res = 1;
528
529
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
530
78
    drbg->max_request = 1 << 16;
531
78
    if (ctr->use_df) {
532
54
        drbg->min_entropylen = 0;
533
54
        drbg->max_entropylen = DRBG_MAX_LENGTH;
534
54
        drbg->min_noncelen = 0;
535
54
        drbg->max_noncelen = DRBG_MAX_LENGTH;
536
54
        drbg->max_perslen = DRBG_MAX_LENGTH;
537
54
        drbg->max_adinlen = DRBG_MAX_LENGTH;
538
539
54
        if (ctr->keylen > 0) {
540
15
            drbg->min_entropylen = ctr->keylen;
541
15
            drbg->min_noncelen = drbg->min_entropylen / 2;
542
15
        }
543
54
    } else {
544
24
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
545
546
24
        drbg->min_entropylen = len;
547
24
        drbg->max_entropylen = len;
548
        /* Nonce not used */
549
24
        drbg->min_noncelen = 0;
550
24
        drbg->max_noncelen = 0;
551
24
        drbg->max_perslen = len;
552
24
        drbg->max_adinlen = len;
553
24
    }
554
78
    return res;
555
78
}
556
557
static int drbg_ctr_init(PROV_DRBG *drbg)
558
39
{
559
39
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
560
39
    size_t keylen;
561
562
39
    if (ctr->cipher_ctr == NULL) {
563
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
564
0
        return 0;
565
0
    }
566
39
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
567
39
    if (ctr->ctx_ecb == NULL)
568
39
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
569
39
    if (ctr->ctx_ctr == NULL)
570
39
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
571
39
    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
39
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
577
39
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
578
39
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
579
39
                              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
39
    drbg->strength = keylen * 8;
585
39
    drbg->seedlen = keylen + 16;
586
587
39
    if (ctr->use_df) {
588
        /* df initialisation */
589
15
        static const unsigned char df_key[32] = {
590
15
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
591
15
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
592
15
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
593
15
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
594
15
        };
595
596
15
        if (ctr->ctx_df == NULL)
597
15
            ctr->ctx_df = EVP_CIPHER_CTX_new();
598
15
        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
15
        if (!EVP_CipherInit_ex(ctr->ctx_df,
604
15
                               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
15
    }
609
39
    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
39
}
617
618
static int drbg_ctr_new(PROV_DRBG *drbg)
619
39
{
620
39
    PROV_DRBG_CTR *ctr;
621
622
39
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
623
39
    if (ctr == NULL)
624
0
        return 0;
625
626
39
    ctr->use_df = 1;
627
39
    drbg->data = ctr;
628
39
    return drbg_ctr_init_lengths(drbg);
629
39
}
630
631
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
632
                                   const OSSL_DISPATCH *parent_dispatch)
633
39
{
634
39
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch, &drbg_ctr_new,
635
39
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
636
39
                              &drbg_ctr_reseed, &drbg_ctr_generate);
637
39
}
638
639
static void drbg_ctr_free(void *vdrbg)
640
39
{
641
39
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
642
39
    PROV_DRBG_CTR *ctr;
643
644
39
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
645
39
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
646
39
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
647
39
        EVP_CIPHER_CTX_free(ctr->ctx_df);
648
39
        EVP_CIPHER_free(ctr->cipher_ecb);
649
39
        EVP_CIPHER_free(ctr->cipher_ctr);
650
651
39
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
652
39
    }
653
39
    ossl_rand_drbg_free(drbg);
654
39
}
655
656
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
657
469k
{
658
469k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
659
469k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
660
469k
    OSSL_PARAM *p;
661
469k
    int ret = 0, complete = 0;
662
663
469k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
664
0
        return 0;
665
666
469k
    if (complete)
667
334k
        return 1;
668
669
135k
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
670
0
        return 0;
671
672
135k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
673
135k
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
674
0
        goto err;
675
676
135k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
677
135k
    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
135k
    ret = ossl_drbg_get_ctx_params(drbg, params);
685
135k
 err:
686
135k
    if (drbg->lock != NULL)
687
135k
        CRYPTO_THREAD_unlock(drbg->lock);
688
689
135k
    return ret;
690
135k
}
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
39
{
706
39
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
707
39
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
708
39
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
709
39
    const OSSL_PARAM *p;
710
39
    char *ecb;
711
39
    const char *propquery = NULL;
712
39
    int i, cipher_init = 0;
713
714
39
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
715
39
            && OSSL_PARAM_get_int(p, &i)) {
716
        /* FIPS errors out in the drbg_ctr_init() call later */
717
39
        ctr->use_df = i != 0;
718
39
        cipher_init = 1;
719
39
    }
720
721
39
    if ((p = OSSL_PARAM_locate_const(params,
722
39
                                     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
39
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
729
39
        const char *base = (const char *)p->data;
730
39
        size_t ctr_str_len = sizeof("CTR") - 1;
731
39
        size_t ecb_str_len = sizeof("ECB") - 1;
732
733
39
        if (p->data_type != OSSL_PARAM_UTF8_STRING
734
39
                || p->data_size < ctr_str_len)
735
0
            return 0;
736
39
        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
39
        if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
741
0
            return 0;
742
39
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
743
39
        EVP_CIPHER_free(ctr->cipher_ecb);
744
39
        EVP_CIPHER_free(ctr->cipher_ctr);
745
39
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
746
39
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
747
39
        OPENSSL_free(ecb);
748
39
        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
39
        cipher_init = 1;
753
39
    }
754
755
39
    if (cipher_init && !drbg_ctr_init(ctx))
756
0
        return 0;
757
758
39
    return ossl_drbg_set_ctx_params(ctx, params);
759
39
}
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
39
{
780
39
    static const OSSL_PARAM known_settable_ctx_params[] = {
781
39
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
782
39
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
783
39
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
784
39
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
785
39
        OSSL_PARAM_END
786
39
    };
787
39
    return known_settable_ctx_params;
788
39
}
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
};