e3d97d38d96e3f79988dfd8ca2e7746bcad81319
[openssl.git] / crypto / rand / drbg_lib.c
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 <string.h>
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/rand.h>
14 #include "rand_lcl.h"
15
16 /*
17  * Support framework for NIST SP 800-90A DRBG, AES-CTR mode.
18  * The RAND_DRBG is OpenSSL's pointer to an instance of the DRBG.
19  *
20  * The OpenSSL model is to have new and free functions, and that new
21  * does all initialization.  That is not the NIST model, which has
22  * instantiation and un-instantiate, and re-use within a new/free
23  * lifecycle.  (No doubt this comes from the desire to support hardware
24  * DRBG, where allocation of resources on something like an HSM is
25  * a much bigger deal than just re-setting an allocated resource.)
26  */
27
28 /*
29  * Set/initialize |drbg| to be of type |nid|, with optional |flags|.
30  * Return -2 if the type is not supported, 1 on success and -1 on
31  * failure.
32  */
33 int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
34 {
35     int ret = 1;
36
37     drbg->state = DRBG_UNINITIALISED;
38     drbg->flags = flags;
39     drbg->nid = nid;
40
41     switch (nid) {
42     default:
43         RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
44         return -2;
45     case 0:
46         /* Uninitialized; that's okay. */
47         return 1;
48     case NID_aes_128_ctr:
49     case NID_aes_192_ctr:
50     case NID_aes_256_ctr:
51         ret = ctr_init(drbg);
52         break;
53     }
54
55     if (ret < 0)
56         RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
57     return ret;
58 }
59
60 /*
61  * Allocate memory and initialize a new DRBG.  The |parent|, if not
62  * NULL, will be used to auto-seed this RAND_DRBG as needed.
63  */
64 RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
65 {
66     RAND_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg));
67     unsigned char *ucp = OPENSSL_zalloc(RANDOMNESS_NEEDED);
68
69     if (drbg == NULL || ucp == NULL) {
70         RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
71         goto err;
72     }
73     drbg->size = RANDOMNESS_NEEDED;
74     drbg->randomness = ucp;
75
76     drbg->parent = parent;
77     if (RAND_DRBG_set(drbg, type, flags) < 0)
78         goto err;
79
80     if (parent != NULL) {
81         if (!RAND_DRBG_set_callbacks(drbg, drbg_entropy_from_parent,
82                                      drbg_release_entropy,
83                                      NULL, NULL)
84                 /*
85                  * Add in our address.  Note we are adding the pointer
86                  * itself, not its contents!
87                  */
88                 || !RAND_DRBG_instantiate(drbg,
89                                           (unsigned char*)&drbg, sizeof(drbg)))
90             goto err;
91     }
92
93     return drbg;
94
95 err:
96     OPENSSL_free(ucp);
97     OPENSSL_free(drbg);
98     return NULL;
99 }
100
101 /*
102  * Uninstantiate |drbg| and free all memory.
103  */
104 void RAND_DRBG_free(RAND_DRBG *drbg)
105 {
106     /* The global DRBG is free'd by rand_cleanup_int() */
107     if (drbg == NULL || drbg == &rand_drbg)
108         return;
109
110     ctr_uninstantiate(drbg);
111     OPENSSL_cleanse(drbg->randomness, drbg->size);
112     OPENSSL_free(drbg->randomness);
113     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
114     OPENSSL_clear_free(drbg, sizeof(*drbg));
115 }
116
117 /*
118  * Instantiate |drbg|, after it has been initialized.  Use |pers| and
119  * |perslen| as prediction-resistance input.
120  */
121 int RAND_DRBG_instantiate(RAND_DRBG *drbg,
122                           const unsigned char *pers, size_t perslen)
123 {
124     unsigned char *nonce = NULL, *entropy = NULL;
125     size_t noncelen = 0, entlen = 0;
126
127     if (perslen > drbg->max_pers) {
128         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
129                 RAND_R_PERSONALISATION_STRING_TOO_LONG);
130         goto end;
131     }
132     if (drbg->state != DRBG_UNINITIALISED) {
133         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
134                 drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
135                                           : RAND_R_ALREADY_INSTANTIATED);
136         goto end;
137     }
138
139     drbg->state = DRBG_ERROR;
140     if (drbg->get_entropy != NULL)
141         entlen = drbg->get_entropy(drbg, &entropy, drbg->strength,
142                                    drbg->min_entropy, drbg->max_entropy);
143     if (entlen < drbg->min_entropy || entlen > drbg->max_entropy) {
144         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY);
145         goto end;
146     }
147
148     if (drbg->max_nonce > 0 && drbg->get_nonce != NULL) {
149         noncelen = drbg->get_nonce(drbg, &nonce, drbg->strength / 2,
150                                    drbg->min_nonce, drbg->max_nonce);
151         if (noncelen < drbg->min_nonce || noncelen > drbg->max_nonce) {
152             RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_NONCE);
153             goto end;
154         }
155     }
156
157     if (!ctr_instantiate(drbg, entropy, entlen,
158                          nonce, noncelen, pers, perslen)) {
159         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_INSTANTIATING_DRBG);
160         goto end;
161     }
162
163     drbg->state = DRBG_READY;
164     drbg->reseed_counter = 1;
165
166 end:
167     if (entropy != NULL && drbg->cleanup_entropy != NULL)
168         drbg->cleanup_entropy(drbg, entropy);
169     if (nonce != NULL && drbg->cleanup_nonce!= NULL )
170         drbg->cleanup_nonce(drbg, nonce);
171     if (drbg->state == DRBG_READY)
172         return 1;
173     return 0;
174 }
175
176 /*
177  * Uninstantiate |drbg|. Must be instantiated before it can be used.
178  */
179 int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
180 {
181     int ret = ctr_uninstantiate(drbg);
182
183     OPENSSL_cleanse(&drbg->ctr, sizeof(drbg->ctr));
184     drbg->state = DRBG_UNINITIALISED;
185     return ret;
186 }
187
188 /*
189  * Mix in the specified data to reseed |drbg|.
190  */
191 int RAND_DRBG_reseed(RAND_DRBG *drbg,
192                      const unsigned char *adin, size_t adinlen)
193 {
194     unsigned char *entropy = NULL;
195     size_t entlen = 0;
196
197     if (drbg->state == DRBG_ERROR) {
198         RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_IN_ERROR_STATE);
199         return 0;
200     }
201     if (drbg->state == DRBG_UNINITIALISED) {
202         RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_NOT_INSTANTIATED);
203         return 0;
204     }
205
206     if (adin == NULL)
207         adinlen = 0;
208     else if (adinlen > drbg->max_adin) {
209         RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
210         return 0;
211     }
212
213     drbg->state = DRBG_ERROR;
214     if (drbg->get_entropy != NULL)
215         entlen = drbg->get_entropy(drbg, &entropy, drbg->strength,
216                                    drbg->min_entropy, drbg->max_entropy);
217     if (entlen < drbg->min_entropy || entlen > drbg->max_entropy) {
218         RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY);
219         goto end;
220     }
221
222     if (!ctr_reseed(drbg, entropy, entlen, adin, adinlen))
223         goto end;
224     drbg->state = DRBG_READY;
225     drbg->reseed_counter = 1;
226
227 end:
228     if (entropy != NULL && drbg->cleanup_entropy != NULL)
229         drbg->cleanup_entropy(drbg, entropy);
230     if (drbg->state == DRBG_READY)
231         return 1;
232     return 0;
233 }
234
235 /*
236  * Generate |outlen| bytes into the buffer at |out|.  Reseed if we need
237  * to or if |prediction_resistance| is set.  Additional input can be
238  * sent in |adin| and |adinlen|.
239  */
240 int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
241                        int prediction_resistance,
242                        const unsigned char *adin, size_t adinlen)
243 {
244     if (drbg->state == DRBG_ERROR) {
245         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_IN_ERROR_STATE);
246         return 0;
247     }
248     if (drbg->state == DRBG_UNINITIALISED) {
249         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_NOT_INSTANTIATED);
250         return 0;
251     }
252     if (outlen > drbg->max_request) {
253         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG);
254         return 0;
255     }
256     if (adinlen > drbg->max_adin) {
257         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
258         return 0;
259     }
260
261     if (drbg->reseed_counter >= drbg->reseed_interval)
262         drbg->state = DRBG_RESEED;
263
264     if (drbg->state == DRBG_RESEED || prediction_resistance) {
265         if (!RAND_DRBG_reseed(drbg, adin, adinlen)) {
266             RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_RESEED_ERROR);
267             return 0;
268         }
269         adin = NULL;
270         adinlen = 0;
271     }
272
273     if (!ctr_generate(drbg, out, outlen, adin, adinlen)) {
274         drbg->state = DRBG_ERROR;
275         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_GENERATE_ERROR);
276         return 0;
277     }
278
279     if (drbg->reseed_counter >= drbg->reseed_interval)
280         drbg->state = DRBG_RESEED;
281     else
282         drbg->reseed_counter++;
283     return 1;
284 }
285
286 /*
287  * Set the callbacks for entropy and nonce.  We currently don't use
288  * the nonce; that's mainly for the KATs
289  */
290 int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
291                             RAND_DRBG_get_entropy_fn cb_get_entropy,
292                             RAND_DRBG_cleanup_entropy_fn cb_cleanup_entropy,
293                             RAND_DRBG_get_nonce_fn cb_get_nonce,
294                             RAND_DRBG_cleanup_nonce_fn cb_cleanup_nonce)
295 {
296     if (drbg->state != DRBG_UNINITIALISED)
297         return 0;
298     drbg->get_entropy = cb_get_entropy;
299     drbg->cleanup_entropy = cb_cleanup_entropy;
300     drbg->get_nonce = cb_get_nonce;
301     drbg->cleanup_nonce = cb_cleanup_nonce;
302     return 1;
303 }
304
305 /*
306  * Set the reseed interval.
307  */
308 int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, int interval)
309 {
310     if (interval < 0 || interval > MAX_RESEED)
311         return 0;
312     drbg->reseed_interval = interval;
313     return 1;
314 }
315
316 /*
317  * Get and set the EXDATA
318  */
319 int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg)
320 {
321     return CRYPTO_set_ex_data(&drbg->ex_data, idx, arg);
322 }
323
324 void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx)
325 {
326     return CRYPTO_get_ex_data(&drbg->ex_data, idx);
327 }
328
329
330 /*
331  * The following functions provide a RAND_METHOD that works on the
332  * global DRBG.  They lock.
333  */
334
335 static int drbg_bytes(unsigned char *out, int count)
336 {
337     int ret = 0;
338     size_t chunk;
339
340     CRYPTO_THREAD_write_lock(rand_drbg.lock);
341     if (rand_drbg.state == DRBG_UNINITIALISED
342             && RAND_DRBG_instantiate(&rand_drbg, NULL, 0) == 0)
343         goto err;
344
345     for ( ; count > 0; count -= chunk, out += chunk) {
346         chunk = count;
347         if (chunk > rand_drbg.max_request)
348             chunk = rand_drbg.max_request;
349         ret = RAND_DRBG_generate(&rand_drbg, out, chunk, 0, NULL, 0);
350         if (!ret)
351             goto err;
352     }
353     ret = 1;
354
355 err:
356     CRYPTO_THREAD_unlock(rand_drbg.lock);
357     return ret;
358 }
359
360 static void drbg_cleanup(void)
361 {
362     CRYPTO_THREAD_write_lock(rand_drbg.lock);
363     RAND_DRBG_uninstantiate(&rand_drbg);
364     CRYPTO_THREAD_unlock(rand_drbg.lock);
365 }
366
367 static int drbg_add(const void *buf, int num, double randomness)
368 {
369     unsigned char *in = (unsigned char *)buf;
370     unsigned char *out, *end;
371
372     CRYPTO_THREAD_write_lock(rand_bytes.lock);
373     out = &rand_bytes.buff[rand_bytes.curr];
374     end = &rand_bytes.buff[rand_bytes.size];
375
376     /* Copy whatever fits into the end of the buffer. */
377     for ( ; --num >= 0 && out < end; rand_bytes.curr++)
378         *out++ = *in++;
379
380     /* XOR any the leftover. */
381     while (num > 0) {
382         for (out = rand_bytes.buff; --num >= 0 && out < end; )
383             *out++ ^= *in++;
384     }
385
386     CRYPTO_THREAD_unlock(rand_bytes.lock);
387     return 1;
388 }
389
390 static int drbg_seed(const void *buf, int num)
391 {
392     return drbg_add(buf, num, num);
393 }
394
395 static int drbg_status(void)
396 {
397     int ret;
398
399     CRYPTO_THREAD_write_lock(rand_drbg.lock);
400     ret = rand_drbg.state == DRBG_READY ? 1 : 0;
401     CRYPTO_THREAD_unlock(rand_drbg.lock);
402     return ret;
403 }
404
405 RAND_DRBG rand_drbg; /* The default global DRBG. */
406
407 RAND_METHOD rand_meth = {
408     drbg_seed,
409     drbg_bytes,
410     drbg_cleanup,
411     drbg_add,
412     drbg_bytes,
413     drbg_status
414 };
415
416 RAND_METHOD *RAND_OpenSSL(void)
417 {
418     return &rand_meth;
419 }