drbg_lib.c 30.0 KB
Newer Older
R
Rich Salz 已提交
1
/*
2
 * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
R
Rich Salz 已提交
3 4 5 6 7 8 9 10 11 12 13 14
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include "rand_lcl.h"
15 16
#include "internal/thread_once.h"
#include "internal/rand_int.h"
17
#include "internal/cryptlib_int.h"
R
Rich Salz 已提交
18 19

/*
20 21 22
 * Support framework for NIST SP 800-90A DRBG
 *
 * See manual page RAND_DRBG(7) for a general overview.
R
Rich Salz 已提交
23
 *
R
Rich Salz 已提交
24 25 26 27 28 29 30 31
 * The OpenSSL model is to have new and free functions, and that new
 * does all initialization.  That is not the NIST model, which has
 * instantiation and un-instantiate, and re-use within a new/free
 * lifecycle.  (No doubt this comes from the desire to support hardware
 * DRBG, where allocation of resources on something like an HSM is
 * a much bigger deal than just re-setting an allocated resource.)
 */

32
/*
33
 * The three shared DRBG instances
34
 *
35 36 37 38 39
 * There are three shared DRBG instances: <master>, <public>, and <private>.
 */

/*
 * The <master> DRBG
40 41 42
 *
 * Not used directly by the application, only for reseeding the two other
 * DRBGs. It reseeds itself by pulling either randomness from os entropy
43
 * sources or by consuming randomness which was added by RAND_add().
44
 *
45 46 47 48 49 50 51
 * The <master> DRBG is a global instance which is accessed concurrently by
 * all threads. The necessary locking is managed automatically by its child
 * DRBG instances during reseeding.
 */
static RAND_DRBG *master_drbg;
/*
 * The <public> DRBG
52
 *
53
 * Used by default for generating random bytes using RAND_bytes().
D
Dr. Matthias St. Pierre 已提交
54
 *
55 56 57 58 59
 * The <public> DRBG is thread-local, i.e., there is one instance per thread.
 */
static CRYPTO_THREAD_LOCAL public_drbg;
/*
 * The <private> DRBG
D
Dr. Matthias St. Pierre 已提交
60
 *
61
 * Used by default for generating private keys using RAND_priv_bytes()
62
 *
63
 * The <private> DRBG is thread-local, i.e., there is one instance per thread.
64
 */
65 66
static CRYPTO_THREAD_LOCAL private_drbg;

67 68 69 70 71


/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG";

72 73
static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;

74 75 76 77 78


static int rand_drbg_type = RAND_DRBG_TYPE;
static unsigned int rand_drbg_flags = RAND_DRBG_FLAGS;

79 80 81 82 83 84
static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL;
static unsigned int slave_reseed_interval  = SLAVE_RESEED_INTERVAL;

static time_t master_reseed_time_interval = MASTER_RESEED_TIME_INTERVAL;
static time_t slave_reseed_time_interval  = SLAVE_RESEED_TIME_INTERVAL;

85 86 87 88
/* A logical OR of all used DRBG flag bits (currently there is only one) */
static const unsigned int rand_drbg_used_flags =
    RAND_DRBG_FLAG_CTR_NO_DF;

89
static RAND_DRBG *drbg_setup(RAND_DRBG *parent);
90 91 92 93 94

static RAND_DRBG *rand_drbg_new(int secure,
                                int type,
                                unsigned int flags,
                                RAND_DRBG *parent);
95

R
Rich Salz 已提交
96
/*
97 98 99
 * Set/initialize |drbg| to be of type |type|, with optional |flags|.
 *
 * If |type| and |flags| are zero, use the defaults
100 101
 *
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
102
 */
103
int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
R
Rich Salz 已提交
104 105 106
{
    int ret = 1;

107 108 109 110 111
    if (type == 0 && flags == 0) {
        type = rand_drbg_type;
        flags = rand_drbg_flags;
    }

R
Rich Salz 已提交
112 113
    drbg->state = DRBG_UNINITIALISED;
    drbg->flags = flags;
114
    drbg->type = type;
R
Rich Salz 已提交
115

116
    switch (type) {
R
Rich Salz 已提交
117 118
    default:
        RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
119
        return 0;
R
Rich Salz 已提交
120 121 122 123 124 125
    case 0:
        /* Uninitialized; that's okay. */
        return 1;
    case NID_aes_128_ctr:
    case NID_aes_192_ctr:
    case NID_aes_256_ctr:
126
        ret = drbg_ctr_init(drbg);
R
Rich Salz 已提交
127 128 129
        break;
    }

130
    if (ret == 0)
R
Rich Salz 已提交
131 132 133 134
        RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
    return ret;
}

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/*
 * Set/initialize default |type| and |flag| for new drbg instances.
 *
 * Returns 1 on success, 0 on failure.
 */
int RAND_DRBG_set_defaults(int type, unsigned int flags)
{
    int ret = 1;

    switch (type) {
    default:
        RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_TYPE);
        return 0;
    case NID_aes_128_ctr:
    case NID_aes_192_ctr:
    case NID_aes_256_ctr:
        break;
    }

154
    if ((flags & ~rand_drbg_used_flags) != 0) {
155 156 157 158 159 160 161 162 163 164 165
        RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS);
        return 0;
    }

    rand_drbg_type  = type;
    rand_drbg_flags = flags;

    return ret;
}


R
Rich Salz 已提交
166
/*
167 168 169
 * Allocate memory and initialize a new DRBG. The DRBG is allocated on
 * the secure heap if |secure| is nonzero and the secure heap is enabled.
 * The |parent|, if not NULL, will be used as random source for reseeding.
170 171
 *
 * Returns a pointer to the new DRBG instance on success, NULL on failure.
R
Rich Salz 已提交
172
 */
173 174 175 176
static RAND_DRBG *rand_drbg_new(int secure,
                                int type,
                                unsigned int flags,
                                RAND_DRBG *parent)
R
Rich Salz 已提交
177
{
178 179
    RAND_DRBG *drbg = secure ?
        OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));
R
Rich Salz 已提交
180

R
Rich Salz 已提交
181
    if (drbg == NULL) {
R
Rich Salz 已提交
182
        RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
183
        return NULL;
R
Rich Salz 已提交
184
    }
185 186

    drbg->secure = secure && CRYPTO_secure_allocated(drbg);
R
Rich Salz 已提交
187
    drbg->fork_count = rand_fork_count;
R
Rich Salz 已提交
188
    drbg->parent = parent;
189 190

    if (parent == NULL) {
191 192 193 194 195 196 197
        drbg->get_entropy = rand_drbg_get_entropy;
        drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
#ifndef RAND_DRBG_GET_RANDOM_NONCE
        drbg->get_nonce = rand_drbg_get_nonce;
        drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
#endif

198 199 200
        drbg->reseed_interval = master_reseed_interval;
        drbg->reseed_time_interval = master_reseed_time_interval;
    } else {
201 202 203 204 205 206 207
        drbg->get_entropy = rand_drbg_get_entropy;
        drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
        /*
         * Do not provide nonce callbacks, the child DRBGs will
         * obtain their nonce using random bits from the parent.
         */

208 209 210 211
        drbg->reseed_interval = slave_reseed_interval;
        drbg->reseed_time_interval = slave_reseed_time_interval;
    }

212
    if (RAND_DRBG_set(drbg, type, flags) == 0)
R
Rich Salz 已提交
213 214
        goto err;

215 216 217 218 219 220 221 222 223 224 225 226
    if (parent != NULL) {
        rand_drbg_lock(parent);
        if (drbg->strength > parent->strength) {
            /*
             * We currently don't support the algorithm from NIST SP 800-90C
             * 10.1.2 to use a weaker DRBG as source
             */
            rand_drbg_unlock(parent);
            RANDerr(RAND_F_RAND_DRBG_NEW, RAND_R_PARENT_STRENGTH_TOO_WEAK);
            goto err;
        }
        rand_drbg_unlock(parent);
K
Kurt Roeckx 已提交
227 228
    }

R
Rich Salz 已提交
229 230
    return drbg;

F
FdaSilvaYY 已提交
231
 err:
232 233 234 235 236
    if (drbg->secure)
        OPENSSL_secure_free(drbg);
    else
        OPENSSL_free(drbg);

R
Rich Salz 已提交
237
    return NULL;
R
Rich Salz 已提交
238 239
}

240 241 242 243 244 245 246 247 248 249
RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
{
    return rand_drbg_new(0, type, flags, parent);
}

RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent)
{
    return rand_drbg_new(1, type, flags, parent);
}

R
Rich Salz 已提交
250
/*
R
Rich Salz 已提交
251
 * Uninstantiate |drbg| and free all memory.
R
Rich Salz 已提交
252
 */
R
Rich Salz 已提交
253
void RAND_DRBG_free(RAND_DRBG *drbg)
R
Rich Salz 已提交
254
{
255
    if (drbg == NULL)
R
Rich Salz 已提交
256 257
        return;

258 259
    if (drbg->meth != NULL)
        drbg->meth->uninstantiate(drbg);
260
    CRYPTO_THREAD_lock_free(drbg->lock);
R
Rich Salz 已提交
261
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
262 263 264 265 266

    if (drbg->secure)
        OPENSSL_secure_clear_free(drbg, sizeof(*drbg));
    else
        OPENSSL_clear_free(drbg, sizeof(*drbg));
R
Rich Salz 已提交
267 268 269
}

/*
R
Rich Salz 已提交
270
 * Instantiate |drbg|, after it has been initialized.  Use |pers| and
R
Rich Salz 已提交
271
 * |perslen| as prediction-resistance input.
B
Benjamin Kaduk 已提交
272 273
 *
 * Requires that drbg->lock is already locked for write, if non-null.
274 275
 *
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
276
 */
