mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
AppleM1: Update openssl to v1.1.1l
This commit is contained in:
parent
1fe12b8e8c
commit
b787656eea
990 changed files with 13406 additions and 18710 deletions
|
@ -2,3 +2,5 @@ LIBS=../../libcrypto
|
|||
SOURCE[../../libcrypto]=\
|
||||
randfile.c rand_lib.c rand_err.c rand_egd.c \
|
||||
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c
|
||||
|
||||
INCLUDE[drbg_ctr.o]=../modes
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2020 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
|
||||
|
@ -12,28 +12,25 @@
|
|||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "modes_local.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "rand_lcl.h"
|
||||
#include "rand_local.h"
|
||||
|
||||
/*
|
||||
* Implementation of NIST SP 800-90A CTR DRBG.
|
||||
*/
|
||||
|
||||
static void inc_128(RAND_DRBG_CTR *ctr)
|
||||
{
|
||||
int i;
|
||||
unsigned char c;
|
||||
unsigned char *p = &ctr->V[15];
|
||||
unsigned char *p = &ctr->V[0];
|
||||
u32 n = 16, c = 1;
|
||||
|
||||
for (i = 0; i < 16; i++, p--) {
|
||||
c = *p;
|
||||
c++;
|
||||
*p = c;
|
||||
if (c != 0) {
|
||||
/* If we didn't wrap around, we're done. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
do {
|
||||
--n;
|
||||
c += p[n];
|
||||
p[n] = (u8)c;
|
||||
c >>= 8;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
|
||||
|
@ -66,15 +63,15 @@ static void ctr_XOR(RAND_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
|
|||
* Process a complete block using BCC algorithm of SP 800-90A 10.3.3
|
||||
*/
|
||||
__owur static int ctr_BCC_block(RAND_DRBG_CTR *ctr, unsigned char *out,
|
||||
const unsigned char *in)
|
||||
const unsigned char *in, int len)
|
||||
{
|
||||
int i, outlen = AES_BLOCK_SIZE;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (i = 0; i < len; i++)
|
||||
out[i] ^= in[i];
|
||||
|
||||
if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
|
||||
|| outlen != len)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -85,12 +82,16 @@ __owur static int ctr_BCC_block(RAND_DRBG_CTR *ctr, unsigned char *out,
|
|||
*/
|
||||
__owur static int ctr_BCC_blocks(RAND_DRBG_CTR *ctr, const unsigned char *in)
|
||||
{
|
||||
if (!ctr_BCC_block(ctr, ctr->KX, in)
|
||||
|| !ctr_BCC_block(ctr, ctr->KX + 16, in))
|
||||
return 0;
|
||||
if (ctr->keylen != 16 && !ctr_BCC_block(ctr, ctr->KX + 32, in))
|
||||
return 0;
|
||||
return 1;
|
||||
unsigned char in_tmp[48];
|
||||
unsigned char num_of_blk = 2;
|
||||
|
||||
memcpy(in_tmp, in, 16);
|
||||
memcpy(in_tmp + 16, in, 16);
|
||||
if (ctr->keylen != 16) {
|
||||
memcpy(in_tmp + 32, in, 16);
|
||||
num_of_blk = 3;
|
||||
}
|
||||
return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -99,19 +100,14 @@ __owur static int ctr_BCC_blocks(RAND_DRBG_CTR *ctr, const unsigned char *in)
|
|||
*/
|
||||
__owur static int ctr_BCC_init(RAND_DRBG_CTR *ctr)
|
||||
{
|
||||
unsigned char bltmp[48] = {0};
|
||||
unsigned char num_of_blk;
|
||||
|
||||
memset(ctr->KX, 0, 48);
|
||||
memset(ctr->bltmp, 0, 16);
|
||||
if (!ctr_BCC_block(ctr, ctr->KX, ctr->bltmp))
|
||||
return 0;
|
||||
ctr->bltmp[3] = 1;
|
||||
if (!ctr_BCC_block(ctr, ctr->KX + 16, ctr->bltmp))
|
||||
return 0;
|
||||
if (ctr->keylen != 16) {
|
||||
ctr->bltmp[3] = 2;
|
||||
if (!ctr_BCC_block(ctr, ctr->KX + 32, ctr->bltmp))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
num_of_blk = ctr->keylen == 16 ? 2 : 3;
|
||||
bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
|
||||
bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
|
||||
return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -200,20 +196,20 @@ __owur static int ctr_df(RAND_DRBG_CTR *ctr,
|
|||
|| !ctr_BCC_final(ctr))
|
||||
return 0;
|
||||
/* Set up key K */
|
||||
if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->KX, NULL, 1))
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
|
||||
return 0;
|
||||
/* X follows key K */
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->KX, &outlen, ctr->KX + ctr->keylen,
|
||||
if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
|
||||
AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 16, &outlen, ctr->KX,
|
||||
if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
|
||||
AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
if (ctr->keylen != 16)
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->KX + 32, &outlen, ctr->KX + 16,
|
||||
AES_BLOCK_SIZE)
|
||||
if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
|
||||
ctr->KX + 16, AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -232,31 +228,25 @@ __owur static int ctr_update(RAND_DRBG *drbg,
|
|||
{
|
||||
RAND_DRBG_CTR *ctr = &drbg->data.ctr;
|
||||
int outlen = AES_BLOCK_SIZE;
|
||||
unsigned char V_tmp[48], out[48];
|
||||
unsigned char len;
|
||||
|
||||
/* correct key is already set up. */
|
||||
memcpy(V_tmp, ctr->V, 16);
|
||||
inc_128(ctr);
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outlen, ctr->V, AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
|
||||
/* If keylen longer than 128 bits need extra encrypt */
|
||||
if (ctr->keylen != 16) {
|
||||
memcpy(V_tmp + 16, ctr->V, 16);
|
||||
if (ctr->keylen == 16) {
|
||||
len = 32;
|
||||
} else {
|
||||
inc_128(ctr);
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->K+16, &outlen, ctr->V,
|
||||
AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
memcpy(V_tmp + 32, ctr->V, 16);
|
||||
len = 48;
|
||||
}
|
||||
inc_128(ctr);
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->V, &outlen, ctr->V, AES_BLOCK_SIZE)
|
||||
|| outlen != AES_BLOCK_SIZE)
|
||||
if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
|
||||
|| outlen != len)
|
||||
return 0;
|
||||
|
||||
/* If 192 bit key part of V is on end of K */
|
||||
if (ctr->keylen == 24) {
|
||||
memcpy(ctr->V + 8, ctr->V, 8);
|
||||
memcpy(ctr->V, ctr->K + 24, 8);
|
||||
}
|
||||
memcpy(ctr->K, out, ctr->keylen);
|
||||
memcpy(ctr->V, out + ctr->keylen, 16);
|
||||
|
||||
if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
|
||||
/* If no input reuse existing derived value */
|
||||
|
@ -271,7 +261,8 @@ __owur static int ctr_update(RAND_DRBG *drbg,
|
|||
ctr_XOR(ctr, in2, in2len);
|
||||
}
|
||||
|
||||
if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
|
||||
|| !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -288,8 +279,10 @@ __owur static int drbg_ctr_instantiate(RAND_DRBG *drbg,
|
|||
|
||||
memset(ctr->K, 0, sizeof(ctr->K));
|
||||
memset(ctr->V, 0, sizeof(ctr->V));
|
||||
if (!EVP_CipherInit_ex(ctr->ctx, ctr->cipher, NULL, ctr->K, NULL, 1))
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
|
||||
return 0;
|
||||
|
||||
inc_128(ctr);
|
||||
if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -299,20 +292,40 @@ __owur static int drbg_ctr_reseed(RAND_DRBG *drbg,
|
|||
const unsigned char *entropy, size_t entropylen,
|
||||
const unsigned char *adin, size_t adinlen)
|
||||
{
|
||||
RAND_DRBG_CTR *ctr = &drbg->data.ctr;
|
||||
|
||||
if (entropy == NULL)
|
||||
return 0;
|
||||
|
||||
inc_128(ctr);
|
||||
if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ctr96_inc(unsigned char *counter)
|
||||
{
|
||||
u32 n = 12, c = 1;
|
||||
|
||||
do {
|
||||
--n;
|
||||
c += counter[n];
|
||||
counter[n] = (u8)c;
|
||||
c >>= 8;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
__owur static int drbg_ctr_generate(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen,
|
||||
const unsigned char *adin, size_t adinlen)
|
||||
{
|
||||
RAND_DRBG_CTR *ctr = &drbg->data.ctr;
|
||||
unsigned int ctr32, blocks;
|
||||
int outl, buflen;
|
||||
|
||||
if (adin != NULL && adinlen != 0) {
|
||||
inc_128(ctr);
|
||||
|
||||
if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
|
||||
return 0;
|
||||
/* This means we reuse derived value */
|
||||
|
@ -324,28 +337,53 @@ __owur static int drbg_ctr_generate(RAND_DRBG *drbg,
|
|||
adinlen = 0;
|
||||
}
|
||||
|
||||
for ( ; ; ) {
|
||||
int outl = AES_BLOCK_SIZE;
|
||||
inc_128(ctr);
|
||||
|
||||
if (outlen == 0) {
|
||||
inc_128(ctr);
|
||||
if (outlen < 16) {
|
||||
/* Use K as temp space as it will be updated */
|
||||
if (!EVP_CipherUpdate(ctr->ctx, ctr->K, &outl, ctr->V,
|
||||
AES_BLOCK_SIZE)
|
||||
|| outl != AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
memcpy(out, ctr->K, outlen);
|
||||
break;
|
||||
}
|
||||
if (!EVP_CipherUpdate(ctr->ctx, out, &outl, ctr->V, AES_BLOCK_SIZE)
|
||||
|| outl != AES_BLOCK_SIZE)
|
||||
|
||||
if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
|
||||
return 0;
|
||||
out += 16;
|
||||
outlen -= 16;
|
||||
if (outlen == 0)
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(out, 0, outlen);
|
||||
|
||||
do {
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_ctr,
|
||||
NULL, NULL, NULL, ctr->V, -1))
|
||||
return 0;
|
||||
|
||||
/*-
|
||||
* outlen has type size_t while EVP_CipherUpdate takes an
|
||||
* int argument and thus cannot be guaranteed to process more
|
||||
* than 2^31-1 bytes at a time. We process such huge generate
|
||||
* requests in 2^30 byte chunks, which is the greatest multiple
|
||||
* of AES block size lower than or equal to 2^31-1.
|
||||
*/
|
||||
buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
|
||||
blocks = (buflen + 15) / 16;
|
||||
|
||||
ctr32 = GETU32(ctr->V + 12) + blocks;
|
||||
if (ctr32 < blocks) {
|
||||
/* 32-bit counter overflow into V. */
|
||||
if (ctr32 != 0) {
|
||||
blocks -= ctr32;
|
||||
buflen = blocks * 16;
|
||||
ctr32 = 0;
|
||||
}
|
||||
ctr96_inc(ctr->V);
|
||||
}
|
||||
PUTU32(ctr->V + 12, ctr32);
|
||||
|
||||
if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
|
||||
|| outl != buflen)
|
||||
return 0;
|
||||
|
||||
out += buflen;
|
||||
outlen -= buflen;
|
||||
} while (outlen);
|
||||
|
||||
if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -353,7 +391,8 @@ __owur static int drbg_ctr_generate(RAND_DRBG *drbg,
|
|||
|
||||
static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
|
||||
{
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_ecb);
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_ctr);
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
|
||||
OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
|
||||
return 1;
|
||||
|
@ -377,25 +416,36 @@ int drbg_ctr_init(RAND_DRBG *drbg)
|
|||
return 0;
|
||||
case NID_aes_128_ctr:
|
||||
keylen = 16;
|
||||
ctr->cipher = EVP_aes_128_ecb();
|
||||
ctr->cipher_ecb = EVP_aes_128_ecb();
|
||||
ctr->cipher_ctr = EVP_aes_128_ctr();
|
||||
break;
|
||||
case NID_aes_192_ctr:
|
||||
keylen = 24;
|
||||
ctr->cipher = EVP_aes_192_ecb();
|
||||
ctr->cipher_ecb = EVP_aes_192_ecb();
|
||||
ctr->cipher_ctr = EVP_aes_192_ctr();
|
||||
break;
|
||||
case NID_aes_256_ctr:
|
||||
keylen = 32;
|
||||
ctr->cipher = EVP_aes_256_ecb();
|
||||
ctr->cipher_ecb = EVP_aes_256_ecb();
|
||||
ctr->cipher_ctr = EVP_aes_256_ctr();
|
||||
break;
|
||||
}
|
||||
|
||||
drbg->meth = &drbg_ctr_meth;
|
||||
|
||||
ctr->keylen = keylen;
|
||||
if (ctr->ctx == NULL)
|
||||
ctr->ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctr->ctx == NULL)
|
||||
if (ctr->ctx_ecb == NULL)
|
||||
ctr->ctx_ecb = EVP_CIPHER_CTX_new();
|
||||
if (ctr->ctx_ctr == NULL)
|
||||
ctr->ctx_ctr = EVP_CIPHER_CTX_new();
|
||||
if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL
|
||||
|| !EVP_CipherInit_ex(ctr->ctx_ecb,
|
||||
ctr->cipher_ecb, NULL, NULL, NULL, 1)
|
||||
|| !EVP_CipherInit_ex(ctr->ctx_ctr,
|
||||
ctr->cipher_ctr, NULL, NULL, NULL, 1))
|
||||
return 0;
|
||||
|
||||
drbg->meth = &drbg_ctr_meth;
|
||||
drbg->strength = keylen * 8;
|
||||
drbg->seedlen = keylen + 16;
|
||||
|
||||
|
@ -413,7 +463,8 @@ int drbg_ctr_init(RAND_DRBG *drbg)
|
|||
if (ctr->ctx_df == NULL)
|
||||
return 0;
|
||||
/* Set key schedule for df_key */
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_df, ctr->cipher, NULL, df_key, NULL, 1))
|
||||
if (!EVP_CipherInit_ex(ctr->ctx_df,
|
||||
ctr->cipher_ecb, NULL, df_key, NULL, 1))
|
||||
return 0;
|
||||
|
||||
drbg->min_entropylen = ctr->keylen;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2020 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
|
||||
|
@ -11,10 +11,10 @@
|
|||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "rand_lcl.h"
|
||||
#include "rand_local.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/rand_int.h"
|
||||
#include "internal/cryptlib_int.h"
|
||||
#include "crypto/rand.h"
|
||||
#include "crypto/cryptlib.h"
|
||||
|
||||
/*
|
||||
* Support framework for NIST SP 800-90A DRBG
|
||||
|
@ -188,8 +188,8 @@ static RAND_DRBG *rand_drbg_new(int secure,
|
|||
unsigned int flags,
|
||||
RAND_DRBG *parent)
|
||||
{
|
||||
RAND_DRBG *drbg = secure ?
|
||||
OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));
|
||||
RAND_DRBG *drbg = secure ? OPENSSL_secure_zalloc(sizeof(*drbg))
|
||||
: OPENSSL_zalloc(sizeof(*drbg));
|
||||
|
||||
if (drbg == NULL) {
|
||||
RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
|
@ -197,7 +197,7 @@ static RAND_DRBG *rand_drbg_new(int secure,
|
|||
}
|
||||
|
||||
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
|
||||
drbg->fork_count = rand_fork_count;
|
||||
drbg->fork_id = openssl_get_fork_id();
|
||||
drbg->parent = parent;
|
||||
|
||||
if (parent == NULL) {
|
||||
|
@ -318,7 +318,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
|||
/*
|
||||
* 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.
|
||||
* the minimum length to accommodate 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) {
|
||||
|
@ -327,13 +327,6 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
|||
max_entropylen += drbg->max_noncelen;
|
||||
}
|
||||
|
||||
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (drbg->reseed_next_counter) {
|
||||
drbg->reseed_next_counter++;
|
||||
if(!drbg->reseed_next_counter)
|
||||
drbg->reseed_next_counter = 1;
|
||||
}
|
||||
|
||||
if (drbg->get_entropy != NULL)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
|
||||
min_entropylen, max_entropylen, 0);
|
||||
|
@ -359,9 +352,15 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
|||
}
|
||||
|
||||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 1;
|
||||
drbg->generate_counter = 1;
|
||||
drbg->reseed_time = time(NULL);
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
if (drbg->enable_reseed_propagation) {
|
||||
if (drbg->parent == NULL)
|
||||
tsan_counter(&drbg->reseed_counter);
|
||||
else
|
||||
tsan_store(&drbg->reseed_counter,
|
||||
tsan_load(&drbg->parent->reseed_counter));
|
||||
}
|
||||
|
||||
end:
|
||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||
|
@ -428,14 +427,6 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
|||
}
|
||||
|
||||
drbg->state = DRBG_ERROR;
|
||||
|
||||
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (drbg->reseed_next_counter) {
|
||||
drbg->reseed_next_counter++;
|
||||
if(!drbg->reseed_next_counter)
|
||||
drbg->reseed_next_counter = 1;
|
||||
}
|
||||
|
||||
if (drbg->get_entropy != NULL)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
|
||||
drbg->min_entropylen,
|
||||
|
@ -451,9 +442,15 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
|||
goto end;
|
||||
|
||||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 1;
|
||||
drbg->generate_counter = 1;
|
||||
drbg->reseed_time = time(NULL);
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
if (drbg->enable_reseed_propagation) {
|
||||
if (drbg->parent == NULL)
|
||||
tsan_counter(&drbg->reseed_counter);
|
||||
else
|
||||
tsan_store(&drbg->reseed_counter,
|
||||
tsan_load(&drbg->parent->reseed_counter));
|
||||
}
|
||||
|
||||
end:
|
||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||
|
@ -554,7 +551,9 @@ int rand_drbg_restart(RAND_DRBG *drbg,
|
|||
drbg->meth->reseed(drbg, adin, adinlen, NULL, 0);
|
||||
} else if (reseeded == 0) {
|
||||
/* do a full reseeding if it has not been done yet above */
|
||||
RAND_DRBG_reseed(drbg, NULL, 0, 0);
|
||||
if (!RAND_DRBG_reseed(drbg, NULL, 0, 0)) {
|
||||
RANDerr(RAND_F_RAND_DRBG_RESTART, RAND_R_RESEED_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,6 +577,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
int prediction_resistance,
|
||||
const unsigned char *adin, size_t adinlen)
|
||||
{
|
||||
int fork_id;
|
||||
int reseed_required = 0;
|
||||
|
||||
if (drbg->state != DRBG_READY) {
|
||||
|
@ -603,13 +603,15 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (drbg->fork_count != rand_fork_count) {
|
||||
drbg->fork_count = rand_fork_count;
|
||||
fork_id = openssl_get_fork_id();
|
||||
|
||||
if (drbg->fork_id != fork_id) {
|
||||
drbg->fork_id = fork_id;
|
||||
reseed_required = 1;
|
||||
}
|
||||
|
||||
if (drbg->reseed_interval > 0) {
|
||||
if (drbg->reseed_gen_counter >= drbg->reseed_interval)
|
||||
if (drbg->generate_counter >= drbg->reseed_interval)
|
||||
reseed_required = 1;
|
||||
}
|
||||
if (drbg->reseed_time_interval > 0) {
|
||||
|
@ -618,11 +620,8 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
|
||||
reseed_required = 1;
|
||||
}
|
||||
if (drbg->parent != NULL) {
|
||||
unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (reseed_counter > 0
|
||||
&& tsan_load(&drbg->parent->reseed_prop_counter)
|
||||
!= reseed_counter)
|
||||
if (drbg->enable_reseed_propagation && drbg->parent != NULL) {
|
||||
if (drbg->reseed_counter != tsan_load(&drbg->parent->reseed_counter))
|
||||
reseed_required = 1;
|
||||
}
|
||||
|
||||
|
@ -641,7 +640,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
drbg->reseed_gen_counter++;
|
||||
drbg->generate_counter++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -664,7 +663,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
|
|||
if (drbg->adin_pool == NULL) {
|
||||
if (drbg->type == 0)
|
||||
goto err;
|
||||
drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
|
||||
drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen);
|
||||
if (drbg->adin_pool == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
@ -703,8 +702,7 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
|
|||
RAND_DRBG_get_nonce_fn get_nonce,
|
||||
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
|
||||
{
|
||||
if (drbg->state != DRBG_UNINITIALISED
|
||||
|| drbg->parent != NULL)
|
||||
if (drbg->state != DRBG_UNINITIALISED)
|
||||
return 0;
|
||||
drbg->get_entropy = get_entropy;
|
||||
drbg->cleanup_entropy = cleanup_entropy;
|
||||
|
@ -880,8 +878,9 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
|
|||
if (parent == NULL && rand_drbg_enable_locking(drbg) == 0)
|
||||
goto err;
|
||||
|
||||
/* enable seed propagation */
|
||||
tsan_store(&drbg->reseed_prop_counter, 1);
|
||||
/* enable reseed propagation */
|
||||
drbg->enable_reseed_propagation = 1;
|
||||
drbg->reseed_counter = 1;
|
||||
|
||||
/*
|
||||
* Ignore instantiation error to support just-in-time instantiation.
|
||||
|
@ -1041,7 +1040,7 @@ static int drbg_add(const void *buf, int num, double randomness)
|
|||
return ret;
|
||||
#else
|
||||
/*
|
||||
* If an os entropy source is avaible then we declare the buffer content
|
||||
* If an os entropy source is available then we declare the buffer content
|
||||
* as additional data by setting randomness to zero and trigger a regular
|
||||
* reseeding.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
|
@ -14,6 +14,8 @@
|
|||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA RAND_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_DATA_COLLECT_METHOD, 0),
|
||||
"data_collect_method"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_BYTES, 0), "drbg_bytes"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_GET_ENTROPY, 0), "drbg_get_entropy"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"},
|
||||
|
@ -47,7 +49,9 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
|
|||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ATTACH, 0), "rand_pool_attach"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_BYTES_NEEDED, 0),
|
||||
"rand_pool_bytes_needed"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_GROW, 0), "rand_pool_grow"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_NEW, 0), "rand_pool_new"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_PSEUDO_BYTES, 0), "RAND_pseudo_bytes"},
|
||||
{ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_WRITE_FILE, 0), "RAND_write_file"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 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
|
||||
|
@ -11,10 +11,10 @@
|
|||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/opensslconf.h>
|
||||
#include "internal/rand_int.h"
|
||||
#include "crypto/rand.h"
|
||||
#include <openssl/engine.h>
|
||||
#include "internal/thread_once.h"
|
||||
#include "rand_lcl.h"
|
||||
#include "rand_local.h"
|
||||
#include "e_os.h"
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
|
@ -26,8 +26,6 @@ static CRYPTO_RWLOCK *rand_meth_lock;
|
|||
static const RAND_METHOD *default_RAND_meth;
|
||||
static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
|
||||
int rand_fork_count;
|
||||
|
||||
static CRYPTO_RWLOCK *rand_nonce_lock;
|
||||
static int rand_nonce_count;
|
||||
|
||||
|
@ -137,7 +135,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
size_t entropy_available = 0;
|
||||
RAND_POOL *pool;
|
||||
|
||||
if (drbg->parent && drbg->strength > drbg->parent->strength) {
|
||||
if (drbg->parent != NULL && drbg->strength > drbg->parent->strength) {
|
||||
/*
|
||||
* We currently don't support the algorithm from NIST SP 800-90C
|
||||
* 10.1.2 to use a weaker DRBG as source
|
||||
|
@ -150,12 +148,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
pool = drbg->seed_pool;
|
||||
pool->entropy_requested = entropy;
|
||||
} else {
|
||||
pool = rand_pool_new(entropy, min_len, max_len);
|
||||
pool = rand_pool_new(entropy, drbg->secure, min_len, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (drbg->parent) {
|
||||
if (drbg->parent != NULL) {
|
||||
size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed);
|
||||
|
||||
|
@ -163,7 +161,9 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
size_t bytes = 0;
|
||||
|
||||
/*
|
||||
* Get random from parent, include our state as additional input.
|
||||
* Get random data from parent. Include our address as additional input,
|
||||
* in order to provide some additional distinction between different
|
||||
* DRBG child instances.
|
||||
* Our lock is already held, but we need to lock our parent before
|
||||
* generating bits from it. (Note: taking the lock will be a no-op
|
||||
* if locking if drbg->parent->lock == NULL.)
|
||||
|
@ -172,10 +172,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
if (RAND_DRBG_generate(drbg->parent,
|
||||
buffer, bytes_needed,
|
||||
prediction_resistance,
|
||||
NULL, 0) != 0)
|
||||
(unsigned char *)&drbg, sizeof(drbg)) != 0)
|
||||
bytes = bytes_needed;
|
||||
drbg->reseed_next_counter
|
||||
= tsan_load(&drbg->parent->reseed_prop_counter);
|
||||
rand_drbg_unlock(drbg->parent);
|
||||
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
|
@ -216,8 +214,12 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen)
|
||||
{
|
||||
if (drbg->seed_pool == NULL)
|
||||
OPENSSL_secure_clear_free(out, outlen);
|
||||
if (drbg->seed_pool == NULL) {
|
||||
if (drbg->secure)
|
||||
OPENSSL_secure_clear_free(out, outlen);
|
||||
else
|
||||
OPENSSL_clear_free(out, outlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -235,9 +237,10 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
|
|||
struct {
|
||||
void * instance;
|
||||
int count;
|
||||
} data = { 0 };
|
||||
} data;
|
||||
|
||||
pool = rand_pool_new(0, min_len, max_len);
|
||||
memset(&data, 0, sizeof(data));
|
||||
pool = rand_pool_new(0, 0, min_len, max_len);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -266,7 +269,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
|
|||
void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
|
||||
unsigned char *out, size_t outlen)
|
||||
{
|
||||
OPENSSL_secure_clear_free(out, outlen);
|
||||
OPENSSL_clear_free(out, outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -298,11 +301,6 @@ void rand_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out)
|
|||
rand_pool_reattach(pool, out);
|
||||
}
|
||||
|
||||
void rand_fork(void)
|
||||
{
|
||||
rand_fork_count++;
|
||||
}
|
||||
|
||||
DEFINE_RUN_ONCE_STATIC(do_rand_init)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
|
@ -362,7 +360,7 @@ void rand_cleanup_int(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* RAND_close_seed_files() ensures that any seed file decriptors are
|
||||
* RAND_close_seed_files() ensures that any seed file descriptors are
|
||||
* closed after use.
|
||||
*/
|
||||
void RAND_keep_random_devices_open(int keep)
|
||||
|
@ -386,6 +384,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();
|
||||
|
@ -401,8 +402,8 @@ int RAND_poll(void)
|
|||
|
||||
} else {
|
||||
/* fill random pool and seed the current legacy RNG */
|
||||
pool = rand_pool_new(RAND_DRBG_STRENGTH,
|
||||
RAND_DRBG_STRENGTH / 8,
|
||||
pool = rand_pool_new(RAND_DRBG_STRENGTH, 1,
|
||||
(RAND_DRBG_STRENGTH + 7) / 8,
|
||||
RAND_POOL_MAX_LENGTH);
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
|
@ -428,10 +429,16 @@ err:
|
|||
* Allocate memory and initialize a new random pool
|
||||
*/
|
||||
|
||||
RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
|
||||
RAND_POOL *rand_pool_new(int entropy_requested, int secure,
|
||||
size_t min_len, size_t max_len)
|
||||
{
|
||||
RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
|
||||
RAND_POOL *pool;
|
||||
size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure);
|
||||
|
||||
if (!RUN_ONCE(&rand_init, do_rand_init))
|
||||
return NULL;
|
||||
|
||||
pool = OPENSSL_zalloc(sizeof(*pool));
|
||||
if (pool == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
|
@ -440,14 +447,22 @@ RAND_POOL *rand_pool_new(int entropy_requested, size_t min_len, size_t max_len)
|
|||
pool->min_len = min_len;
|
||||
pool->max_len = (max_len > RAND_POOL_MAX_LENGTH) ?
|
||||
RAND_POOL_MAX_LENGTH : max_len;
|
||||
pool->alloc_len = min_len < min_alloc_size ? min_alloc_size : min_len;
|
||||
if (pool->alloc_len > pool->max_len)
|
||||
pool->alloc_len = pool->max_len;
|
||||
|
||||
if (secure)
|
||||
pool->buffer = OPENSSL_secure_zalloc(pool->alloc_len);
|
||||
else
|
||||
pool->buffer = OPENSSL_zalloc(pool->alloc_len);
|
||||
|
||||
pool->buffer = OPENSSL_secure_zalloc(pool->max_len);
|
||||
if (pool->buffer == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pool->entropy_requested = entropy_requested;
|
||||
pool->secure = secure;
|
||||
|
||||
return pool;
|
||||
|
||||
|
@ -482,7 +497,7 @@ RAND_POOL *rand_pool_attach(const unsigned char *buffer, size_t len,
|
|||
|
||||
pool->attached = 1;
|
||||
|
||||
pool->min_len = pool->max_len = pool->len;
|
||||
pool->min_len = pool->max_len = pool->alloc_len = pool->len;
|
||||
pool->entropy = entropy;
|
||||
|
||||
return pool;
|
||||
|
@ -502,8 +517,13 @@ void rand_pool_free(RAND_POOL *pool)
|
|||
* to rand_pool_attach() as `const unsigned char*`.
|
||||
* (see corresponding comment in rand_pool_attach()).
|
||||
*/
|
||||
if (!pool->attached)
|
||||
OPENSSL_secure_clear_free(pool->buffer, pool->max_len);
|
||||
if (!pool->attached) {
|
||||
if (pool->secure)
|
||||
OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
|
||||
else
|
||||
OPENSSL_clear_free(pool->buffer, pool->alloc_len);
|
||||
}
|
||||
|
||||
OPENSSL_free(pool);
|
||||
}
|
||||
|
||||
|
@ -596,6 +616,42 @@ size_t rand_pool_entropy_needed(RAND_POOL *pool)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Increase the allocation size -- not usable for an attached pool */
|
||||
static int rand_pool_grow(RAND_POOL *pool, size_t len)
|
||||
{
|
||||
if (len > pool->alloc_len - pool->len) {
|
||||
unsigned char *p;
|
||||
const size_t limit = pool->max_len / 2;
|
||||
size_t newlen = pool->alloc_len;
|
||||
|
||||
if (pool->attached || len > pool->max_len - pool->len) {
|
||||
RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
newlen = newlen < limit ? newlen * 2 : pool->max_len;
|
||||
while (len > newlen - pool->len);
|
||||
|
||||
if (pool->secure)
|
||||
p = OPENSSL_secure_zalloc(newlen);
|
||||
else
|
||||
p = OPENSSL_zalloc(newlen);
|
||||
if (p == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_GROW, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memcpy(p, pool->buffer, pool->len);
|
||||
if (pool->secure)
|
||||
OPENSSL_secure_clear_free(pool->buffer, pool->alloc_len);
|
||||
else
|
||||
OPENSSL_clear_free(pool->buffer, pool->alloc_len);
|
||||
pool->buffer = p;
|
||||
pool->alloc_len = newlen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of bytes needed to fill the pool, assuming
|
||||
* the input has 1 / |entropy_factor| entropy bits per data bit.
|
||||
|
@ -625,6 +681,24 @@ size_t rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor)
|
|||
/* to meet the min_len requirement */
|
||||
bytes_needed = pool->min_len - pool->len;
|
||||
|
||||
/*
|
||||
* Make sure the buffer is large enough for the requested amount
|
||||
* of data. This guarantees that existing code patterns where
|
||||
* rand_pool_add_begin, rand_pool_add_end or rand_pool_add
|
||||
* are used to collect entropy data without any error handling
|
||||
* whatsoever, continue to be valid.
|
||||
* Furthermore if the allocation here fails once, make sure that
|
||||
* we don't fall back to a less secure or even blocking random source,
|
||||
* as that could happen by the existing code patterns.
|
||||
* This is not a concern for additional data, therefore that
|
||||
* is not needed if rand_pool_grow fails in other places.
|
||||
*/
|
||||
if (!rand_pool_grow(pool, bytes_needed)) {
|
||||
/* persistent error for this pool */
|
||||
pool->max_len = pool->len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bytes_needed;
|
||||
}
|
||||
|
||||
|
@ -657,6 +731,27 @@ int rand_pool_add(RAND_POOL *pool,
|
|||
}
|
||||
|
||||
if (len > 0) {
|
||||
/*
|
||||
* This is to protect us from accidentally passing the buffer
|
||||
* returned from rand_pool_add_begin.
|
||||
* The check for alloc_len makes sure we do not compare the
|
||||
* address of the end of the allocated memory to something
|
||||
* different, since that comparison would have an
|
||||
* indeterminate result.
|
||||
*/
|
||||
if (pool->alloc_len > pool->len && pool->buffer + pool->len == buffer) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* We have that only for cases when a pool is used to collect
|
||||
* additional data.
|
||||
* For entropy data, as long as the allocation request stays within
|
||||
* the limits given by rand_pool_bytes_needed this rand_pool_grow
|
||||
* below is guaranteed to succeed, thus no allocation happens.
|
||||
*/
|
||||
if (!rand_pool_grow(pool, len))
|
||||
return 0;
|
||||
memcpy(pool->buffer + pool->len, buffer, len);
|
||||
pool->len += len;
|
||||
pool->entropy += entropy;
|
||||
|
@ -675,7 +770,7 @@ int rand_pool_add(RAND_POOL *pool,
|
|||
* is returned without producing an error message.
|
||||
*
|
||||
* After updating the buffer, rand_pool_add_end() needs to be called
|
||||
* to finish the udpate operation (see next comment).
|
||||
* to finish the update operation (see next comment).
|
||||
*/
|
||||
unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
||||
{
|
||||
|
@ -689,9 +784,21 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
|||
|
||||
if (pool->buffer == NULL) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD_BEGIN, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* As long as the allocation request stays within the limits given
|
||||
* by rand_pool_bytes_needed this rand_pool_grow below is guaranteed
|
||||
* to succeed, thus no allocation happens.
|
||||
* We have that only for cases when a pool is used to collect
|
||||
* additional data. Then the buffer might need to grow here,
|
||||
* and of course the caller is responsible to check the return
|
||||
* value of this function.
|
||||
*/
|
||||
if (!rand_pool_grow(pool, len))
|
||||
return NULL;
|
||||
|
||||
return pool->buffer + pool->len;
|
||||
}
|
||||
|
||||
|
@ -706,7 +813,7 @@ unsigned char *rand_pool_add_begin(RAND_POOL *pool, size_t len)
|
|||
*/
|
||||
int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
|
||||
{
|
||||
if (len > pool->max_len - pool->len) {
|
||||
if (len > pool->alloc_len - pool->len) {
|
||||
RANDerr(RAND_F_RAND_POOL_ADD_END, RAND_R_RANDOM_POOL_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
|
@ -794,7 +901,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);
|
||||
}
|
||||
|
||||
|
@ -802,7 +909,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);
|
||||
}
|
||||
|
||||
|
@ -815,24 +922,22 @@ int RAND_priv_bytes(unsigned char *buf, int num)
|
|||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
RAND_DRBG *drbg;
|
||||
int ret;
|
||||
|
||||
if (meth != RAND_OpenSSL())
|
||||
if (meth != NULL && meth != RAND_OpenSSL())
|
||||
return RAND_bytes(buf, num);
|
||||
|
||||
drbg = RAND_DRBG_get0_private();
|
||||
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)
|
||||
{
|
||||
const RAND_METHOD *meth = RAND_get_rand_method();
|
||||
|
||||
if (meth->bytes != NULL)
|
||||
if (meth != NULL && meth->bytes != NULL)
|
||||
return meth->bytes(buf, num);
|
||||
RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
|
||||
return -1;
|
||||
|
@ -843,8 +948,9 @@ 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
|
||||
|
@ -853,7 +959,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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
|
@ -7,8 +7,8 @@
|
|||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef HEADER_RAND_LCL_H
|
||||
# define HEADER_RAND_LCL_H
|
||||
#ifndef OSSL_CRYPTO_RAND_LOCAL_H
|
||||
# define OSSL_CRYPTO_RAND_LOCAL_H
|
||||
|
||||
# include <openssl/aes.h>
|
||||
# include <openssl/evp.h>
|
||||
|
@ -45,7 +45,6 @@
|
|||
# define DRBG_MAX_LENGTH INT32_MAX
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Maximum allocation size for RANDOM_POOL buffers
|
||||
*
|
||||
|
@ -72,6 +71,24 @@
|
|||
* 1.5 * (RAND_DRBG_STRENGTH / 8))
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initial allocation minimum.
|
||||
*
|
||||
* There is a distinction between the secure and normal allocation minimums.
|
||||
* Ideally, the secure allocation size should be a power of two. The normal
|
||||
* allocation size doesn't have any such restriction.
|
||||
*
|
||||
* The secure value is based on 128 bits of secure material, which is 16 bytes.
|
||||
* Typically, the DRBGs will set a minimum larger than this so optimal
|
||||
* allocation ought to take place (for full quality seed material).
|
||||
*
|
||||
* The normal value has been chosen by noticing that the rand_drbg_get_nonce
|
||||
* function is usually the largest of the built in allocation (twenty four
|
||||
* bytes and then appending another sixteen bytes). This means the buffer ends
|
||||
* with 40 bytes. The value of forty eight is comfortably above this which
|
||||
* allows some slack in the platform specific values used.
|
||||
*/
|
||||
# define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48)
|
||||
|
||||
/* DRBG status values */
|
||||
typedef enum drbg_status_e {
|
||||
|
@ -121,9 +138,11 @@ typedef struct rand_drbg_method_st {
|
|||
* The state of a DRBG AES-CTR.
|
||||
*/
|
||||
typedef struct rand_drbg_ctr_st {
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
EVP_CIPHER_CTX *ctx_ecb;
|
||||
EVP_CIPHER_CTX *ctx_ctr;
|
||||
EVP_CIPHER_CTX *ctx_df;
|
||||
const EVP_CIPHER *cipher;
|
||||
const EVP_CIPHER *cipher_ecb;
|
||||
const EVP_CIPHER *cipher_ctr;
|
||||
size_t keylen;
|
||||
unsigned char K[32];
|
||||
unsigned char V[16];
|
||||
|
@ -150,9 +169,11 @@ struct rand_pool_st {
|
|||
size_t len; /* current number of random bytes contained in the pool */
|
||||
|
||||
int attached; /* true pool was attached to existing buffer */
|
||||
int secure; /* 1: allocated on the secure heap, 0: otherwise */
|
||||
|
||||
size_t min_len; /* minimum number of random bytes requested */
|
||||
size_t max_len; /* maximum number of random bytes (allocated buffer size) */
|
||||
size_t alloc_len; /* current number of bytes allocated */
|
||||
size_t entropy; /* current entropy count in bits */
|
||||
size_t entropy_requested; /* requested entropy count in bits */
|
||||
};
|
||||
|
@ -167,12 +188,12 @@ struct rand_drbg_st {
|
|||
int secure; /* 1: allocated on the secure heap, 0: otherwise */
|
||||
int type; /* the nid of the underlying algorithm */
|
||||
/*
|
||||
* Stores the value of the rand_fork_count global as of when we last
|
||||
* reseeded. The DRBG reseeds automatically whenever drbg->fork_count !=
|
||||
* rand_fork_count. Used to provide fork-safety and reseed this DRBG in
|
||||
* the child process.
|
||||
* Stores the return value of openssl_get_fork_id() as of when we last
|
||||
* reseeded. The DRBG reseeds automatically whenever drbg->fork_id !=
|
||||
* openssl_get_fork_id(). Used to provide fork-safety and reseed this
|
||||
* DRBG in the child process.
|
||||
*/
|
||||
int fork_count;
|
||||
int fork_id;
|
||||
unsigned short flags; /* various external flags */
|
||||
|
||||
/*
|
||||
|
@ -214,7 +235,7 @@ struct rand_drbg_st {
|
|||
size_t max_perslen, max_adinlen;
|
||||
|
||||
/* Counts the number of generate requests since the last reseed. */
|
||||
unsigned int reseed_gen_counter;
|
||||
unsigned int generate_counter;
|
||||
/*
|
||||
* Maximum number of generate requests until a reseed is required.
|
||||
* This value is ignored if it is zero.
|
||||
|
@ -227,9 +248,15 @@ struct rand_drbg_st {
|
|||
* This value is ignored if it is zero.
|
||||
*/
|
||||
time_t reseed_time_interval;
|
||||
|
||||
/*
|
||||
* Enables reseed propagation (see following comment)
|
||||
*/
|
||||
unsigned int enable_reseed_propagation;
|
||||
|
||||
/*
|
||||
* Counts the number of reseeds since instantiation.
|
||||
* This value is ignored if it is zero.
|
||||
* This value is ignored if enable_reseed_propagation is zero.
|
||||
*
|
||||
* This counter is used only for seed propagation from the <master> DRBG
|
||||
* to its two children, the <public> and <private> DRBG. This feature is
|
||||
|
@ -237,8 +264,7 @@ struct rand_drbg_st {
|
|||
* is added by RAND_add() or RAND_seed() will have an immediate effect on
|
||||
* the output of RAND_bytes() resp. RAND_priv_bytes().
|
||||
*/
|
||||
TSAN_QUALIFIER unsigned int reseed_prop_counter;
|
||||
unsigned int reseed_next_counter;
|
||||
TSAN_QUALIFIER unsigned int reseed_counter;
|
||||
|
||||
size_t seedlen;
|
||||
DRBG_STATUS state;
|
||||
|
@ -264,19 +290,6 @@ struct rand_drbg_st {
|
|||
/* The global RAND method, and the global buffer and DRBG instance. */
|
||||
extern RAND_METHOD rand_meth;
|
||||
|
||||
/*
|
||||
* A "generation count" of forks. Incremented in the child process after a
|
||||
* fork. Since rand_fork_count is increment-only, and only ever written to in
|
||||
* the child process of the fork, which is guaranteed to be single-threaded, no
|
||||
* locking is needed for normal (read) accesses; the rest of pthread fork
|
||||
* processing is assumed to introduce the necessary memory barriers. Sibling
|
||||
* children of a given parent will produce duplicate values, but this is not
|
||||
* problematic because the reseeding process pulls input from the system CSPRNG
|
||||
* and/or other global sources, so the siblings will end up generating
|
||||
* different output streams.
|
||||
*/
|
||||
extern int rand_fork_count;
|
||||
|
||||
/* DRBG helpers */
|
||||
int rand_drbg_restart(RAND_DRBG *drbg,
|
||||
const unsigned char *buffer, size_t len, size_t entropy);
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 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
|
||||
|
@ -14,21 +14,29 @@
|
|||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rand.h>
|
||||
#include "rand_lcl.h"
|
||||
#include "internal/rand_int.h"
|
||||
#include <openssl/crypto.h>
|
||||
#include "rand_local.h"
|
||||
#include "crypto/rand.h"
|
||||
#include <stdio.h>
|
||||
#include "internal/dso.h"
|
||||
#if defined(__linux)
|
||||
#ifdef __linux
|
||||
# include <sys/syscall.h>
|
||||
# ifdef DEVRANDOM_WAIT
|
||||
# include <sys/shm.h>
|
||||
# include <sys/utsname.h>
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(OPENSSL_SYS_UEFI)
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#if defined(__OpenBSD__)
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
# include <CommonCrypto/CommonRandom.h>
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
|
||||
# include <sys/types.h>
|
||||
|
@ -75,7 +83,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 */
|
||||
|
@ -241,10 +250,12 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
|
|||
* when the sysctl returns long and we want to request something not a
|
||||
* multiple of longs, which should never be the case.
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
if (!ossl_assert(buflen % sizeof(long) == 0)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On NetBSD before 4.0 KERN_ARND was an alias for KERN_URND, and only
|
||||
|
@ -262,7 +273,7 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
|
|||
mib[1] = KERN_ARND;
|
||||
|
||||
do {
|
||||
len = buflen;
|
||||
len = buflen > 256 ? 256 : buflen;
|
||||
if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
|
||||
return done > 0 ? done : -1;
|
||||
done += len;
|
||||
|
@ -275,6 +286,63 @@ static ssize_t sysctl_random(char *buf, size_t buflen)
|
|||
# endif
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
|
||||
|
||||
# if defined(__linux) && !defined(__NR_getrandom)
|
||||
# if defined(__arm__)
|
||||
# define __NR_getrandom (__NR_SYSCALL_BASE+384)
|
||||
# elif defined(__i386__)
|
||||
# define __NR_getrandom 355
|
||||
# elif defined(__x86_64__)
|
||||
# if defined(__ILP32__)
|
||||
# define __NR_getrandom (__X32_SYSCALL_BIT + 318)
|
||||
# else
|
||||
# define __NR_getrandom 318
|
||||
# endif
|
||||
# elif defined(__xtensa__)
|
||||
# define __NR_getrandom 338
|
||||
# elif defined(__s390__) || defined(__s390x__)
|
||||
# define __NR_getrandom 349
|
||||
# elif defined(__bfin__)
|
||||
# define __NR_getrandom 389
|
||||
# elif defined(__powerpc__)
|
||||
# define __NR_getrandom 359
|
||||
# elif defined(__mips__) || defined(__mips64)
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_getrandom (__NR_Linux + 353)
|
||||
# elif _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_getrandom (__NR_Linux + 313)
|
||||
# elif _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_getrandom (__NR_Linux + 317)
|
||||
# endif
|
||||
# elif defined(__hppa__)
|
||||
# define __NR_getrandom (__NR_Linux + 339)
|
||||
# elif defined(__sparc__)
|
||||
# define __NR_getrandom 347
|
||||
# elif defined(__ia64__)
|
||||
# define __NR_getrandom 1339
|
||||
# elif defined(__alpha__)
|
||||
# define __NR_getrandom 511
|
||||
# elif defined(__sh__)
|
||||
# if defined(__SH5__)
|
||||
# define __NR_getrandom 373
|
||||
# else
|
||||
# define __NR_getrandom 384
|
||||
# endif
|
||||
# elif defined(__avr32__)
|
||||
# define __NR_getrandom 317
|
||||
# elif defined(__microblaze__)
|
||||
# define __NR_getrandom 385
|
||||
# elif defined(__m68k__)
|
||||
# define __NR_getrandom 352
|
||||
# elif defined(__cris__)
|
||||
# define __NR_getrandom 356
|
||||
# elif defined(__aarch64__)
|
||||
# define __NR_getrandom 278
|
||||
# else /* generic */
|
||||
# define __NR_getrandom 278
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
* syscall_random(): Try to get random data using a system call
|
||||
* returns the number of bytes returned in buf, or < 0 on error.
|
||||
|
@ -300,12 +368,24 @@ static ssize_t syscall_random(void *buf, size_t buflen)
|
|||
* - OpenBSD since 5.6
|
||||
* - Linux since 3.17 with glibc 2.25
|
||||
* - FreeBSD since 12.0 (1200061)
|
||||
*
|
||||
* Note: Sometimes getentropy() can be provided but not implemented
|
||||
* internally. So we need to check errno for ENOSYS
|
||||
*/
|
||||
# if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
|
||||
extern int getentropy(void *buffer, size_t length) __attribute__((weak));
|
||||
|
||||
if (getentropy != NULL)
|
||||
return getentropy(buf, buflen) == 0 ? (ssize_t)buflen : -1;
|
||||
if (getentropy != NULL) {
|
||||
if (getentropy(buf, buflen) == 0)
|
||||
return (ssize_t)buflen;
|
||||
if (errno != ENOSYS)
|
||||
return -1;
|
||||
}
|
||||
# elif defined(__APPLE__)
|
||||
if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
|
||||
return (ssize_t)buflen;
|
||||
|
||||
return -1;
|
||||
# else
|
||||
union {
|
||||
void *p;
|
||||
|
@ -324,8 +404,8 @@ static ssize_t syscall_random(void *buf, size_t buflen)
|
|||
# endif
|
||||
|
||||
/* Linux supports this since version 3.17 */
|
||||
# if defined(__linux) && defined(SYS_getrandom)
|
||||
return syscall(SYS_getrandom, buf, buflen, 0);
|
||||
# if defined(__linux) && defined(__NR_getrandom)
|
||||
return syscall(__NR_getrandom, buf, buflen, 0);
|
||||
# elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
|
||||
return sysctl_random(buf, buflen);
|
||||
# else
|
||||
|
@ -346,6 +426,92 @@ static struct random_device {
|
|||
} random_devices[OSSL_NELEM(random_device_paths)];
|
||||
static int keep_random_devices_open = 1;
|
||||
|
||||
# if defined(__linux) && defined(DEVRANDOM_WAIT) \
|
||||
&& defined(OPENSSL_RAND_SEED_GETRANDOM)
|
||||
static void *shm_addr;
|
||||
|
||||
static void cleanup_shm(void)
|
||||
{
|
||||
shmdt(shm_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the system randomness source has been adequately seeded.
|
||||
* This is done by having the first start of libcrypto, wait until the device
|
||||
* /dev/random becomes able to supply a byte of entropy. Subsequent starts
|
||||
* of the library and later reseedings do not need to do this.
|
||||
*/
|
||||
static int wait_random_seeded(void)
|
||||
{
|
||||
static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0;
|
||||
static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL };
|
||||
int kernel[2];
|
||||
int shm_id, fd, r;
|
||||
char c, *p;
|
||||
struct utsname un;
|
||||
fd_set fds;
|
||||
|
||||
if (!seeded) {
|
||||
/* See if anything has created the global seeded indication */
|
||||
if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) {
|
||||
/*
|
||||
* Check the kernel's version and fail if it is too recent.
|
||||
*
|
||||
* Linux kernels from 4.8 onwards do not guarantee that
|
||||
* /dev/urandom is properly seeded when /dev/random becomes
|
||||
* readable. However, such kernels support the getentropy(2)
|
||||
* system call and this should always succeed which renders
|
||||
* this alternative but essentially identical source moot.
|
||||
*/
|
||||
if (uname(&un) == 0) {
|
||||
kernel[0] = atoi(un.release);
|
||||
p = strchr(un.release, '.');
|
||||
kernel[1] = p == NULL ? 0 : atoi(p + 1);
|
||||
if (kernel[0] > kernel_version[0]
|
||||
|| (kernel[0] == kernel_version[0]
|
||||
&& kernel[1] >= kernel_version[1])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Open /dev/random and wait for it to be readable */
|
||||
if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
|
||||
if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0
|
||||
&& errno == EINTR);
|
||||
} else {
|
||||
while ((r = read(fd, &c, 1)) < 0 && errno == EINTR);
|
||||
}
|
||||
close(fd);
|
||||
if (r == 1) {
|
||||
seeded = 1;
|
||||
/* Create the shared memory indicator */
|
||||
shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1,
|
||||
IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shm_id != -1) {
|
||||
seeded = 1;
|
||||
/*
|
||||
* Map the shared memory to prevent its premature destruction.
|
||||
* If this call fails, it isn't a big problem.
|
||||
*/
|
||||
shm_addr = shmat(shm_id, NULL, SHM_RDONLY);
|
||||
if (shm_addr != (void *)-1)
|
||||
OPENSSL_atexit(&cleanup_shm);
|
||||
}
|
||||
}
|
||||
return seeded;
|
||||
}
|
||||
# else /* defined __linux && DEVRANDOM_WAIT && OPENSSL_RAND_SEED_GETRANDOM */
|
||||
static int wait_random_seeded(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Verify that the file descriptor associated with the random source is
|
||||
* still valid. The rationale for doing this is the fact that it is not
|
||||
|
@ -472,12 +638,12 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
|||
# if defined(OPENSSL_RAND_SEED_NONE)
|
||||
return rand_pool_entropy_available(pool);
|
||||
# else
|
||||
size_t bytes_needed;
|
||||
size_t entropy_available = 0;
|
||||
unsigned char *buffer;
|
||||
size_t entropy_available;
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_GETRANDOM)
|
||||
{
|
||||
size_t bytes_needed;
|
||||
unsigned char *buffer;
|
||||
ssize_t bytes;
|
||||
/* Maximum allowed number of consecutive unsuccessful attempts */
|
||||
int attempts = 3;
|
||||
|
@ -507,13 +673,16 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
|||
# endif
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_DEVRANDOM)
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
{
|
||||
if (wait_random_seeded()) {
|
||||
size_t bytes_needed;
|
||||
unsigned char *buffer;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths);
|
||||
i++) {
|
||||
ssize_t bytes = 0;
|
||||
/* Maximum allowed number of consecutive unsuccessful attempts */
|
||||
/* Maximum number of consecutive unsuccessful attempts */
|
||||
int attempts = 3;
|
||||
const int fd = get_random_device(i);
|
||||
|
||||
|
@ -527,7 +696,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
|||
if (bytes > 0) {
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
bytes_needed -= bytes;
|
||||
attempts = 3; /* reset counter after successful attempt */
|
||||
attempts = 3; /* reset counter on successful attempt */
|
||||
} else if (bytes < 0 && errno != EINTR) {
|
||||
break;
|
||||
}
|
||||
|
@ -535,7 +704,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
|||
if (bytes < 0 || !keep_random_devices_open)
|
||||
close_random_device(i);
|
||||
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1);
|
||||
}
|
||||
entropy_available = rand_pool_entropy_available(pool);
|
||||
if (entropy_available > 0)
|
||||
|
@ -556,26 +725,29 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
|
|||
# endif
|
||||
|
||||
# if defined(OPENSSL_RAND_SEED_EGD)
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
if (bytes_needed > 0) {
|
||||
{
|
||||
static const char *paths[] = { DEVRANDOM_EGD, NULL };
|
||||
size_t bytes_needed;
|
||||
unsigned char *buffer;
|
||||
int i;
|
||||
|
||||
for (i = 0; paths[i] != NULL; i++) {
|
||||
buffer = rand_pool_add_begin(pool, bytes_needed);
|
||||
if (buffer != NULL) {
|
||||
size_t bytes = 0;
|
||||
int num = RAND_query_egd_bytes(paths[i],
|
||||
buffer, (int)bytes_needed);
|
||||
if (num == (int)bytes_needed)
|
||||
bytes = bytes_needed;
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) {
|
||||
size_t bytes = 0;
|
||||
int num;
|
||||
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
entropy_available = rand_pool_entropy_available(pool);
|
||||
}
|
||||
if (entropy_available > 0)
|
||||
return entropy_available;
|
||||
buffer = rand_pool_add_begin(pool, bytes_needed);
|
||||
num = RAND_query_egd_bytes(paths[i],
|
||||
buffer, (int)bytes_needed);
|
||||
if (num == (int)bytes_needed)
|
||||
bytes = bytes_needed;
|
||||
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
bytes_needed = rand_pool_bytes_needed(pool, 1);
|
||||
}
|
||||
entropy_available = rand_pool_entropy_available(pool);
|
||||
if (entropy_available > 0)
|
||||
return entropy_available;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
@ -609,15 +781,18 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
|
|||
int rand_pool_add_additional_data(RAND_POOL *pool)
|
||||
{
|
||||
struct {
|
||||
int fork_id;
|
||||
CRYPTO_THREAD_ID tid;
|
||||
uint64_t time;
|
||||
} data = { 0 };
|
||||
|
||||
/*
|
||||
* Add some noise from the thread id and a high resolution timer.
|
||||
* The fork_id adds some extra fork-safety.
|
||||
* The thread id adds a little randomness if the drbg is accessed
|
||||
* concurrently (which is the case for the <master> drbg).
|
||||
*/
|
||||
data.fork_id = openssl_get_fork_id();
|
||||
data.tid = CRYPTO_THREAD_get_current_id();
|
||||
data.time = get_timer_bits();
|
||||
|
||||
|
@ -704,4 +879,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__) */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2020 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
|
||||
|
@ -13,9 +13,11 @@
|
|||
# define __NEW_STARLET 1 /* New starlet definitions since VMS 7.0 */
|
||||
# include <unistd.h>
|
||||
# include "internal/cryptlib.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/rand.h>
|
||||
# include "internal/rand_int.h"
|
||||
# include "rand_lcl.h"
|
||||
# include "crypto/rand.h"
|
||||
# include "rand_local.h"
|
||||
# include <descrip.h>
|
||||
# include <dvidef.h>
|
||||
# include <jpidef.h>
|
||||
|
@ -32,10 +34,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 +343,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 +458,12 @@ 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];
|
||||
char buf[100]; /* That should be enough */
|
||||
|
||||
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);
|
||||
BIO_snprintf(buf, sizeof(buf), "Needed: %zu, Available: %zu",
|
||||
bytes_needed, total_length);
|
||||
RANDerr(RAND_F_DATA_COLLECT_METHOD, RAND_R_RANDOM_POOL_UNDERFLOW);
|
||||
ERR_add_error_data(1, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -480,7 +490,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();
|
||||
|
@ -494,6 +504,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 {
|
||||
|
@ -507,7 +591,11 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
|||
* concurrently (which is the case for the <master> drbg).
|
||||
*/
|
||||
data.tid = CRYPTO_THREAD_get_current_id();
|
||||
#if __CRTL_VER >= 80400000
|
||||
sys$gettim_prec(&data.time);
|
||||
#else
|
||||
sys$gettim((void*)&data.time);
|
||||
#endif
|
||||
|
||||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 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
|
||||
|
@ -9,8 +9,8 @@
|
|||
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/rand.h>
|
||||
#include "rand_lcl.h"
|
||||
#include "internal/rand_int.h"
|
||||
#include "rand_local.h"
|
||||
#include "crypto/rand.h"
|
||||
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
|
||||
|
||||
# ifndef OPENSSL_RAND_SEED_OS
|
||||
|
@ -18,8 +18,9 @@
|
|||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
/* On Windows 7 or higher use BCrypt instead of the legacy CryptoAPI */
|
||||
# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0601
|
||||
/* On Windows Vista or higher use BCrypt instead of the legacy CryptoAPI */
|
||||
# if defined(_MSC_VER) && _MSC_VER > 1500 /* 1500 = Visual Studio 2008 */ \
|
||||
&& defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
|
||||
# define USE_BCRYPTGENRANDOM
|
||||
# endif
|
||||
|
||||
|
@ -129,7 +130,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();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
|
@ -26,7 +26,7 @@
|
|||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
# ifdef _WIN32
|
||||
# if defined(_WIN32) && !defined(_WIN32_WCE)
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# define stat _stat
|
||||
|
@ -254,7 +254,7 @@ const char *RAND_file_name(char *buf, size_t size)
|
|||
size_t len;
|
||||
int use_randfile = 1;
|
||||
|
||||
#if defined(_WIN32) && defined(CP_UTF8)
|
||||
#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE)
|
||||
DWORD envlen;
|
||||
WCHAR *var;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue