Latest update.
This commit is contained in:
+5
-26
@@ -309,37 +309,16 @@ int drbg_hash_init(RAND_DRBG *drbg)
|
||||
RAND_DRBG_HASH *hash = &drbg->data.hash;
|
||||
|
||||
/*
|
||||
* Confirm digest is allowed. Outside FIPS_MODE we allow all non-legacy
|
||||
* digests. Inside FIPS_MODE we only allow approved digests. Also no XOF
|
||||
* digests (such as SHAKE).
|
||||
* Confirm digest is allowed. We allow all digests that are not XOF
|
||||
* (such as SHAKE). In FIPS mode, the fetch will fail for non-approved
|
||||
* digests.
|
||||
*/
|
||||
switch (drbg->type) {
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case NID_sha1:
|
||||
case NID_sha224:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
case NID_sha512_224:
|
||||
case NID_sha512_256:
|
||||
case NID_sha3_224:
|
||||
case NID_sha3_256:
|
||||
case NID_sha3_384:
|
||||
case NID_sha3_512:
|
||||
#ifndef FIPS_MODE
|
||||
case NID_blake2b512:
|
||||
case NID_blake2s256:
|
||||
case NID_sm3:
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
md = EVP_MD_fetch(drbg->libctx, ossl_prov_util_nid_to_name(drbg->type), "");
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0)
|
||||
return 0;
|
||||
|
||||
drbg->meth = &drbg_hash_meth;
|
||||
|
||||
|
||||
+6
-26
@@ -203,37 +203,17 @@ int drbg_hmac_init(RAND_DRBG *drbg)
|
||||
RAND_DRBG_HMAC *hmac = &drbg->data.hmac;
|
||||
|
||||
/*
|
||||
* Confirm digest is allowed. Outside FIPS_MODE we allow all non-legacy
|
||||
* digests. Inside FIPS_MODE we only allow approved digests. Also no XOF
|
||||
* digests (such as SHAKE).
|
||||
* Confirm digest is allowed. We allow all digests that are not XOF
|
||||
* (such as SHAKE). In FIPS mode, the fetch will fail for non-approved
|
||||
* digests.
|
||||
*/
|
||||
switch (drbg->type) {
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case NID_sha1:
|
||||
case NID_sha224:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
case NID_sha512_224:
|
||||
case NID_sha512_256:
|
||||
case NID_sha3_224:
|
||||
case NID_sha3_256:
|
||||
case NID_sha3_384:
|
||||
case NID_sha3_512:
|
||||
#ifndef FIPS_MODE
|
||||
case NID_blake2b512:
|
||||
case NID_blake2s256:
|
||||
case NID_sm3:
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
md = EVP_MD_fetch(drbg->libctx, ossl_prov_util_nid_to_name(drbg->type), "");
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) != 0)
|
||||
return 0;
|
||||
|
||||
drbg->meth = &drbg_hmac_meth;
|
||||
|
||||
if (hmac->ctx == NULL) {
|
||||
|
||||
@@ -503,7 +503,9 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
|
||||
drbg->meth->uninstantiate(drbg);
|
||||
rand_pool_free(drbg->adin_pool);
|
||||
CRYPTO_THREAD_lock_free(drbg->lock);
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
|
||||
#ifndef FIPS_MODE
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data);
|
||||
#endif
|
||||
|
||||
if (drbg->secure)
|
||||
OPENSSL_secure_clear_free(drbg, sizeof(*drbg));
|
||||
@@ -1098,6 +1100,7 @@ int rand_drbg_enable_locking(RAND_DRBG *drbg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* Get and set the EXDATA
|
||||
*/
|
||||
@@ -1110,7 +1113,7 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&drbg->ex_data, idx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following functions provide a RAND_METHOD that works on the
|
||||
|
||||
+22
-18
@@ -311,6 +311,9 @@ int RAND_poll(void)
|
||||
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth == NULL)
|
||||
return 0;
|
||||
|
||||
if (meth == RAND_OpenSSL()) {
|
||||
/* fill random pool and seed the master DRBG */
|
||||
RAND_DRBG *drbg = RAND_DRBG_get0_master();
|
||||
@@ -831,7 +834,7 @@ void RAND_seed(const void *buf, int num)
|
||||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth->seed != NULL)
|
||||
if (meth != NULL && meth->seed != NULL)
|
||||
meth->seed(buf, num);
|
||||
}
|
||||
|
||||
@@ -839,7 +842,7 @@ void RAND_add(const void *buf, int num, double randomness)
|
||||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth->add != NULL)
|
||||
if (meth != NULL && meth->add != NULL)
|
||||
meth->add(buf, num, randomness);
|
||||
}
|
||||
|
||||
@@ -851,18 +854,20 @@ void RAND_add(const void *buf, int num, double randomness)
|
||||
int rand_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
|
||||
{
|
||||
RAND_DRBG *drbg;
|
||||
int ret;
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth != RAND_OpenSSL())
|
||||
return meth->bytes(buf, num);
|
||||
if (meth != NULL && meth != RAND_OpenSSL()) {
|
||||
if (meth->bytes != NULL)
|
||||
return meth->bytes(buf, num);
|
||||
RANDerr(RAND_F_RAND_PRIV_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
drbg = OPENSSL_CTX_get0_private_drbg(ctx);
|
||||
if (drbg == NULL)
|
||||
return 0;
|
||||
if (drbg != NULL)
|
||||
return RAND_DRBG_bytes(drbg, buf, num);
|
||||
|
||||
ret = RAND_DRBG_bytes(drbg, buf, num);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RAND_priv_bytes(unsigned char *buf, int num)
|
||||
@@ -873,10 +878,9 @@ int RAND_priv_bytes(unsigned char *buf, int num)
|
||||
int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
|
||||
{
|
||||
RAND_DRBG *drbg;
|
||||
int ret;
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth != RAND_OpenSSL()) {
|
||||
if (meth != NULL && meth != RAND_OpenSSL()) {
|
||||
if (meth->bytes != NULL)
|
||||
return meth->bytes(buf, num);
|
||||
RANDerr(RAND_F_RAND_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED);
|
||||
@@ -884,11 +888,10 @@ int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
|
||||
}
|
||||
|
||||
drbg = OPENSSL_CTX_get0_public_drbg(ctx);
|
||||
if (drbg == NULL)
|
||||
return 0;
|
||||
if (drbg != NULL)
|
||||
return RAND_DRBG_bytes(drbg, buf, num);
|
||||
|
||||
ret = RAND_DRBG_bytes(drbg, buf, num);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RAND_bytes(unsigned char *buf, int num)
|
||||
@@ -896,13 +899,14 @@ int RAND_bytes(unsigned char *buf, int num)
|
||||
return rand_bytes_ex(NULL, buf, num);
|
||||
}
|
||||
|
||||
#if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE)
|
||||
#if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODE)
|
||||
int RAND_pseudo_bytes(unsigned char *buf, int num)
|
||||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth->pseudorand != NULL)
|
||||
if (meth != NULL && meth->pseudorand != NULL)
|
||||
return meth->pseudorand(buf, num);
|
||||
RANDerr(RAND_F_RAND_PSEUDO_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -911,7 +915,7 @@ int RAND_status(void)
|
||||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth->status != NULL)
|
||||
if (meth != NULL && meth->status != NULL)
|
||||
return meth->status();
|
||||
return 0;
|
||||
}
|
||||
@@ -308,8 +308,10 @@ struct rand_drbg_st {
|
||||
size_t seedlen;
|
||||
DRBG_STATUS state;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* Application data, mainly used in the KATs. */
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
#endif
|
||||
|
||||
/* Implementation specific data */
|
||||
union {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "crypto/rand.h"
|
||||
#include <stdio.h>
|
||||
#include "internal/dso.h"
|
||||
|
||||
#ifdef __linux
|
||||
# include <sys/syscall.h>
|
||||
# ifdef DEVRANDOM_WAIT
|
||||
@@ -81,7 +82,8 @@ static uint64_t get_timer_bits(void);
|
||||
# define OSSL_POSIX_TIMER_OKAY
|
||||
# endif
|
||||
# endif
|
||||
#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */
|
||||
#endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS))
|
||||
|| defined(__DJGPP__) */
|
||||
|
||||
#if defined(OPENSSL_RAND_SEED_NONE)
|
||||
/* none means none. this simplifies the following logic */
|
||||
@@ -851,4 +853,5 @@ static uint64_t get_timer_bits(void)
|
||||
# endif
|
||||
return time(NULL);
|
||||
}
|
||||
#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */
|
||||
#endif /* (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS))
|
||||
|| defined(__DJGPP__) */
|
||||
+90
-11
@@ -32,10 +32,21 @@
|
||||
# pragma message disable DOLLARID
|
||||
# endif
|
||||
|
||||
# include <dlfcn.h> /* SYS$GET_ENTROPY presence */
|
||||
|
||||
# ifndef OPENSSL_RAND_SEED_OS
|
||||
# error "Unsupported seeding method configured; must be os"
|
||||
# endif
|
||||
|
||||
/*
|
||||
* DATA COLLECTION METHOD
|
||||
* ======================
|
||||
*
|
||||
* This is a method to get low quality entropy.
|
||||
* It works by collecting all kinds of statistical data that
|
||||
* VMS offers and using them as random seed.
|
||||
*/
|
||||
|
||||
/* We need to make sure we have the right size pointer in some cases */
|
||||
# if __INITIAL_POINTER_SIZE == 64
|
||||
# pragma pointer_size save
|
||||
@@ -330,7 +341,7 @@ static void massage_JPI(ILE3 *items)
|
||||
*/
|
||||
#define ENTROPY_FACTOR 20
|
||||
|
||||
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
size_t data_collect_method(RAND_POOL *pool)
|
||||
{
|
||||
ILE3 JPI_items_64bit[OSSL_NELEM(JPI_item_data_64bit) + 1];
|
||||
ILE3 RMI_items_64bit[OSSL_NELEM(RMI_item_data_64bit) + 1];
|
||||
@@ -445,15 +456,9 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
* If we can't feed the requirements from the caller, we're in deep trouble.
|
||||
*/
|
||||
if (!ossl_assert(total_length >= bytes_needed)) {
|
||||
char neededstr[20];
|
||||
char availablestr[20];
|
||||
|
||||
BIO_snprintf(neededstr, sizeof(neededstr), "%zu", bytes_needed);
|
||||
BIO_snprintf(availablestr, sizeof(availablestr), "%zu", total_length);
|
||||
RANDerr(RAND_F_RAND_POOL_ACQUIRE_ENTROPY,
|
||||
RAND_R_RANDOM_POOL_UNDERFLOW);
|
||||
ERR_add_error_data(4, "Needed: ", neededstr, ", Available: ",
|
||||
availablestr);
|
||||
ERR_raise_data(ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW,
|
||||
"Needed: %zu, Available: %zu",
|
||||
bytes_needed, total_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -483,7 +488,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp
|
||||
* (where available, which is OpenVMS v8.4 and up) to ensure that
|
||||
* the nonce is unique whith high probability for different process
|
||||
* the nonce is unique with high probability for different process
|
||||
* instances.
|
||||
*/
|
||||
data.pid = getpid();
|
||||
@@ -497,6 +502,80 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SYS$GET_ENTROPY METHOD
|
||||
* ======================
|
||||
*
|
||||
* This is a high entropy method based on a new system service that is
|
||||
* based on getentropy() from FreeBSD 12. It's only used if available,
|
||||
* and its availability is detected at run-time.
|
||||
*
|
||||
* We assume that this function provides full entropy random output.
|
||||
*/
|
||||
#define PUBLIC_VECTORS "SYS$LIBRARY:SYS$PUBLIC_VECTORS.EXE"
|
||||
#define GET_ENTROPY "SYS$GET_ENTROPY"
|
||||
|
||||
static int get_entropy_address_flag = 0;
|
||||
static int (*get_entropy_address)(void *buffer, size_t buffer_size) = NULL;
|
||||
static int init_get_entropy_address(void)
|
||||
{
|
||||
if (get_entropy_address_flag == 0)
|
||||
get_entropy_address = dlsym(dlopen(PUBLIC_VECTORS, 0), GET_ENTROPY);
|
||||
get_entropy_address_flag = 1;
|
||||
return get_entropy_address != NULL;
|
||||
}
|
||||
|
||||
size_t get_entropy_method(RAND_POOL *pool)
|
||||
{
|
||||
/*
|
||||
* The documentation says that SYS$GET_ENTROPY will give a maximum of
|
||||
* 256 bytes of data.
|
||||
*/
|
||||
unsigned char buffer[256];
|
||||
size_t bytes_needed;
|
||||
size_t bytes_to_get = 0;
|
||||
uint32_t status;
|
||||
|
||||
for (bytes_needed = rand_pool_bytes_needed(pool, 1);
|
||||
bytes_needed > 0;
|
||||
bytes_needed -= bytes_to_get) {
|
||||
bytes_to_get =
|
||||
bytes_needed > sizeof(buffer) ? sizeof(buffer) : bytes_needed;
|
||||
|
||||
status = get_entropy_address(buffer, bytes_to_get);
|
||||
if (status == SS$_RETRY) {
|
||||
/* Set to zero so the loop doesn't diminish |bytes_needed| */
|
||||
bytes_to_get = 0;
|
||||
/* Should sleep some amount of time */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status != SS$_NORMAL) {
|
||||
lib$signal(status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rand_pool_add(pool, buffer, bytes_to_get, 8 * bytes_to_get);
|
||||
}
|
||||
|
||||
return rand_pool_entropy_available(pool);
|
||||
}
|
||||
|
||||
/*
|
||||
* MAIN ENTROPY ACQUISITION FUNCTIONS
|
||||
* ==================================
|
||||
*
|
||||
* These functions are called by the RAND / DRBG functions
|
||||
*/
|
||||
|
||||
size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
||||
{
|
||||
if (init_get_entropy_address())
|
||||
return get_entropy_method(pool);
|
||||
return data_collect_method(pool);
|
||||
}
|
||||
|
||||
|
||||
int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
{
|
||||
struct {
|
||||
|
||||
@@ -133,7 +133,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
||||
|
||||
/*
|
||||
* Add process id, thread id, and a high resolution timestamp to
|
||||
* ensure that the nonce is unique whith high probability for
|
||||
* ensure that the nonce is unique with high probability for
|
||||
* different process instances.
|
||||
*/
|
||||
data.pid = GetCurrentProcessId();
|
||||
@@ -163,7 +163,7 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
# if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE)
|
||||
# if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODE)
|
||||
int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
RAND_poll();
|
||||
|
||||
Reference in New Issue
Block a user