R
Rich Salz 已提交
277
int RAND_DRBG_instantiate(RAND_DRBG *drbg,
R
Rich Salz 已提交
278 279 280
                          const unsigned char *pers, size_t perslen)
{
    unsigned char *nonce = NULL, *entropy = NULL;
281
    size_t noncelen = 0, entropylen = 0;
282 283 284
    size_t min_entropy = drbg->strength;
    size_t min_entropylen = drbg->min_entropylen;
    size_t max_entropylen = drbg->max_entropylen;
R
Rich Salz 已提交
285

286
    if (perslen > drbg->max_perslen) {
R
Rich Salz 已提交
287 288
        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
                RAND_R_PERSONALISATION_STRING_TOO_LONG);
R
Rich Salz 已提交
289 290
        goto end;
    }
291

292
    if (drbg->meth == NULL) {
293 294 295 296 297
        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
                RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
        goto end;
    }

R
Rich Salz 已提交
298 299 300 301
    if (drbg->state != DRBG_UNINITIALISED) {
        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
                drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
                                          : RAND_R_ALREADY_INSTANTIATED);
R
Rich Salz 已提交
302 303 304
        goto end;
    }

R
Rich Salz 已提交
305
    drbg->state = DRBG_ERROR;
306 307 308 309 310 311 312 313 314 315 316 317 318

    /*
     * NIST SP800-90Ar1 section 9.1 says you can combine getting the entropy
     * and nonce in 1 call by increasing the entropy with 50% and increasing
     * the minimum length to accomadate the length of the nonce.
     * We do this in case a nonce is require and get_nonce is NULL.
     */
    if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) {
        min_entropy += drbg->strength / 2;
        min_entropylen += drbg->min_noncelen;
        max_entropylen += drbg->max_noncelen;
    }

R
Rich Salz 已提交
319
    if (drbg->get_entropy != NULL)
320 321 322
        entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
                                       min_entropylen, max_entropylen, 0);
    if (entropylen < min_entropylen
F
FdaSilvaYY 已提交
323
            || entropylen > max_entropylen) {
R
Rich Salz 已提交
324
        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY);
R
Rich Salz 已提交
325 326 327
        goto end;
    }

328
    if (drbg->min_noncelen > 0 && drbg->get_nonce != NULL) {
R
Rich Salz 已提交
329
        noncelen = drbg->get_nonce(drbg, &nonce, drbg->strength / 2,
330 331
                                   drbg->min_noncelen, drbg->max_noncelen);
        if (noncelen < drbg->min_noncelen || noncelen > drbg->max_noncelen) {
332
            RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_NONCE);
R
Rich Salz 已提交
333 334 335 336
            goto end;
        }
    }

337
    if (!drbg->meth->instantiate(drbg, entropy, entropylen,
R
Rich Salz 已提交
338
                         nonce, noncelen, pers, perslen)) {
R
Rich Salz 已提交
339
        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_INSTANTIATING_DRBG);
R
Rich Salz 已提交
340 341 342
        goto end;
    }

R
Rich Salz 已提交
343
    drbg->state = DRBG_READY;
344
    drbg->generate_counter = 0;
345
    drbg->reseed_time = time(NULL);
346 347 348 349 350 351
    if (drbg->reseed_counter > 0) {
        if (drbg->parent == NULL)
            drbg->reseed_counter++;
        else
            drbg->reseed_counter = drbg->parent->reseed_counter;
    }
R
Rich Salz 已提交
352

F
FdaSilvaYY 已提交
353
 end:
R
Rich Salz 已提交
354
    if (entropy != NULL && drbg->cleanup_entropy != NULL)
355
        drbg->cleanup_entropy(drbg, entropy, entropylen);
F
FdaSilvaYY 已提交
356
    if (nonce != NULL && drbg->cleanup_nonce != NULL)
357
        drbg->cleanup_nonce(drbg, nonce, noncelen);
358 359 360 361 362 363
    if (drbg->pool != NULL) {
        if (drbg->state == DRBG_READY) {
            RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
                    RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED);
            drbg->state = DRBG_ERROR;
        }
364
        rand_pool_free(drbg->pool);
365 366
        drbg->pool = NULL;
    }
R
Rich Salz 已提交
367
    if (drbg->state == DRBG_READY)
R
Rich Salz 已提交
368 369 370 371 372
        return 1;
    return 0;
}

/*
R
Rich Salz 已提交
373
 * Uninstantiate |drbg|. Must be instantiated before it can be used.
B
Benjamin Kaduk 已提交
374 375
 *
 * Requires that drbg->lock is already locked for write, if non-null.
376 377
 *
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
378
 */
R
Rich Salz 已提交
379
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
R
Rich Salz 已提交
380
{
381
    if (drbg->meth == NULL) {
382 383 384 385 386
        RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
                RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
        return 0;
    }

387 388 389 390
    /* Clear the entire drbg->ctr struct, then reset some important
     * members of the drbg->ctr struct (e.g. keysize, df_ks) to their
     * initial values.
     */
391
    drbg->meth->uninstantiate(drbg);
392
    return RAND_DRBG_set(drbg, drbg->type, drbg->flags);
R
Rich Salz 已提交
393 394 395
}

