Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/rand/drbg_ctr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the OpenSSL license (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 "internal/thread_once.h"
16
#include "internal/thread_once.h"
17
#include "rand_lcl.h"
18
/*
19
 * Implementation of NIST SP 800-90A CTR DRBG.
20
 */
21
22
static void inc_128(RAND_DRBG_CTR *ctr)
23
0
{
24
0
    int i;
25
0
    unsigned char c;
26
0
    unsigned char *p = &ctr->V[15];
27
0
28
0
    for (i = 0; i < 16; i++, p--) {
29
0
        c = *p;
30
0
        c++;
31
0
        *p = c;
32
0
        if (c != 0) {
33
0
            /* If we didn't wrap around, we're done. */
34
0
            break;
35
0
        }
36
0
    }
37
0
}
38
39
static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
40
0
{
41
0
    size_t i, n;
42
0
43
0
    if (in == NULL || inlen == 0)
44
0
        return;
45
0
46
0
    /*
47
0
     * Any zero padding will have no effect on the result as we
48
0
     * are XORing. So just process however much input we have.
49
0
     */
50
0
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
51
0
    for (i = 0; i < n; i++)
52
0
        ctr->K[i] ^= in[i];
53
0
    if (inlen <= ctr->keylen)
54
0
        return;
55
0
56
0
    n = inlen - ctr->keylen;
57
0
    if (n > 16) {
58
0
        /* Should never happen */
59
0
        n = 16;
60
0
    }
61
0
    for (i = 0; i < n; i++)
62
0
        ctr->V[i] ^= in[i + ctr->keylen];
63
0
}
64
65
/*
66
 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
67
 */
68
__owur static int ctr_BCC_block(RAND_DRBG_CTR *ctr, unsigned char *out,
69
                                const unsigned char *in)
70
0
{
71
0
    int i, outlen = AES_BLOCK_SIZE;
72
0
73
0
    for (i = 0; i < 16; i++)
74
0
        out[i] ^= in[i];
75
0
76
0
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, AES_BLOCK_SIZE)
77
0
        || outlen != AES_BLOCK_SIZE)
78
0
        return 0;
79
0
    return 1;
80
0
}
81
82
83
/*
84
 * Handle several BCC operations for as much data as we need for K and X
85
 */
86
__owur static int ctr_BCC_blocks(RAND_DRBG_CTR *ctr, const unsigned char *in)
87
0
{
88
0
    if (!ctr_BCC_block(ctr, ctr->KX, in)
89
0
        || !ctr_BCC_block(ctr, ctr->KX + 16, in))
90
0
        return 0;
91
0
    if (ctr->keylen != 16 && !ctr_BCC_block(ctr, ctr->KX + 32, in))
92
0
        return 0;
93
0
    return 1;
94
0
}
95
96
/*
97
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
98
 * see 10.3.1 stage 7.
99
 */
100
__owur static int ctr_BCC_init(RAND_DRBG_CTR *ctr)
101
0
{
102
0
    memset(ctr->KX, 0, 48);
103
0
    memset(ctr->bltmp, 0, 16);
104
0
    if (!ctr_BCC_block(ctr, ctr->KX, ctr->bltmp))
105
0
        return 0;
106
0
    ctr->bltmp[3] = 1;
107
0
    if (!ctr_BCC_block(ctr, ctr->KX + 16, ctr->bltmp))
108
0
        return 0;
109
0
    if (ctr->keylen != 16) {
110
0
        ctr->bltmp[3] = 2;
111
0
        if (!ctr_BCC_block(ctr, ctr->KX + 32, ctr->bltmp))
112
0
            return 0;
113
0
    }
114
0
    return 1;
115
0
}
116
117
/*
118
 * Process several blocks into BCC algorithm, some possibly partial
119
 */
120
__owur static int ctr_BCC_update(RAND_DRBG_CTR *ctr,
121
                                 const unsigned char *in, size_t inlen)
