Coverage Report

Created: 2025-07-11 06:57

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