2 * Copyright 2011-2017 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/rand.h>
15 #include "internal/thread_once.h"
16 #include "internal/rand_int.h"
18 static RAND_DRBG rand_drbg
; /* The default global DRBG. */
19 static RAND_DRBG priv_drbg
; /* The global private-key DRBG. */
22 * Support framework for NIST SP 800-90A DRBG, AES-CTR mode.
23 * The RAND_DRBG is OpenSSL's pointer to an instance of the DRBG.
25 * The OpenSSL model is to have new and free functions, and that new
26 * does all initialization. That is not the NIST model, which has
27 * instantiation and un-instantiate, and re-use within a new/free
28 * lifecycle. (No doubt this comes from the desire to support hardware
29 * DRBG, where allocation of resources on something like an HSM is
30 * a much bigger deal than just re-setting an allocated resource.)
33 static CRYPTO_ONCE rand_init_drbg
= CRYPTO_ONCE_STATIC_INIT
;
36 * Set/initialize |drbg| to be of type |nid|, with optional |flags|.
37 * Return -2 if the type is not supported, 1 on success and -1 on
40 int RAND_DRBG_set(RAND_DRBG
*drbg
, int nid
, unsigned int flags
)
44 drbg
->state
= DRBG_UNINITIALISED
;
50 RANDerr(RAND_F_RAND_DRBG_SET
, RAND_R_UNSUPPORTED_DRBG_TYPE
);
53 /* Uninitialized; that's okay. */
63 RANDerr(RAND_F_RAND_DRBG_SET
, RAND_R_ERROR_INITIALISING_DRBG
);
68 * Allocate memory and initialize a new DRBG. The |parent|, if not
69 * NULL, will be used to auto-seed this RAND_DRBG as needed.
71 RAND_DRBG
*RAND_DRBG_new(int type
, unsigned int flags
, RAND_DRBG
*parent
)
73 RAND_DRBG
*drbg
= OPENSSL_zalloc(sizeof(*drbg
));
76 RANDerr(RAND_F_RAND_DRBG_NEW
, ERR_R_MALLOC_FAILURE
);
79 drbg
->size
= RANDOMNESS_NEEDED
;
80 drbg
->fork_count
= rand_fork_count
;
81 drbg
->parent
= parent
;
82 if (RAND_DRBG_set(drbg
, type
, flags
) < 0)
86 if (!RAND_DRBG_set_callbacks(drbg
, drbg_entropy_from_parent
,
100 * Uninstantiate |drbg| and free all memory.
102 void RAND_DRBG_free(RAND_DRBG
*drbg
)
104 /* The global DRBG is free'd by rand_cleanup_drbg_int() */
105 if (drbg
== NULL
|| drbg
== &rand_drbg
)
108 ctr_uninstantiate(drbg
);
109 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG
, drbg
, &drbg
->ex_data
);
110 OPENSSL_clear_free(drbg
, sizeof(*drbg
));
114 * Instantiate |drbg|, after it has been initialized. Use |pers| and
115 * |perslen| as prediction-resistance input.
117 int RAND_DRBG_instantiate(RAND_DRBG
*drbg
,
118 const unsigned char *pers
, size_t perslen
)
120 unsigned char *nonce
= NULL
, *entropy
= NULL
;
121 size_t noncelen
= 0, entropylen
= 0;
123 if (perslen
> drbg
->max_perslen
) {
124 RANDerr(RAND_F_RAND_DRBG_INSTANTIATE
,
125 RAND_R_PERSONALISATION_STRING_TOO_LONG
);
128 if (drbg
->state
!= DRBG_UNINITIALISED
) {
129 RANDerr(RAND_F_RAND_DRBG_INSTANTIATE
,
130 drbg
->state
== DRBG_ERROR
? RAND_R_IN_ERROR_STATE
131 : RAND_R_ALREADY_INSTANTIATED
);
135 drbg
->state
= DRBG_ERROR
;
136 if (drbg
->get_entropy
!= NULL
)
137 entropylen
= drbg
->get_entropy(drbg
, &entropy
, drbg
->strength
,
138 drbg
->min_entropylen
, drbg
->max_entropylen
);
139 if (entropylen
< drbg
->min_entropylen
|| entropylen
> drbg
->max_entropylen
) {
140 RANDerr(RAND_F_RAND_DRBG_INSTANTIATE
, RAND_R_ERROR_RETRIEVING_ENTROPY
);
144 if (drbg
->max_noncelen
> 0 && drbg
->get_nonce
!= NULL
) {
145 noncelen
= drbg
->get_nonce(drbg
, &nonce
, drbg
->strength
/ 2,
146 drbg
->min_noncelen
, drbg
->max_noncelen
);
147 if (noncelen
< drbg
->min_noncelen
|| noncelen
> drbg
->max_noncelen
) {
148 RANDerr(RAND_F_RAND_DRBG_INSTANTIATE
, RAND_R_ERROR_RETRIEVING_NONCE
);
153 if (!ctr_instantiate(drbg
, entropy
, entropylen
,
154 nonce
, noncelen
, pers
, perslen
)) {
155 RANDerr(RAND_F_RAND_DRBG_INSTANTIATE
, RAND_R_ERROR_INSTANTIATING_DRBG
);
159 drbg
->state
= DRBG_READY
;
160 drbg
->reseed_counter
= 1;
163 if (entropy
!= NULL
&& drbg
->cleanup_entropy
!= NULL
)
164 drbg
->cleanup_entropy(drbg
, entropy
, entropylen
);
165 if (nonce
!= NULL
&& drbg
->cleanup_nonce
!= NULL
)
166 drbg
->cleanup_nonce(drbg
, nonce
, noncelen
);
167 if (drbg
->state
== DRBG_READY
)
173 * Uninstantiate |drbg|. Must be instantiated before it can be used.
175 int RAND_DRBG_uninstantiate(RAND_DRBG
*drbg
)
177 int ret
= ctr_uninstantiate(drbg
);
179 OPENSSL_cleanse(&drbg
->ctr
, sizeof(drbg
->ctr
));
180 drbg
->state
= DRBG_UNINITIALISED
;
185 * Mix in the specified data to reseed |drbg|.
187 int RAND_DRBG_reseed(RAND_DRBG
*drbg
,
188 const unsigned char *adin
, size_t adinlen
)
190 unsigned char *entropy
= NULL
;
191 size_t entropylen
= 0;
193 if (drbg
->state
== DRBG_ERROR
) {
194 RANDerr(RAND_F_RAND_DRBG_RESEED
, RAND_R_IN_ERROR_STATE
);
197 if (drbg
->state
== DRBG_UNINITIALISED
) {
198 RANDerr(RAND_F_RAND_DRBG_RESEED
, RAND_R_NOT_INSTANTIATED
);
204 else if (adinlen
> drbg
->max_adinlen
) {
205 RANDerr(RAND_F_RAND_DRBG_RESEED
, RAND_R_ADDITIONAL_INPUT_TOO_LONG
);
209 drbg
->state
= DRBG_ERROR
;
210 if (drbg
->get_entropy
!= NULL
)
211 entropylen
= drbg
->get_entropy(drbg
, &entropy
, drbg
->strength
,
212 drbg
->min_entropylen
, drbg
->max_entropylen
);
213 if (entropylen
< drbg
->min_entropylen
|| entropylen
> drbg
->max_entropylen
) {
214 RANDerr(RAND_F_RAND_DRBG_RESEED
, RAND_R_ERROR_RETRIEVING_ENTROPY
);
218 if (!ctr_reseed(drbg
, entropy
, entropylen
, adin
, adinlen
))
220 drbg
->state
= DRBG_READY
;
221 drbg
->reseed_counter
= 1;
224 if (entropy
!= NULL
&& drbg
->cleanup_entropy
!= NULL
)
225 drbg
->cleanup_entropy(drbg
, entropy
, entropylen
);
226 if (drbg
->state
== DRBG_READY
)
232 * Generate |outlen| bytes into the buffer at |out|. Reseed if we need
233 * to or if |prediction_resistance| is set. Additional input can be
234 * sent in |adin| and |adinlen|.
236 int RAND_DRBG_generate(RAND_DRBG
*drbg
, unsigned char *out
, size_t outlen
,
237 int prediction_resistance
,
238 const unsigned char *adin
, size_t adinlen
)
240 if (drbg
->state
== DRBG_ERROR
) {
241 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_IN_ERROR_STATE
);
244 if (drbg
->state
== DRBG_UNINITIALISED
) {
245 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_NOT_INSTANTIATED
);
248 if (outlen
> drbg
->max_request
) {
249 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG
);
252 if (adinlen
> drbg
->max_adinlen
) {
253 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_ADDITIONAL_INPUT_TOO_LONG
);
257 if (drbg
->fork_count
!= rand_fork_count
) {
258 drbg
->fork_count
= rand_fork_count
;
259 drbg
->state
= DRBG_RESEED
;
262 if (drbg
->reseed_counter
>= drbg
->reseed_interval
)
263 drbg
->state
= DRBG_RESEED
;
265 if (drbg
->state
== DRBG_RESEED
|| prediction_resistance
) {
266 if (!RAND_DRBG_reseed(drbg
, adin
, adinlen
)) {
267 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_RESEED_ERROR
);
274 if (!ctr_generate(drbg
, out
, outlen
, adin
, adinlen
)) {
275 drbg
->state
= DRBG_ERROR
;
276 RANDerr(RAND_F_RAND_DRBG_GENERATE
, RAND_R_GENERATE_ERROR
);
280 if (drbg
->reseed_counter
>= drbg
->reseed_interval
)
281 drbg
->state
= DRBG_RESEED
;
283 drbg
->reseed_counter
++;
288 * Set the callbacks for entropy and nonce. We currently don't use
289 * the nonce; that's mainly for the KATs
291 int RAND_DRBG_set_callbacks(RAND_DRBG
*drbg
,
292 RAND_DRBG_get_entropy_fn cb_get_entropy
,
293 RAND_DRBG_cleanup_entropy_fn cb_cleanup_entropy
,
294 RAND_DRBG_get_nonce_fn cb_get_nonce
,
295 RAND_DRBG_cleanup_nonce_fn cb_cleanup_nonce
)
297 if (drbg
->state
!= DRBG_UNINITIALISED
)
299 drbg
->get_entropy
= cb_get_entropy
;
300 drbg
->cleanup_entropy
= cb_cleanup_entropy
;
301 drbg
->get_nonce
= cb_get_nonce
;
302 drbg
->cleanup_nonce
= cb_cleanup_nonce
;
307 * Set the reseed interval.
309 int RAND_DRBG_set_reseed_interval(RAND_DRBG
*drbg
, int interval
)
311 if (interval
< 0 || interval
> MAX_RESEED
)
313 drbg
->reseed_interval
= interval
;
318 * Get and set the EXDATA
320 int RAND_DRBG_set_ex_data(RAND_DRBG
*drbg
, int idx
, void *arg
)
322 return CRYPTO_set_ex_data(&drbg
->ex_data
, idx
, arg
);
325 void *RAND_DRBG_get_ex_data(const RAND_DRBG
*drbg
, int idx
)
327 return CRYPTO_get_ex_data(&drbg
->ex_data
, idx
);
332 * The following functions provide a RAND_METHOD that works on the
333 * global DRBG. They lock.
337 * Creates a global DRBG with default settings.
338 * Returns 1 on success, 0 on failure
340 static int setup_drbg(RAND_DRBG
*drbg
)
344 drbg
->lock
= CRYPTO_THREAD_lock_new();
345 ret
&= drbg
->lock
!= NULL
;
346 drbg
->size
= RANDOMNESS_NEEDED
;
347 drbg
->secure
= CRYPTO_secure_malloc_initialized();
348 /* If you change these parameters, see RANDOMNESS_NEEDED */
349 ret
&= RAND_DRBG_set(drbg
,
350 NID_aes_128_ctr
, RAND_DRBG_FLAG_CTR_USE_DF
) == 1;
351 ret
&= RAND_DRBG_set_callbacks(drbg
, drbg_entropy_from_system
,
352 drbg_release_entropy
, NULL
, NULL
) == 1;
353 ret
&= RAND_DRBG_instantiate(drbg
, NULL
, 0) == 1;
358 * Initialize the global DRBGs on first use.
359 * Returns 1 on success, 0 on failure.
361 DEFINE_RUN_ONCE_STATIC(do_rand_init_drbg
)
365 ret
&= setup_drbg(&rand_drbg
);
366 ret
&= setup_drbg(&priv_drbg
);
371 /* Clean up a DRBG and free it */
372 static void free_drbg(RAND_DRBG
*drbg
)
374 CRYPTO_THREAD_lock_free(drbg
->lock
);
375 RAND_DRBG_uninstantiate(drbg
);
378 /* Clean up the global DRBGs before exit */
379 void rand_cleanup_drbg_int(void)
381 free_drbg(&rand_drbg
);
382 free_drbg(&priv_drbg
);
385 static int drbg_bytes(unsigned char *out
, int count
)
389 RAND_DRBG
*drbg
= RAND_DRBG_get0_global();
394 CRYPTO_THREAD_write_lock(drbg
->lock
);
395 if (drbg
->state
== DRBG_UNINITIALISED
)
398 for ( ; count
> 0; count
-= chunk
, out
+= chunk
) {
400 if (chunk
> drbg
->max_request
)
401 chunk
= drbg
->max_request
;
402 ret
= RAND_DRBG_generate(drbg
, out
, chunk
, 0, NULL
, 0);
409 CRYPTO_THREAD_unlock(drbg
->lock
);
413 static int drbg_add(const void *buf
, int num
, double randomness
)
415 unsigned char *in
= (unsigned char *)buf
;
416 unsigned char *out
, *end
;
418 CRYPTO_THREAD_write_lock(rand_bytes
.lock
);
419 out
= &rand_bytes
.buff
[rand_bytes
.curr
];
420 end
= &rand_bytes
.buff
[rand_bytes
.size
];
422 /* Copy whatever fits into the end of the buffer. */
423 for ( ; --num
>= 0 && out
< end
; rand_bytes
.curr
++)
426 /* XOR any the leftover. */
428 for (out
= rand_bytes
.buff
; --num
>= 0 && out
< end
; )
432 CRYPTO_THREAD_unlock(rand_bytes
.lock
);
436 static int drbg_seed(const void *buf
, int num
)
438 return drbg_add(buf
, num
, num
);
441 static int drbg_status(void)
444 RAND_DRBG
*drbg
= RAND_DRBG_get0_global();
449 CRYPTO_THREAD_write_lock(drbg
->lock
);
450 ret
= drbg
->state
== DRBG_READY
? 1 : 0;
451 CRYPTO_THREAD_unlock(drbg
->lock
);
456 * Get the global public DRBG.
457 * Returns pointer to the DRBG on success, NULL on failure.
459 RAND_DRBG
*RAND_DRBG_get0_global(void)
461 if (!RUN_ONCE(&rand_init_drbg
, do_rand_init_drbg
))
468 * Get the global private DRBG.
469 * Returns pointer to the DRBG on success, NULL on failure.
471 RAND_DRBG
*RAND_DRBG_get0_priv_global(void)
473 if (!RUN_ONCE(&rand_init_drbg
, do_rand_init_drbg
))
479 RAND_METHOD rand_meth
= {
488 RAND_METHOD
*RAND_OpenSSL(void)