/*
396
 * Reseed |drbg|, mixing in the specified data
B
Benjamin Kaduk 已提交
397 398
 *
 * Requires that drbg->lock is already locked for write, if non-null.
399 400
 *
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
401
 */
R
Rich Salz 已提交
402
int RAND_DRBG_reseed(RAND_DRBG *drbg,
403 404
                     const unsigned char *adin, size_t adinlen,
                     int prediction_resistance)
R
Rich Salz 已提交
405 406
{
    unsigned char *entropy = NULL;
407
    size_t entropylen = 0;
R
Rich Salz 已提交
408 409 410 411 412 413 414 415

    if (drbg->state == DRBG_ERROR) {
        RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_IN_ERROR_STATE);
        return 0;
    }
    if (drbg->state == DRBG_UNINITIALISED) {
        RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_NOT_INSTANTIATED);
        return 0;
R
Rich Salz 已提交
416 417
    }

418
    if (adin == NULL) {
R
Rich Salz 已提交
419
        adinlen = 0;
420
    } else if (adinlen > drbg->max_adinlen) {
R
Rich Salz 已提交
421 422
        RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
        return 0;
R
Rich Salz 已提交
423 424
    }

R
Rich Salz 已提交
425 426
    drbg->state = DRBG_ERROR;
    if (drbg->get_entropy != NULL)
427
        entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
428 429 430
                                       drbg->min_entropylen,
                                       drbg->max_entropylen,
                                       prediction_resistance);
431
    if (entropylen < drbg->min_entropylen
F
FdaSilvaYY 已提交
432
            || entropylen > drbg->max_entropylen) {
R
Rich Salz 已提交
433
        RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY);
R
Rich Salz 已提交
434 435 436
        goto end;
    }

437
    if (!drbg->meth->reseed(drbg, entropy, entropylen, adin, adinlen))
R
Rich Salz 已提交
438
        goto end;
439

R
Rich Salz 已提交
440
    drbg->state = DRBG_READY;
441
    drbg->generate_counter = 0;
442
    drbg->reseed_time = time(NULL);
443 444 445 446 447 448
    if (drbg->reseed_counter > 0) {
        if (drbg->parent == NULL)
            drbg->reseed_counter++;
        else
            drbg->reseed_counter = drbg->parent->reseed_counter;
    }
R
Rich Salz 已提交
449

F
FdaSilvaYY 已提交
450
 end:
R
Rich Salz 已提交
451
    if (entropy != NULL && drbg->cleanup_entropy != NULL)
452
        drbg->cleanup_entropy(drbg, entropy, entropylen);
R
Rich Salz 已提交
453
    if (drbg->state == DRBG_READY)
R
Rich Salz 已提交
454 455 456 457
        return 1;
    return 0;
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
/*
 * Restart |drbg|, using the specified entropy or additional input
 *
 * Tries its best to get the drbg instantiated by all means,
 * regardless of its current state.
 *
 * Optionally, a |buffer| of |len| random bytes can be passed,
 * which is assumed to contain at least |entropy| bits of entropy.
 *
 * If |entropy| > 0, the buffer content is used as entropy input.
 *
 * If |entropy| == 0, the buffer content is used as additional input
 *
 * Returns 1 on success, 0 on failure.
 *
 * This function is used internally only.
 */
int rand_drbg_restart(RAND_DRBG *drbg,
                      const unsigned char *buffer, size_t len, size_t entropy)
{
    int reseeded = 0;
    const unsigned char *adin = NULL;
    size_t adinlen = 0;

    if (drbg->pool != NULL) {
        RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
484
        rand_pool_free(drbg->pool);
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
        drbg->pool = NULL;
    }

    if (buffer != NULL) {
        if (entropy > 0) {
            if (drbg->max_entropylen < len) {
                RANDerr(RAND_F_RAND_DRBG_RESTART,
                    RAND_R_ENTROPY_INPUT_TOO_LONG);
                return 0;
            }

            if (entropy > 8 * len) {
                RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_ENTROPY_OUT_OF_RANGE);
                return 0;
            }

            /* will be picked up by the rand_drbg_get_entropy() callback */
502
            drbg->pool = rand_pool_new(entropy, len, len);
503 504 505
            if (drbg->pool == NULL)
                return 0;

506
            rand_pool_add(drbg->pool, buffer, len, entropy);
507 508 509 510 511 512 513 514 515 516 517 518
        } else {
            if (drbg->max_adinlen < len) {
                RANDerr(RAND_F_RAND_DRBG_RESTART,
                        RAND_R_ADDITIONAL_INPUT_TOO_LONG);
                return 0;
            }
            adin = buffer;
            adinlen = len;
        }
    }

    /* repair error state */
519
    if (drbg->state == DRBG_ERROR)