122
0
{
123
0
    if (in == NULL || inlen == 0)
124
0
        return 1;
125
0
126
0
    /* If we have partial block handle it first */
127
0
    if (ctr->bltmp_pos) {
128
0
        size_t left = 16 - ctr->bltmp_pos;
129
0
130
0
        /* If we now have a complete block process it */
131
0
        if (inlen >= left) {
132
0
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
133
0
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
134
0
                return 0;
135
0
            ctr->bltmp_pos = 0;
136
0
            inlen -= left;
137
0
            in += left;
138
0
        }
139
0
    }
140
0
141
0
    /* Process zero or more complete blocks */
142
0
    for (; inlen >= 16; in += 16, inlen -= 16) {
143
0
        if (!ctr_BCC_blocks(ctr, in))
144
0
            return 0;
145
0
    }
146
0
147
0
    /* Copy any remaining partial block to the temporary buffer */
148
0
    if (inlen > 0) {
149
0
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
150
0
        ctr->bltmp_pos += inlen;
151
0
    }
152
0
    return 1;
153
0
}
154
155
__owur static int ctr_BCC_final(RAND_DRBG_CTR *ctr)
156
0
{
157
0
    if (ctr->bltmp_pos) {
158
0
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
159
0
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
160
0
            return 0;
161
0
    }
162
0
    return 1;
163
0
}
164
165
__owur static int ctr_df(RAND_DRBG_CTR *ctr,
166
                         const unsigned char *in1, size_t in1len,
167
                         const unsigned char *in2, size_t in2len,
168
                         const unsigned char *in3, size_t in3len)
169
0
{
170
0
    static unsigned char c80 = 0x80;
171
0
    size_t inlen;
172
0
    unsigned char *p = ctr->bltmp;
173
0
    int outlen = AES_BLOCK_SIZE;
174
0
175
0
    if (!ctr_BCC_init(ctr))
176
0
        return 0;
177
0
    if (in1 == NULL)
178
0
        in1len = 0;
179
0
    if (in2 == NULL)
180
0
        in2len = 0;
181
0
    if (in3 == NULL)
182
0
        in3len = 0;
183
0
    inlen = in1len + in2len + in3len;
184
0
    /* Initialise L||N in temporary block */
185
0
    *p++ = (inlen >> 24) & 0xff;
186
0
    *p++ = (inlen >> 16) & 0xff;
187
0
    *p++ = (inlen >> 8) & 0xff;
188
0
    *p++ = inlen & 0xff;
189
0
190
0
    /* NB keylen is at most 32 bytes */
191
0
    *p++ = 0;
192
0
    *p++ = 0;
193
0
    *p++ = 0;
194
0
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
195
0
    ctr->bltmp_pos = 8;
196
0
    if (!ctr_BCC_update(ctr, in1, in1len)
197
0
        || !ctr_BCC_update(ctr, in2, in2len)
198
0
        || !ctr_BCC_update(ctr, in3, in3len)
199
0
        || !ctr_BCC_update(ctr, &c80, 1)
200
0
        || !ctr_BCC_final(ctr))
201
0
        return 0;
202
0
    /* Set up key K */
203
0
    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->KX, NULL, 1))
204
0
        return 0;
205
0
    /* X follows key K */
206
0
    if (!EVP_CipherUpdate(ctr->ctx, ctr->KX, &outlen, ctr->KX + ctr->keylen,
207
0
                          AES_BLOCK_SIZE)
208
0
        || outlen != AES_BLOCK_SIZE)
209
0
        return 0;
210
0
    if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 16, &outlen, ctr->KX,
211
0
                          AES_BLOCK_SIZE)
212
0
        || outlen != AES_BLOCK_SIZE)
213
0
        return 0;
214
0
    if (ctr->keylen != 16)
215
0
        if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 32, &outlen, ctr->KX + 16,
216
0
                              AES_BLOCK_SIZE)
217
0
            || outlen != AES_BLOCK_SIZE)
218
0
            return 0;
219
0
    return 1;
220
0
}
221
222
/*
223
 * NB the no-df Update in SP800-90A specifies a constant input length
224
 * of seedlen, however other uses of this algorithm pad the input with
225
 * zeroes if necessary and have up to two parameters XORed together,
226
 * so we handle both cases in this function instead.
227
 */
