Coverage Report

Created: 2024-02-25 06:25

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