520 521 522 523
        RAND_DRBG_uninstantiate(drbg);

    /* repair uninitialized state */
    if (drbg->state == DRBG_UNINITIALISED) {
524 525 526 527
        /* reinstantiate drbg */
        RAND_DRBG_instantiate(drbg,
                              (const unsigned char *) ossl_pers_string,
                              sizeof(ossl_pers_string) - 1);
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
        /* already reseeded. prevent second reseeding below */
        reseeded = (drbg->state == DRBG_READY);
    }

    /* refresh current state if entropy or additional input has been provided */
    if (drbg->state == DRBG_READY) {
        if (adin != NULL) {
            /*
             * mix in additional input without reseeding
             *
             * Similar to RAND_DRBG_reseed(), but the provided additional
             * data |adin| is mixed into the current state without pulling
             * entropy from the trusted entropy source using get_entropy().
             * This is not a reseeding in the strict sense of NIST SP 800-90A.
             */
543
            drbg->meth->reseed(drbg, adin, adinlen, NULL, 0);
544 545
        } else if (reseeded == 0) {
            /* do a full reseeding if it has not been done yet above */
546
            RAND_DRBG_reseed(drbg, NULL, 0, 0);
547 548 549 550 551 552 553
        }
    }

    /* check whether a given entropy pool was cleared properly during reseed */
    if (drbg->pool != NULL) {
        drbg->state = DRBG_ERROR;
        RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
554
        rand_pool_free(drbg->pool);
555 556 557 558 559 560 561
        drbg->pool = NULL;
        return 0;
    }

    return drbg->state == DRBG_READY;
}

R
Rich Salz 已提交
562 563 564 565
/*
 * Generate |outlen| bytes into the buffer at |out|.  Reseed if we need
 * to or if |prediction_resistance| is set.  Additional input can be
 * sent in |adin| and |adinlen|.
566
 *
B
Benjamin Kaduk 已提交
567 568
 * Requires that drbg->lock is already locked for write, if non-null.
 *
569 570
 * Returns 1 on success, 0 on failure.
 *
R
Rich Salz 已提交
571
 */
R
Rich Salz 已提交
572
int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
R
Rich Salz 已提交
573 574 575
                       int prediction_resistance,
                       const unsigned char *adin, size_t adinlen)
{
576 577
    int reseed_required = 0;

578 579 580 581 582 583 584 585 586 587 588 589
    if (drbg->state != DRBG_READY) {
        /* try to recover from previous errors */
        rand_drbg_restart(drbg, NULL, 0, 0);

        if (drbg->state == DRBG_ERROR) {
            RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_IN_ERROR_STATE);
            return 0;
        }
        if (drbg->state == DRBG_UNINITIALISED) {
            RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_NOT_INSTANTIATED);
            return 0;
        }
R
Rich Salz 已提交
590
    }
591

R
Rich Salz 已提交
592 593 594 595
    if (outlen > drbg->max_request) {
        RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG);
        return 0;
    }
596
    if (adinlen > drbg->max_adinlen) {
R
Rich Salz 已提交
597 598
        RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
        return 0;
R
Rich Salz 已提交
599 600
    }

R
Rich Salz 已提交
601 602
    if (drbg->fork_count != rand_fork_count) {
        drbg->fork_count = rand_fork_count;
603
        reseed_required = 1;
R
Rich Salz 已提交
604 605
    }

606 607 608 609
    if (drbg->reseed_interval > 0) {
        if (drbg->generate_counter >= drbg->reseed_interval)
            reseed_required = 1;
    }
610 611 612 613 614 615
    if (drbg->reseed_time_interval > 0) {
        time_t now = time(NULL);
        if (now < drbg->reseed_time
            || now - drbg->reseed_time >= drbg->reseed_time_interval)
            reseed_required = 1;
    }
616 617 618 619
    if (drbg->reseed_counter > 0 && drbg->parent != NULL) {
        if (drbg->reseed_counter != drbg->parent->reseed_counter)
            reseed_required = 1;
    }
R
Rich Salz 已提交
620

621
    if (reseed_required || prediction_resistance) {
622
        if (!RAND_DRBG_reseed(drbg, adin, adinlen, prediction_resistance)) {
R
Rich Salz 已提交
623 624
            RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_RESEED_ERROR);
            return 0;
R
Rich Salz 已提交
625 626 627 628 629
        }
        adin = NULL;
        adinlen = 0;
    }

630
    if (!drbg->meth->generate(drbg, out, outlen, adin, adinlen)) {
R
Rich Salz 已提交
631 632 633
        drbg->state = DRBG_ERROR;
        RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_GENERATE_ERROR);
        return 0;
R
Rich Salz 已提交
634
    }
R
Rich Salz 已提交
635

636
    drbg->generate_counter++;
637

R
Rich Salz 已提交
638 639 640
    return 1;
}

