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