228
__owur static int ctr_update(RAND_DRBG *drbg,
229
                             const unsigned char *in1, size_t in1len,
230
                             const unsigned char *in2, size_t in2len,
231
                             const unsigned char *nonce, size_t noncelen)
232
0
{
233
0
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
234
0
    int outlen = AES_BLOCK_SIZE;
235
0
236
0
    /* correct key is already set up. */
237
0
    inc_128(ctr);
238
0
    if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outlen, ctr->V, AES_BLOCK_SIZE)
239
0
        || outlen != AES_BLOCK_SIZE)
240
0
        return 0;
241
0
242
0
    /* If keylen longer than 128 bits need extra encrypt */
243
0
    if (ctr->keylen != 16) {
244
0
        inc_128(ctr);
245
0
        if (!EVP_CipherUpdate(ctr->ctx, ctr->K+16, &outlen, ctr->V,
246
0
                              AES_BLOCK_SIZE)
247
0
            || outlen != AES_BLOCK_SIZE)
248
0
            return 0;
249
0
    }
250
0
    inc_128(ctr);
251
0
    if (!EVP_CipherUpdate(ctr->ctx, ctr->V, &outlen, ctr->V, AES_BLOCK_SIZE)
252
0
        || outlen != AES_BLOCK_SIZE)
253
0
        return 0;
254
0
255
0
    /* If 192 bit key part of V is on end of K */
256
0
    if (ctr->keylen == 24) {
257
0
        memcpy(ctr->V + 8, ctr->V, 8);
258
0
        memcpy(ctr->V, ctr->K + 24, 8);
259
0
    }
260
0
261
0
    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
262
0
        /* If no input reuse existing derived value */
263
0
        if (in1 != NULL || nonce != NULL || in2 != NULL)
264
0
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
265
0
                return 0;
266
0
        /* If this a reuse input in1len != 0 */
267
0
        if (in1len)
268
0
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
269
0
    } else {
270
0
        ctr_XOR(ctr, in1, in1len);
271
0
        ctr_XOR(ctr, in2, in2len);
272
0
    }
273
0
274
0
    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
275
0
        return 0;
276
0
    return 1;
277
0
}
278
279
__owur static int drbg_ctr_instantiate(RAND_DRBG *drbg,
280
                                       const unsigned char *entropy, size_t entropylen,
281
                                       const unsigned char *nonce, size_t noncelen,
282
                                       const unsigned char *pers, size_t perslen)
283
0
{
284
0
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
285
0
286
0
    if (entropy == NULL)
287
0
        return 0;
288
0
289
0
    memset(ctr->K, 0, sizeof(ctr->K));
290
0
    memset(ctr->V, 0, sizeof(ctr->V));
291
0
    if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
292
0
        return 0;
293
0
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
294
0
        return 0;
295
0
    return 1;
296
0
}
297
298
__owur static int drbg_ctr_reseed(RAND_DRBG *drbg,
299
                                  const unsigned char *entropy, size_t entropylen,
300
                                  const unsigned char *adin, size_t adinlen)
301
0
{
302
0
    if (entropy == NULL)
303
0
        return 0;
304
0
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
305
0
        return 0;
306
0
    return 1;
307
0
}
308
309
__owur static int drbg_ctr_generate(RAND_DRBG *drbg,
310
                                    unsigned char *out, size_t outlen,
311
                                    const unsigned char *adin, size_t adinlen)
312
0
{
313
0
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
314
0
315
0
    if (adin != NULL && adinlen != 0) {
316
0
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
317
0
            return 0;
318
0
        /* This means we reuse derived value */
319
0
        if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
320
0
            adin = NULL;
321
0
            adinlen = 1;
322
0
        }
323
0
    } else {
324
0
        adinlen = 0;
325
0
    }
326
0
327
0
    for ( ; ; ) {
328
0
        int outl = AES_BLOCK_SIZE;
329
0
330
0
        inc_128(ctr);
331
0
        if (outlen < 16) {
332
0
            /* Use K as temp space as it will be updated */
333
0
            if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outl, ctr->V,
334
0
                                  AES_BLOCK_SIZE)
335
0
                || outl != AES_BLOCK_SIZE)
