Add RAND_DRBG_bytes
Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/4752)
This commit is contained in:
parent
1af66bb724
commit
20928ff635
6 changed files with 104 additions and 2 deletions
|
@ -534,6 +534,28 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
size_t ret;
|
||||
|
||||
additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen);
|
||||
ret = RAND_DRBG_generate(drbg, out, outlen, 0, additional, additional_len);
|
||||
if (additional_len != 0)
|
||||
OPENSSL_secure_clear_free(additional, additional_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the RAND_DRBG callbacks for obtaining entropy and nonce.
|
||||
*
|
||||
|
|
|
@ -215,6 +215,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
int entropy, size_t min_len, size_t max_len);
|
||||
void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen);
|
||||
size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len);
|
||||
|
||||
/* DRBG helpers */
|
||||
int rand_drbg_restart(RAND_DRBG *drbg,
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
#include <openssl/engine.h>
|
||||
#include "internal/thread_once.h"
|
||||
#include "rand_lcl.h"
|
||||
#ifdef OPENSSL_SYS_UNIX
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* non-NULL if default_RAND_meth is ENGINE-provided */
|
||||
|
@ -187,6 +193,74 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate additional data that can be used for the drbg. The data does
|
||||
* not need to contain entropy, but it's useful if it contains at least
|
||||
* some bits that are unpredictable.
|
||||
*
|
||||
* Returns 0 on failure.
|
||||
*
|
||||
* On success it allocates a buffer at |*pout| and returns the length of
|
||||
* the data. The buffer should get freed using OPENSSL_secure_clear_free().
|
||||
*/
|
||||
size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len)
|
||||
{
|
||||
RAND_POOL *pool;
|
||||
CRYPTO_THREAD_ID thread_id;
|
||||
size_t len;
|
||||
#ifdef OPENSSL_SYS_UNIX
|
||||
pid_t pid;
|
||||
struct timespec ts;
|
||||
#elif defined(OPENSSL_SYS_WIN32)
|
||||
DWORD pid;
|
||||
FILETIME ft;
|
||||
LARGE_INTEGER pc;
|
||||
#endif
|
||||
uint32_t tsc = 0;
|
||||
|
||||
pool = RAND_POOL_new(0, 0, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef OPENSSL_SYS_UNIX
|
||||
pid = getpid();
|
||||
RAND_POOL_add(pool, (unsigned char *)&pid, sizeof(pid), 0);
|
||||
#elif defined(OPENSSL_SYS_WIN32)
|
||||
pid = GetCurrentProcessId();
|
||||
RAND_POOL_add(pool, (unsigned char *)&pid, sizeof(pid), 0);
|
||||
#endif
|
||||
|
||||
thread_id = CRYPTO_THREAD_get_current_id();
|
||||
if (thread_id != 0)
|
||||
RAND_POOL_add(pool, (unsigned char *)&thread_id, sizeof(thread_id), 0);
|
||||
|
||||
#ifdef OPENSSL_CPUID_OBJ
|
||||
tsc = OPENSSL_rdtsc();
|
||||
if (tsc != 0)
|
||||
RAND_POOL_add(pool, (unsigned char *)&tsc, sizeof(tsc), 0);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_SYS_UNIX
|
||||
if (tsc == 0 && clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
RAND_POOL_add(pool, (unsigned char *)&ts, sizeof(ts), 0);
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
||||
RAND_POOL_add(pool, (unsigned char *)&ts, sizeof(ts), 0);
|
||||
#elif defined(OPENSSL_SYS_WIN32)
|
||||
if (tsc == 0 && QueryPerformanceCounter(&pc) != 0)
|
||||
RAND_POOL_add(pool, (unsigned char *)&pc, sizeof(pc), 0);
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
RAND_POOL_add(pool, (unsigned char *)&ft, sizeof(ft), 0);
|
||||
#endif
|
||||
|
||||
/* TODO: Use RDSEED? */
|
||||
|
||||
len = RAND_POOL_length(pool);
|
||||
if (len != 0)
|
||||
*pout = RAND_POOL_detach(pool);
|
||||
RAND_POOL_free(pool);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks())
|
||||
|
|
|
@ -42,6 +42,8 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
|||
int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
||||
int prediction_resistance,
|
||||
const unsigned char *adin, size_t adinlen);
|
||||
int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen);
|
||||
|
||||
int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval);
|
||||
int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval);
|
||||
|
||||
|
|
|
@ -5267,9 +5267,11 @@ int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size)
|
|||
* serialization of SSL accesses for the needed concurrency protection
|
||||
* here.
|
||||
*/
|
||||
return RAND_DRBG_generate(s->drbg, rnd, size, 0, NULL, 0);
|
||||
return RAND_DRBG_bytes(s->drbg, rnd, size);
|
||||
}
|
||||
return RAND_bytes(rnd, (int)size);
|
||||
if (size > INT_MAX)
|
||||
return 0;
|
||||
return RAND_bytes(rnd, size);
|
||||
}
|
||||
|
||||
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
|
||||
|
|
|
@ -4501,3 +4501,4 @@ ADMISSION_SYNTAX_new 4441 1_1_1 EXIST::FUNCTION:
|
|||
EVP_sha512_256 4442 1_1_1 EXIST::FUNCTION:
|
||||
EVP_sha512_224 4443 1_1_1 EXIST::FUNCTION:
|
||||
OCSP_basic_sign_ctx 4444 1_1_1 EXIST::FUNCTION:OCSP
|
||||
RAND_DRBG_bytes 4445 1_1_1 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in a new issue