/*
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* 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"
#include "internal/thread_once.h"
#include "internal/rand_int.h"
#include "internal/cryptlib_int.h"
/*
* Support framework for NIST SP 800-90A DRBG
*
* See manual page RAND_DRBG(7) for a general overview.
*
* 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.)
*/
/*
* The three shared DRBG instances
*
* There are three shared DRBG instances: <master>, <public>, and <private>.
*/
/*
* The <master> DRBG
*
* Not used directly by the application, only for reseeding the two other
* DRBGs. It reseeds itself by pulling either randomness from os entropy
* sources or by consuming randomness which was added by RAND_add().
*
* 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
*
* Used by default for generating random bytes using RAND_bytes().
*
* The <public> DRBG is thread-local, i.e., there is one instance per thread.
*/
static CRYPTO_THREAD_LOCAL public_drbg;
/*
* The <private> DRBG
*
* Used by default for generating private keys using RAND_priv_bytes()
*
* The <private> DRBG is thread-local, i.e., there is one instance per thread.
*/
static CRYPTO_THREAD_LOCAL private_drbg;
/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG";
static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
#define RAND_DRBG_TYPE_FLAGS ( \
RAND_DRBG_FLAG_MASTER | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE )
#define RAND_DRBG_TYPE_MASTER 0
#define RAND_DRBG_TYPE_PUBLIC 1
#define RAND_DRBG_TYPE_PRIVATE 2
/* Defaults */
static int rand_drbg_type[3] = {
RAND_DRBG_TYPE, /* Master */
RAND_DRBG_TYPE, /* Public */
RAND_DRBG_TYPE /* Private */
};
static unsigned int rand_drbg_flags[3] = {
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER, /* Master */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */
RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */
};
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;
/* 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 | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS;
static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type);
static RAND_DRBG *rand_drbg_new(int secure,
int type,
unsigned int flags,
RAND_DRBG *parent);
static int is_ctr(int type)
{
switch (type) {
case NID_aes_128_ctr:
case NID_aes_192_ctr:
case NID_aes_256_ctr:
return 1;
default:
return 0;
}
}
static int is_digest(int type