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