Coverage Report

Created: 2023-04-12 06:23

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