K
Kurt Roeckx 已提交
641 642 643 644 645 646 647 648 649 650 651 652
/*
 * Generates |outlen| random bytes and stores them in |out|. It will
 * using the given |drbg| to generate the bytes.
 *
 * Requires that drbg->lock is already locked for write, if non-null.
 *
 * Returns 1 on success 0 on failure.
 */
int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
{
    unsigned char *additional = NULL;
    size_t additional_len;
653
    size_t chunk;
K
Kurt Roeckx 已提交
654 655 656
    size_t ret;

    additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen);
657 658 659 660 661 662 663 664 665 666 667 668

    for ( ; outlen > 0; outlen -= chunk, out += chunk) {
        chunk = outlen;
        if (chunk > drbg->max_request)
            chunk = drbg->max_request;
        ret = RAND_DRBG_generate(drbg, out, chunk, 0, additional, additional_len);
        if (!ret)
            goto err;
    }
    ret = 1;

err:
K
Kurt Roeckx 已提交
669 670 671 672 673 674
    if (additional_len != 0)
        OPENSSL_secure_clear_free(additional, additional_len);

    return ret;
}

R
Rich Salz 已提交
675
/*
676 677
 * Set the RAND_DRBG callbacks for obtaining entropy and nonce.
 *
678 679
 * Setting the callbacks is allowed only if the drbg has not been
 * initialized yet. Otherwise, the operation will fail.
680
 *
681
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
682
 */
R
Rich Salz 已提交
683
int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
684 685 686 687
                            RAND_DRBG_get_entropy_fn get_entropy,
                            RAND_DRBG_cleanup_entropy_fn cleanup_entropy,
                            RAND_DRBG_get_nonce_fn get_nonce,
                            RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
R
Rich Salz 已提交
688
{
R
Rich Salz 已提交
689
    if (drbg->state != DRBG_UNINITIALISED)
R
Rich Salz 已提交
690
        return 0;
691 692 693 694
    drbg->get_entropy = get_entropy;
    drbg->cleanup_entropy = cleanup_entropy;
    drbg->get_nonce = get_nonce;
    drbg->cleanup_nonce = cleanup_nonce;
R
Rich Salz 已提交
695 696 697 698
    return 1;
}

/*
R
Rich Salz 已提交
699
 * Set the reseed interval.
700 701 702
 *
 * The drbg will reseed automatically whenever the number of generate
 * requests exceeds the given reseed interval. If the reseed interval
703
 * is 0, then this feature is disabled.
704 705
 *
 * Returns 1 on success, 0 on failure.
R
Rich Salz 已提交
706
 */
707
int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval)
R
Rich Salz 已提交
708
{
709
    if (interval > MAX_RESEED_INTERVAL)
710
        return 0;
R
Rich Salz 已提交
711
    drbg->reseed_interval = interval;
712
    return 1;
R
Rich Salz 已提交
713 714
}

715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
/*
 * Set the reseed time interval.
 *
 * The drbg will reseed automatically whenever the time elapsed since
 * the last reseeding exceeds the given reseed time interval. For safety,
 * a reseeding will also occur if the clock has been reset to a smaller
 * value.
 *
 * Returns 1 on success, 0 on failure.
 */
int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval)
{
    if (interval > MAX_RESEED_TIME_INTERVAL)
        return 0;
    drbg->reseed_time_interval = interval;
    return 1;
}

733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
/*
 * Set the default values for reseed (time) intervals of new DRBG instances
 *
 * The default values can be set independently for master DRBG instances
 * (without a parent) and slave DRBG instances (with parent).
 *
 * Returns 1 on success, 0 on failure.
 */

int RAND_DRBG_set_reseed_defaults(
                                  unsigned int _master_reseed_interval,
                                  unsigned int _slave_reseed_interval,
                                  time_t _master_reseed_time_interval,
                                  time_t _slave_reseed_time_interval
                                  )
{
    if (_master_reseed_interval > MAX_RESEED_INTERVAL
        || _slave_reseed_interval > MAX_RESEED_INTERVAL)
        return 0;

    if (_master_reseed_time_interval > MAX_RESEED_TIME_INTERVAL
        || _slave_reseed_time_interval > MAX_RESEED_TIME_INTERVAL)
        return 0;

    master_reseed_interval = _master_reseed_interval;
    slave_reseed_interval = _slave_reseed_interval;

    master_reseed_time_interval = _master_reseed_time_interval;
    slave_reseed_time_interval = _slave_reseed_time_interval;

    return 1;
}
D
Dr. Matthias St. Pierre 已提交
765 766 767 768 769 770 771

/*
 * Locks the given drbg. Locking a drbg which does not have locking
 * enabled is considered a successful no-op.
 *
 * Returns 1 on success, 0 on failure.
 */
772
int rand_drbg_lock(RAND_DRBG *drbg)
D
Dr. Matthias St. Pierre 已提交
773 774 775 776 777 778 779 780 781 782 783 784 785
{
    if (drbg->lock != NULL)
        return CRYPTO_THREAD_write_lock(drbg->lock);

    return 1;
}