336
0
                return 0;
337
0
            memcpy(out, ctr->K, outlen);
338
0
            break;
339
0
        }
340
0
        if (!EVP_CipherUpdate(ctr->ctx, out, &outl, ctr->V, AES_BLOCK_SIZE)
341
0
            || outl != AES_BLOCK_SIZE)
342
0
            return 0;
343
0
        out += 16;
344
0
        outlen -= 16;
345
0
        if (outlen == 0)
346
0
            break;
347
0
    }
348
0
349
0
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
350
0
        return 0;
351
0
    return 1;
352
0
}
353
354
static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
355
0
{
356
0
    EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
357
0
    EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
358
0
    OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
359
0
    return 1;
360
0
}
361
362
static RAND_DRBG_METHOD drbg_ctr_meth = {
363
    drbg_ctr_instantiate,
364
    drbg_ctr_reseed,
365
    drbg_ctr_generate,
366
    drbg_ctr_uninstantiate
367
};
368
369
int drbg_ctr_init(RAND_DRBG *drbg)
370
0
{
371
0
    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
372
0
    size_t keylen;
373
0
374
0
    switch (drbg->type) {
375
0
    default:
376
0
        /* This can't happen, but silence the compiler warning. */
377
0
        return 0;
378
0
    case NID_aes_128_ctr:
379
0
        keylen = 16;
380
0
        ctr->cipher = EVP_aes_128_ecb();
381
0
        break;
382
0
    case NID_aes_192_ctr:
383
0
        keylen = 24;
384
0
        ctr->cipher = EVP_aes_192_ecb();
385
0
        break;
386
0
    case NID_aes_256_ctr:
387
0
        keylen = 32;
388
0
        ctr->cipher = EVP_aes_256_ecb();
389
0
        break;
390
0
    }
391
0
392
0
    drbg->meth = &drbg_ctr_meth;
393
0
394
0
    ctr->keylen = keylen;
395
0
    if (ctr->ctx == NULL)
396
0
        ctr->ctx = EVP_CIPHER_CTX_new();
397
0
    if (ctr->ctx == NULL)
398
0
        return 0;
399
0
    drbg->strength = keylen * 8;
400
0
    drbg->seedlen = keylen + 16;
401
0
402
0
    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
403
0
        /* df initialisation */
404
0
        static const unsigned char df_key[32] = {
405
0
            0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
406
0
            0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
407
0
            0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
408
0
            0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
409
0
        };
410
0
411
0
        if (ctr->ctx_df == NULL)
412
0
            ctr->ctx_df = EVP_CIPHER_CTX_new();
413
0
        if (ctr->ctx_df == NULL)
414
0
            return 0;
415
0
        /* Set key schedule for df_key */
416
0
        if (!EVP_CipherInit_ex(ctr->ctx_df, ctr->cipher, NULL, df_key, NULL, 1))
417
0
            return 0;
418
0
419
0
        drbg->min_entropylen = ctr->keylen;
420
0
        drbg->max_entropylen = DRBG_MINMAX_FACTOR * drbg->min_entropylen;
421
0
        drbg->min_noncelen = drbg->min_entropylen / 2;
422
0
        drbg->max_noncelen = DRBG_MINMAX_FACTOR * drbg->min_noncelen;
423
0
        drbg->max_perslen = DRBG_MAX_LENGTH;
424
0
        drbg->max_adinlen = DRBG_MAX_LENGTH;
425
0
    } else {
426
0
        drbg->min_entropylen = drbg->seedlen;
427
0
        drbg->max_entropylen = drbg->seedlen;
428
0
        /* Nonce not used */
429
0
        drbg->min_noncelen = 0;
430
0
        drbg->max_noncelen = 0;
431
0
        drbg->max_perslen = drbg->seedlen;
432
0
        drbg->max_adinlen = drbg->seedlen;
433
0
    }
434
0
435
0
    drbg->max_request = 1 << 16;
436
0
437
0
    return 1;
438
0
}