Merge 22c6baa3de
into 2076361f88
This commit is contained in:
commit
c4daf148da
24
configure.ac
24
configure.ac
|
@ -171,12 +171,19 @@ AC_ARG_WITH([system-univalue],
|
|||
[system_univalue=$withval],
|
||||
[system_univalue=no]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([zmq],
|
||||
[AS_HELP_STRING([--disable-zmq],
|
||||
[disable ZMQ notifications])],
|
||||
[use_zmq=$enableval],
|
||||
[use_zmq=yes])
|
||||
|
||||
AC_ARG_ENABLE([rdseed],
|
||||
[AS_HELP_STRING([--disable-rdseed],
|
||||
[disable rdseed entropy (default is yes where available)])],
|
||||
[use_rdseed=$enableval],
|
||||
[use_rdseed=yes])
|
||||
|
||||
AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], [])
|
||||
|
||||
AC_ARG_ENABLE(man,
|
||||
|
@ -861,6 +868,23 @@ else
|
|||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
dnl Use rdseed to gather entropy
|
||||
if test "x$use_rdseed" = "xyes"; then
|
||||
dnl Only enable rdseed on the compiler when targeting x86
|
||||
case $host in
|
||||
*x86*)
|
||||
CXXFLAGS="$CXXFLAGS -mrdseed"
|
||||
;;
|
||||
*i686*)
|
||||
CXXFLAGS="$CXXFLAGS -mrdseed"
|
||||
;;
|
||||
*)
|
||||
use_rdseed="no"
|
||||
esac
|
||||
fi
|
||||
|
||||
save_CXXFLAGS="${CXXFLAGS}"
|
||||
CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}"
|
||||
AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT
|
||||
|
|
58
src/lowlevel.h
Normal file
58
src/lowlevel.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2021 The Dogecoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
//Here be dragons, wizards, witches and master of the dark arts.
|
||||
//Careful thou who wonders 'round these parts without magic spells,
|
||||
//mana potions and doggy treats...especially magical doggy treats.
|
||||
|
||||
|
||||
//Only define this header on x86
|
||||
#if ( defined(i386) || defined(__i386) || defined(__i386__) || \
|
||||
defined( __386) || defined(_X86_) || defined( _M_I86) || \
|
||||
defined(__i386__) || defined(__X86__) || defined(__x86_64) )
|
||||
|
||||
#ifndef LOWLEVEL_H
|
||||
#define LOWLEVEL_H
|
||||
#define LOWLEVEL_USE_RDSEED (1)
|
||||
|
||||
#if ( defined(_WIN32) || defined(WIN32) || \
|
||||
defined(__WIN32__) || defined(__NT__) )
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
#ifndef bit_RDSEED
|
||||
#define bit_RDSEED (1 << 18)
|
||||
#endif
|
||||
|
||||
/* To address compatibility issues with MacOS, given the lacking implementation
|
||||
* of intrinsics we here implement rdseed in byte code so that we may use it
|
||||
* anywhere the ISA extension permits it.
|
||||
*
|
||||
* See: https://software.intel.com/content/www/us/en/develop/articles/the-drng-library-and-manual.html
|
||||
* You will find this function definition at:
|
||||
* libdrng-1.0.tar.gz: https://software.intel.com/file/469237/download
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
# define _rdseed16_step(x) ({ unsigned char err; asm volatile(".byte 0x66; .byte 0x0f; .byte 0xc7; .byte 0xf8; setc %1":"=a"(*x), "=qm"(err)); err; })
|
||||
# define _rdseed32_step(x) ({ unsigned char err; asm volatile(".byte 0x0f; .byte 0xc7; .byte 0xf8; setc %1":"=a"(*x), "=qm"(err)); err; })
|
||||
#endif
|
||||
|
||||
/* \union Useful for buffers that will need to be hashed
|
||||
* where data gather comes from different int types.
|
||||
*/
|
||||
union block_512bits {
|
||||
char byte[64];
|
||||
unsigned char ubyte[64];
|
||||
uint16_t word[32];
|
||||
uint32_t dword[16];
|
||||
uint64_t qword[8];
|
||||
unsigned long long int ulli[8];
|
||||
};
|
||||
|
||||
#endif /*LOWLEVEL_H*/
|
||||
#endif /*Detect x86*/
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <lowlevel.h>
|
||||
|
||||
static void RandFailure()
|
||||
{
|
||||
|
@ -129,20 +130,87 @@ void GetRandBytes(unsigned char* buf, int num)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* /fn int getRDSEED( uint64_t *buff, int num)
|
||||
* /brief Use Intel's SP 800-90B & C compliant Hardware implemented
|
||||
* instruction to add entropy to the pool use to create keys.
|
||||
*
|
||||
* For details, see: https://software.intel.com/content/www/us/en/develop/blogs/the-difference-between-rdrand-and-rdseed.html
|
||||
*
|
||||
* /param buff Buffer to fill with random bits.
|
||||
* /param num Number of 64-bit words to write to buffer.
|
||||
* /return Returns 1 if the hardware returned a valid stream of random numbers, 0 otherwise.
|
||||
*
|
||||
*/
|
||||
int getRDSEED( uint64_t *buff, uint32_t num){
|
||||
//Initialize state to 0, or failed.
|
||||
uint32_t cumulativeStatus = 0;
|
||||
|
||||
#ifdef LOWELEVEL_USE_RDSEEED
|
||||
//Check to see if the processor running this code has
|
||||
//this Instruction. Most Intel/AMD CPUs after 2015
|
||||
//should have this instruction.
|
||||
uint32_t level, eax, ebx, ecx, edx;
|
||||
|
||||
//Level where the RDSEED feature is described
|
||||
level = 1;
|
||||
|
||||
//Extract feature vector
|
||||
__get_cpuid(level, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
//Check if RDSEED exists on this processor
|
||||
if( (ecx & bit_RDSEED) == bit_RDSEED ) {
|
||||
|
||||
//Re-initialize value to 1, or success
|
||||
cumulativeStatus = 1;
|
||||
|
||||
for( uint32_t kk = 0; kk < num; kk++){
|
||||
//Get RBG data
|
||||
uint32_t rng_high, rng_low;
|
||||
|
||||
int32_t status1 = _rdseed32_step( &rng_low );
|
||||
int32_t status2 = _rdseed32_step( &rng_high );
|
||||
|
||||
//Place values into a 64-bit register
|
||||
uint64_t temp = rng_high;
|
||||
temp <<= 32;
|
||||
temp += rng_low;
|
||||
|
||||
//Store into buffer
|
||||
buff[kk] = temp;
|
||||
|
||||
//Update status value.
|
||||
//cumulativeStatus will be 1 iff all iterations are 1.
|
||||
cumulativeStatus &= status1 & status2;
|
||||
}
|
||||
}
|
||||
#endif /*LOWLEVEL_USE_RDSEED*/
|
||||
|
||||
return cumulativeStatus;
|
||||
}
|
||||
|
||||
void GetStrongRandBytes(unsigned char* out, int num)
|
||||
{
|
||||
assert(num <= 32);
|
||||
assert(num <= 64);
|
||||
CSHA512 hasher;
|
||||
unsigned char buf[64];
|
||||
|
||||
// First source: OpenSSL's RNG
|
||||
RandAddSeedPerfmon();
|
||||
GetRandBytes(buf, 32);
|
||||
hasher.Write(buf, 32);
|
||||
GetRandBytes(buf, 64);
|
||||
hasher.Write(buf, 64);
|
||||
|
||||
// Second source: OS RNG
|
||||
GetOSRand(buf);
|
||||
hasher.Write(buf, 32);
|
||||
hasher.Write(buf, 64);
|
||||
|
||||
//Third Source: Intel's NIST SP 800-90B & C compliant RBG
|
||||
//if available, use it.
|
||||
#ifdef LOWLEVEL_H
|
||||
block_512bits buf2;
|
||||
if ( getRDSEED(buf2.qword, 8) == 1 )
|
||||
hasher.Write(buf2.ubyte, 64);
|
||||
#endif
|
||||
|
||||
// Produce output
|
||||
hasher.Finalize(buf);
|
||||
|
|
Loading…
Reference in a new issue