/*
 * Unlocks the given drbg. Unlocking a drbg which does not have locking
 * enabled is considered a successful no-op.
 *
 * Returns 1 on success, 0 on failure.
 */
786
int rand_drbg_unlock(RAND_DRBG *drbg)
D
Dr. Matthias St. Pierre 已提交
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
{
    if (drbg->lock != NULL)
        return CRYPTO_THREAD_unlock(drbg->lock);

    return 1;
}

/*
 * Enables locking for the given drbg
 *
 * Locking can only be enabled if the random generator
 * is in the uninitialized state.
 *
 * Returns 1 on success, 0 on failure.
 */
802
int rand_drbg_enable_locking(RAND_DRBG *drbg)
D
Dr. Matthias St. Pierre 已提交
803 804 805 806 807 808 809 810
{
    if (drbg->state != DRBG_UNINITIALISED) {
        RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
                RAND_R_DRBG_ALREADY_INITIALIZED);
        return 0;
    }

    if (drbg->lock == NULL) {
811
        if (drbg->parent != NULL && drbg->parent->lock == NULL) {
D
Dr. Matthias St. Pierre 已提交
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
            RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
                    RAND_R_PARENT_LOCKING_NOT_ENABLED);
            return 0;
        }

        drbg->lock = CRYPTO_THREAD_lock_new();
        if (drbg->lock == NULL) {
            RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
                    RAND_R_FAILED_TO_CREATE_LOCK);
            return 0;
        }
    }

    return 1;
}

R
Rich Salz 已提交
828 829 830
/*
 * Get and set the EXDATA
 */
R
Rich Salz 已提交
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg)
{
    return CRYPTO_set_ex_data(&drbg->ex_data, idx, arg);
}

void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx)
{
    return CRYPTO_get_ex_data(&drbg->ex_data, idx);
}


/*
 * The following functions provide a RAND_METHOD that works on the
 * global DRBG.  They lock.
 */

847
/*
848 849
 * Allocates a new global DRBG on the secure heap (if enabled) and
 * initializes it with default settings.
850 851
 *
 * Returns a pointer to the new DRBG instance on success, NULL on failure.
852
 */
853
static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
854
{
855
    RAND_DRBG *drbg;
856

857
    drbg = RAND_DRBG_secure_new(rand_drbg_type, rand_drbg_flags, parent);
858 859 860
    if (drbg == NULL)
        return NULL;

861 862
    /* Only the master DRBG needs to have a lock */
    if (parent == NULL && rand_drbg_enable_locking(drbg) == 0)
863
        goto err;
864 865 866 867

    /* enable seed propagation */
    drbg->reseed_counter = 1;

868
    /*
869
     * Ignore instantiation error to support just-in-time instantiation.
870 871 872 873
     *
     * The state of the drbg will be checked in RAND_DRBG_generate() and
     * an automatic recovery is attempted.
     */
874 875 876
    (void)RAND_DRBG_instantiate(drbg,
                                (const unsigned char *) ossl_pers_string,
                                sizeof(ossl_pers_string) - 1);
877 878 879
    return drbg;

err:
880
    RAND_DRBG_free(drbg);
881
    return NULL;
882 883 884 885 886 887
}

/*
 * Initialize the global DRBGs on first use.
 * Returns 1 on success, 0 on failure.
 */
888
DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init)
889
{
890 891 892 893 894 895 896
    /*
     * ensure that libcrypto is initialized, otherwise the
     * DRBG locks are not cleaned up properly
     */
    if (!OPENSSL_init_crypto(0, NULL))
        return 0;

897 898
    if (!CRYPTO_THREAD_init_local(&private_drbg, NULL))
        return 0;
899

900 901
    if (!CRYPTO_THREAD_init_local(&public_drbg, NULL))
        goto err1;
902

903 904 905
    master_drbg = drbg_setup(NULL);
    if (master_drbg == NULL)
        goto err2;
906

907
    return 1;
908 909 910 911 912 913

err2:
    CRYPTO_THREAD_cleanup_local(&public_drbg);
err1:
    CRYPTO_THREAD_cleanup_local(&private_drbg);
    return 0;
914 915 916
}

/* Clean up the global DRBGs before exit */
917
void rand_drbg_cleanup_int(void)
918
{
919 920 921
    if (master_drbg != NULL) {
        RAND_DRBG_free(master_drbg);
        master_drbg = NULL;
922

923 924 925
        CRYPTO_THREAD_cleanup_local(&private_drbg);
        CRYPTO_THREAD_cleanup_local(&public_drbg);
    }
926 927
}

928
void drbg_delete_thread_state(void)
929 930 931
{
    RAND_DRBG *drbg;

932
    drbg = CRYPTO_THREAD_get_local(&public_drbg);
933
    CRYPTO_THREAD_set_local(&public_drbg, NULL);
934 935
    RAND_DRBG_free(drbg);

936
    drbg = CRYPTO_THREAD_get_local(&private_drbg);
937
    CRYPTO_THREAD_set_local(&private_drbg, NULL);
938
    RAND_DRBG_free(drbg);
939 940
}

941
/* Implements the default OpenSSL RAND_bytes() method */
R
Rich Salz 已提交
942 943
static int drbg_bytes(unsigned char *out, int count)
{
944
    int ret;
945
    RAND_DRBG *drbg = RAND_DRBG_get0_public();
R
Rich Salz 已提交
946

947 948 949
    if (drbg == NULL)
        return 0;

950 951
    ret = RAND_DRBG_bytes(drbg, out, count);

R
Rich Salz 已提交
952 953 954
    return ret;
}

955
/* Implements the default OpenSSL RAND_add() method */
R
Rich Salz 已提交
956 957
static int drbg_add(const void *buf, int num, double randomness)
{
958
    int ret = 0;
959
    RAND_DRBG *drbg = RAND_DRBG_get0_master();
R
Rich Salz 已提交
960

961 962
    if (drbg == NULL)
        return 0;
R
Rich Salz 已提交
963

964 965
    if (num < 0 || randomness < 0.0)
        return 0;
R
Rich Salz 已提交
966

967 968 969 970 971 972 973 974
    if (randomness > (double)drbg->max_entropylen) {
        /*
         * The purpose of this check is to bound |randomness| by a
         * relatively small value in order to prevent an integer
         * overflow when multiplying by 8 in the rand_drbg_restart()
         * call below.
         */
        return 0;
R
Rich Salz 已提交
975 976
    }

977
    rand_drbg_lock(drbg);
978 979 980
    ret = rand_drbg_restart(drbg, buf,
                            (size_t)(unsigned int)num,
                            (size_t)(8*randomness));
981
    rand_drbg_unlock(drbg);
982 983

    return ret;
R
Rich Salz 已提交
984 985
}

986
/* Implements the default OpenSSL RAND_seed() method */
R
Rich Salz 已提交
987 988 989 990 991
static int drbg_seed(const void *buf, int num)
{
    return drbg_add(buf, num, num);
}

992
/* Implements the default OpenSSL RAND_status() method */
R
Rich Salz 已提交
993
static int drbg_status(void)
R
Rich Salz 已提交
994
{
R
Rich Salz 已提交
995
    int ret;
996
    RAND_DRBG *drbg = RAND_DRBG_get0_master();
997 998 999

    if (drbg == NULL)
        return 0;
R
Rich Salz 已提交
1000

1001
    rand_drbg_lock(drbg);
1002
    ret = drbg->state == DRBG_READY ? 1 : 0;
1003
    rand_drbg_unlock(drbg);
R
Rich Salz 已提交
1004
    return ret;
R
Rich Salz 已提交
1005 1006
}

1007
/*
1008 1009 1010 1011 1012 1013 1014 1015 1016
 * Get the master DRBG.
 * Returns pointer to the DRBG on success, NULL on failure.
 *
 */
RAND_DRBG *RAND_DRBG_get0_master(void)
{
    if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
        return NULL;

1017
    return master_drbg;
1018 1019 1020 1021
}

/*
 * Get the public DRBG.
1022 1023
 * Returns pointer to the DRBG on success, NULL on failure.
 */
1024
RAND_DRBG *RAND_DRBG_get0_public(void)
1025
{
1026 1027
    RAND_DRBG *drbg;

1028
    if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
1029 1030
        return NULL;

1031
    drbg = CRYPTO_THREAD_get_local(&public_drbg);
1032
    if (drbg == NULL) {
1033 1034
        if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
            return NULL;
1035 1036
        drbg = drbg_setup(master_drbg);
        CRYPTO_THREAD_set_local(&public_drbg, drbg);
1037 1038
    }
    return drbg;
1039 1040 1041
}

/*
1042
 * Get the private DRBG.
1043 1044
 * Returns pointer to the DRBG on success, NULL on failure.
 */
1045
RAND_DRBG *RAND_DRBG_get0_private(void)
1046
{
1047 1048
    RAND_DRBG *drbg;

1049
    if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
1050 1051
        return NULL;

1052
    drbg = CRYPTO_THREAD_get_local(&private_drbg);
1053
    if (drbg == NULL) {
1054 1055
        if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
            return NULL;
1056 1057
        drbg = drbg_setup(master_drbg);
        CRYPTO_THREAD_set_local(&private_drbg, drbg);
1058 1059
    }
    return drbg;
1060 1061
}

R
Rich Salz 已提交
1062 1063 1064
RAND_METHOD rand_meth = {
    drbg_seed,
    drbg_bytes,
1065
    NULL,
R
Rich Salz 已提交
1066 1067 1068 1069 1070 1071
    drbg_add,
    drbg_bytes,
    drbg_status
};

RAND_METHOD *RAND_OpenSSL(void)
R
Rich Salz 已提交
1072
{
R
Rich Salz 已提交
1073
    return &rand_meth;
R
Rich Salz 已提交
1074
}