Fix output buffer cast in rdrand.cpp (Issue 388)
Update comments in rdrand.h Fix compile on CentOS 5 with GCC 4.1pull/354/merge
parent
78823bfd0c
commit
19df272d90
57
rdrand.cpp
57
rdrand.cpp
|
|
@ -15,13 +15,14 @@
|
||||||
|
|
||||||
// This file (and friends) provides both RDRAND and RDSEED. They were added at
|
// This file (and friends) provides both RDRAND and RDSEED. They were added at
|
||||||
// Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64}
|
// Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64}
|
||||||
// to select an implementation or "throw NotImplemented". At runtime, the
|
// to select an implementation or "throw NotImplemented". The class does not
|
||||||
// class uses the result of CPUID to determine if RDRAND or RDSEED are
|
// use CPUID to determine if RDRAND or RDSEED are available. If not available,
|
||||||
// available. If not available, then a SIGILL will result.
|
// then a SIGILL will result. Users of the classes should call HasRDRAND() or
|
||||||
|
// HasRDSEED() to determine if a generator is available.
|
||||||
// The original classes accepted a retry count. Retries were superflous for
|
// The original classes accepted a retry count. Retries were superflous for
|
||||||
// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending
|
// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending
|
||||||
// on the processor. Retries were removed at Crypto++ 6.0 because the
|
// on the processor. Retries were removed at Crypto++ 6.0 because
|
||||||
// functions always fulfill the request.
|
// GenerateBlock unconditionally retries and always fulfills the request.
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -69,9 +70,13 @@
|
||||||
# endif
|
# endif
|
||||||
# elif defined(CRYPTOPP_GCC_VERSION)
|
# elif defined(CRYPTOPP_GCC_VERSION)
|
||||||
# if defined(__RDRND__) || (CRYPTOPP_GCC_VERSION >= 40600)
|
# if defined(__RDRND__) || (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
|
# define ALL_RDRAND_INTRIN_AVAILABLE 1
|
||||||
|
# else
|
||||||
# define GCC_RDRAND_ASM_AVAILABLE 1
|
# define GCC_RDRAND_ASM_AVAILABLE 1
|
||||||
# endif
|
# endif
|
||||||
# if defined(__RDSEED__) || (CRYPTOPP_GCC_VERSION >= 40600)
|
# if defined(__RDSEED__) || (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
|
# define ALL_RDSEED_INTRIN_AVAILABLE 1
|
||||||
|
# else
|
||||||
# define GCC_RDSEED_ASM_AVAILABLE 1
|
# define GCC_RDSEED_ASM_AVAILABLE 1
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
@ -143,7 +148,7 @@ inline void RDRAND32(void* output)
|
||||||
: "=a" (*reinterpret_cast<word32*>(output))
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
#elif defined(GCC_RDRAND_ASM_AVAILABLE)
|
#elif defined(GCC_RDRAND_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
INTEL_NOPREFIX
|
INTEL_NOPREFIX
|
||||||
|
|
@ -154,6 +159,14 @@ inline void RDRAND32(void* output)
|
||||||
: "=a" (*reinterpret_cast<word32*>(output))
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
|
#elif defined(GCC_RDRAND_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 30200)
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
".byte 0x0f, 0xc7, 0xf0;\n"
|
||||||
|
".byte 0x73, 0xfb;\n"
|
||||||
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
|
: : "cc"
|
||||||
|
);
|
||||||
#elif defined(ALL_RDRAND_INTRIN_AVAILABLE)
|
#elif defined(ALL_RDRAND_INTRIN_AVAILABLE)
|
||||||
while(!_rdrand32_step(reinterpret_cast<word32*>(output))) {}
|
while(!_rdrand32_step(reinterpret_cast<word32*>(output))) {}
|
||||||
#else
|
#else
|
||||||
|
|
@ -174,7 +187,7 @@ inline void RDRAND64(void* output)
|
||||||
: "=a" (*reinterpret_cast<word64*>(output))
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
#elif defined(GCC_RDRAND_ASM_AVAILABLE)
|
#elif defined(GCC_RDRAND_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
INTEL_NOPREFIX
|
INTEL_NOPREFIX
|
||||||
|
|
@ -185,6 +198,14 @@ inline void RDRAND64(void* output)
|
||||||
: "=a" (*reinterpret_cast<word64*>(output))
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
|
#elif defined(GCC_RDRAND_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 30200)
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
".byte 0x48, 0x0f, 0xc7, 0xf0;\n"
|
||||||
|
".byte 0x73, 0xfa;\n"
|
||||||
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
|
: : "cc"
|
||||||
|
);
|
||||||
#elif defined(ALL_RDRAND_INTRIN_AVAILABLE)
|
#elif defined(ALL_RDRAND_INTRIN_AVAILABLE)
|
||||||
while(!_rdrand64_step(reinterpret_cast<unsigned long long*>(output))) {}
|
while(!_rdrand64_step(reinterpret_cast<unsigned long long*>(output))) {}
|
||||||
#else
|
#else
|
||||||
|
|
@ -274,7 +295,7 @@ inline void RDSEED32(void* output)
|
||||||
: "=a" (*reinterpret_cast<word32*>(output))
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
#elif defined(GCC_RDSEED_ASM_AVAILABLE)
|
#elif defined(GCC_RDSEED_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
INTEL_NOPREFIX
|
INTEL_NOPREFIX
|
||||||
|
|
@ -285,8 +306,16 @@ inline void RDSEED32(void* output)
|
||||||
: "=a" (*reinterpret_cast<word32*>(output))
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
|
#elif defined(GCC_RDSEED_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 30200)
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
".byte 0x0f, 0xc7, 0xf8;\n"
|
||||||
|
".byte 0x73, 0xfb;\n"
|
||||||
|
: "=a" (*reinterpret_cast<word32*>(output))
|
||||||
|
: : "cc"
|
||||||
|
);
|
||||||
#elif defined(ALL_RDSEED_INTRIN_AVAILABLE)
|
#elif defined(ALL_RDSEED_INTRIN_AVAILABLE)
|
||||||
while(!_rdseed32_step(reinterpret_cast<unsigned long long*>(output))) {}
|
while(!_rdseed32_step(reinterpret_cast<word32*>(output))) {}
|
||||||
#else
|
#else
|
||||||
// RDSEED not detected at compile time, or no suitable compiler found
|
// RDSEED not detected at compile time, or no suitable compiler found
|
||||||
throw NotImplemented("RDSEED: failed to find an implementation");
|
throw NotImplemented("RDSEED: failed to find an implementation");
|
||||||
|
|
@ -304,7 +333,7 @@ inline void RDSEED64(void* output)
|
||||||
: "=a" (*reinterpret_cast<word64*>(output))
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
#elif defined(GCC_RDSEED_ASM_AVAILABLE)
|
#elif defined(GCC_RDSEED_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 40600)
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
INTEL_NOPREFIX
|
INTEL_NOPREFIX
|
||||||
|
|
@ -315,6 +344,14 @@ inline void RDSEED64(void* output)
|
||||||
: "=a" (*reinterpret_cast<word64*>(output))
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
: : "cc"
|
: : "cc"
|
||||||
);
|
);
|
||||||
|
#elif defined(GCC_RDSEED_ASM_AVAILABLE) && (CRYPTOPP_GCC_VERSION >= 30200)
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
".byte 0x48, 0x0f, 0xc7, 0xf8;\n"
|
||||||
|
".byte 0x73, 0xfa;\n"
|
||||||
|
: "=a" (*reinterpret_cast<word64*>(output))
|
||||||
|
: : "cc"
|
||||||
|
);
|
||||||
#elif defined(ALL_RDSEED_INTRIN_AVAILABLE)
|
#elif defined(ALL_RDSEED_INTRIN_AVAILABLE)
|
||||||
while(!_rdseed64_step(reinterpret_cast<unsigned long long*>(output))) {}
|
while(!_rdseed64_step(reinterpret_cast<unsigned long long*>(output))) {}
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
19
rdrand.h
19
rdrand.h
|
|
@ -11,18 +11,21 @@
|
||||||
|
|
||||||
// This file (and friends) provides both RDRAND and RDSEED. They were added at
|
// This file (and friends) provides both RDRAND and RDSEED. They were added at
|
||||||
// Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64}
|
// Crypto++ 5.6.3. At compile time, it uses CRYPTOPP_BOOL_{X86|X32|X64}
|
||||||
// to select an implementation or "throw NotImplemented". At runtime, the
|
// to select an implementation or "throw NotImplemented". The class does not
|
||||||
// class uses the result of CPUID to determine if RDRAND or RDSEED are
|
// use CPUID to determine if RDRAND or RDSEED are available. If not available,
|
||||||
// available. If not available, then a SIGILL will result.
|
// then a SIGILL will result. Users of the classes should call HasRDRAND() or
|
||||||
|
// HasRDSEED() to determine if a generator is available.
|
||||||
// The original classes accepted a retry count. Retries were superflous for
|
// The original classes accepted a retry count. Retries were superflous for
|
||||||
// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending
|
// RDRAND, and RDSEED encountered a failure about 1 in 256 bytes depending
|
||||||
// on the processor. Retries were removed at Crypto++ 6.0 because the
|
// on the processor. Retries were removed at Crypto++ 6.0 because
|
||||||
// functions always fulfill the request.
|
// GenerateBlock unconditionally retries and always fulfills the request.
|
||||||
|
|
||||||
// Throughput varies wildly depending on processor and manufacturer. A Core i5 or
|
// Throughput varies wildly depending on processor and manufacturer. A Core i5 or
|
||||||
// Core i7 RDRAND can generate at over 200 MiB/s. A low end Celeron may perform
|
// Core i7 RDRAND can generate at over 200 MiB/s. Its below the theroetical
|
||||||
// RDRAND at 7 MiB/s. RDSEED performs at about 1/4 to 1/2 the rate of RDRAND.
|
// maximum, but it takes about 5 instructions to generate, retry and store a
|
||||||
// AMD RDRAND performed poorly during testing with Athlon X4 845 (Bulldozer v4).
|
// result. A low-end Celeron may perform RDRAND at about 7 MiB/s. RDSEED
|
||||||
|
// performs at about 1/4 to 1/2 the rate of RDRAND. AMD RDRAND performed poorly
|
||||||
|
// during testing with Athlon X4 845. The Bulldozer v4 only performed at 1 MiB/s.
|
||||||
|
|
||||||
// Microsoft added RDRAND in August 2012, VS2012; RDSEED in October 2013, VS2013.
|
// Microsoft added RDRAND in August 2012, VS2012; RDSEED in October 2013, VS2013.
|
||||||
// GCC added RDRAND in December 2010, GCC 4.6. LLVM added RDRAND in July 2012, Clang 3.2.
|
// GCC added RDRAND in December 2010, GCC 4.6. LLVM added RDRAND in July 2012, Clang 3.2.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue