提交 ef643cc7 编写于 作者: D Dr. Stephen Henson

Use rdrand as additional entropy source.

If available rdrand is used as an additional entropy source for the
PRNG and for additional input in FIPS mode.
上级 4b64e0cb
...@@ -167,6 +167,8 @@ int rand_predictable=0; ...@@ -167,6 +167,8 @@ int rand_predictable=0;
const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
static void rand_hw_seed(EVP_MD_CTX *ctx);
static void ssleay_rand_cleanup(void); static void ssleay_rand_cleanup(void);
static int ssleay_rand_seed(const void *buf, int num); static int ssleay_rand_seed(const void *buf, int num);
static int ssleay_rand_add(const void *buf, int num, double add_entropy); static int ssleay_rand_add(const void *buf, int num, double add_entropy);
...@@ -531,6 +533,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo) ...@@ -531,6 +533,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
sizeof tv)) sizeof tv))
goto err; goto err;
curr_time = 0; curr_time = 0;
rand_hw_seed(&m);
} }
if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH)) if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
goto err; goto err;
...@@ -663,3 +666,79 @@ static int ssleay_rand_status(void) ...@@ -663,3 +666,79 @@ static int ssleay_rand_status(void)
return ret; return ret;
} }
/* rand_hw_seed: get seed data from any available hardware RNG.
* only currently supports rdrand.
*/
/* Adapted from eng_rdrand.c */
#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
#define RDRAND_CALLS 4
size_t OPENSSL_ia32_rdrand(void);
extern unsigned int OPENSSL_ia32cap_P[];
static void rand_hw_seed(EVP_MD_CTX *ctx)
{
int i;
if (!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
return;
for (i = 0; i < RDRAND_CALLS; i++)
{
size_t rnd;
rnd = OPENSSL_ia32_rdrand();
if (rnd == 0)
return;
MD_Update(ctx, (unsigned char *)rnd, sizeof(size_t));
}
}
/* XOR an existing buffer with random data */
void rand_hw_xor(unsigned char *buf, size_t num)
{
size_t rnd;
if (!(OPENSSL_ia32cap_P[1] & (1<<(62-32))))
return;
while (num >= sizeof(size_t))
{
rnd = OPENSSL_ia32_rdrand();
if (rnd == 0)
return;
*((size_t *)buf) ^= rnd;
buf += sizeof(size_t);
num -= sizeof(size_t);
}
if (num)
{
rnd = OPENSSL_ia32_rdrand();
if (rnd == 0)
return;
while(num)
{
*buf ^= rnd & 0xff;
rnd >>= 8;
buf++;
num--;
}
}
}
#else
static void rand_hw_seed(EVP_MD_CTX *ctx)
{
return;
}
void rand_hw_xor(unsigned char *buf, size_t num)
{
return;
}
#endif
...@@ -154,5 +154,6 @@ ...@@ -154,5 +154,6 @@
#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) #define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
#endif #endif
void rand_hw_xor(unsigned char *buf, size_t num);
#endif #endif
...@@ -227,6 +227,7 @@ static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) ...@@ -227,6 +227,7 @@ static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
static unsigned char buf[16]; static unsigned char buf[16];
static unsigned long counter; static unsigned long counter;
FIPS_get_timevec(buf, &counter); FIPS_get_timevec(buf, &counter);
rand_hw_xor(buf, sizeof(buf));
*pout = buf; *pout = buf;
return sizeof(buf); return sizeof(buf);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册