11 #if CRYPTOPP_MSC_VERSION
12 # pragma warning(disable: 4100)
41 #define NASM_RDRAND_ASM_AVAILABLE 1
42 #define NASM_RDSEED_ASM_AVAILABLE 1
51 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
52 # ifndef CRYPTOPP_CPUID_AVAILABLE
53 # define CRYPTOPP_CPUID_AVAILABLE
57 #if defined(CRYPTOPP_CPUID_AVAILABLE)
58 # if defined(CRYPTOPP_MSC_VERSION)
59 # define MASM_RDRAND_ASM_AVAILABLE 1
60 # define MASM_RDSEED_ASM_AVAILABLE 1
61 # elif defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION)
62 # define GCC_RDRAND_ASM_AVAILABLE 1
63 # define GCC_RDSEED_ASM_AVAILABLE 1
64 # elif defined(__SUNPRO_CC)
65 # if defined(__RDRND__) && (__SUNPRO_CC >= 0x5130)
66 # define ALL_RDRAND_INTRIN_AVAILABLE 1
67 # elif (__SUNPRO_CC >= 0x5100)
68 # define GCC_RDRAND_ASM_AVAILABLE 1
70 # if defined(__RDSEED__) && (__SUNPRO_CC >= 0x5140)
71 # define ALL_RDSEED_INTRIN_AVAILABLE 1
72 # elif (__SUNPRO_CC >= 0x5100)
73 # define GCC_RDSEED_ASM_AVAILABLE 1
75 # elif defined(CRYPTOPP_GCC_VERSION)
76 # if defined(__RDRND__) && (CRYPTOPP_GCC_VERSION >= 30200)
77 # define ALL_RDRAND_INTRIN_AVAILABLE 1
79 # define GCC_RDRAND_ASM_AVAILABLE 1
81 # if defined(__RDSEED__) && (CRYPTOPP_GCC_VERSION >= 30200)
82 # define ALL_RDSEED_INTRIN_AVAILABLE 1
84 # define GCC_RDSEED_ASM_AVAILABLE 1
91 # if MASM_RDRAND_ASM_AVAILABLE
92 # pragma message ("MASM_RDRAND_ASM_AVAILABLE is 1")
93 # elif NASM_RDRAND_ASM_AVAILABLE
94 # pragma message ("NASM_RDRAND_ASM_AVAILABLE is 1")
95 # elif GCC_RDRAND_ASM_AVAILABLE
96 # pragma message ("GCC_RDRAND_ASM_AVAILABLE is 1")
97 # elif ALL_RDRAND_INTRIN_AVAILABLE
98 # pragma message ("ALL_RDRAND_INTRIN_AVAILABLE is 1")
100 # pragma message ("RDRAND is not available")
102 # if MASM_RDSEED_ASM_AVAILABLE
103 # pragma message ("MASM_RDSEED_ASM_AVAILABLE is 1")
104 # elif NASM_RDSEED_ASM_AVAILABLE
105 # pragma message ("NASM_RDSEED_ASM_AVAILABLE is 1")
106 # elif GCC_RDSEED_ASM_AVAILABLE
107 # pragma message ("GCC_RDSEED_ASM_AVAILABLE is 1")
108 # elif ALL_RDSEED_INTRIN_AVAILABLE
109 # pragma message ("ALL_RDSEED_INTRIN_AVAILABLE is 1")
111 # pragma message ("RDSEED is not available")
118 #if (ALL_RDRAND_INTRIN_AVAILABLE || ALL_RDSEED_INTRIN_AVAILABLE)
119 # include <immintrin.h>
120 # if defined(__GNUC__) && (CRYPTOPP_GCC_VERSION >= 40600)
121 # include <x86intrin.h>
123 # if defined(__has_include)
124 # if __has_include(<x86intrin.h>)
125 # include <x86intrin.h>
130 #if MASM_RDRAND_ASM_AVAILABLE
132 extern "C" int CRYPTOPP_FASTCALL MASM_RRA_GenerateBlock(
byte*,
size_t,
unsigned int);
135 extern "C" int MASM_RRA_GenerateBlock(
byte*,
size_t,
unsigned int);
140 #if MASM_RDSEED_ASM_AVAILABLE
142 extern "C" int CRYPTOPP_FASTCALL MASM_RSA_GenerateBlock(
byte*,
size_t,
unsigned int);
145 extern "C" int MASM_RSA_GenerateBlock(
byte*,
size_t,
unsigned int);
150 #if NASM_RDRAND_ASM_AVAILABLE
151 extern "C" int NASM_RRA_GenerateBlock(
byte*,
size_t,
unsigned int);
154 #if NASM_RDSEED_ASM_AVAILABLE
155 extern "C" int NASM_RSA_GenerateBlock(
byte*,
size_t,
unsigned int);
163 #if ALL_RDRAND_INTRIN_AVAILABLE
164 static int ALL_RRI_GenerateBlock(
byte *output,
size_t size,
unsigned int safety)
167 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
173 while (size >=
sizeof(val))
175 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
176 if (_rdrand32_step((word32*)output))
179 if (_rdrand64_step(
reinterpret_cast<unsigned long long*
>(output)))
182 output +=
sizeof(val);
197 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
198 if (_rdrand32_step(&val))
201 if (_rdrand64_step(
reinterpret_cast<unsigned long long*
>(&val)))
204 memcpy(output, &val, size);
219 return int(size == 0);
221 #endif // ALL_RDRAND_INTRINSIC_AVAILABLE
223 #if GCC_RDRAND_ASM_AVAILABLE
224 static int GCC_RRA_GenerateBlock(
byte *output,
size_t size,
unsigned int safety)
227 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
236 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
237 ".byte 0x48, 0x0f, 0xc7, 0xf0;\n"
239 ".byte 0x0f, 0xc7, 0xf0;\n"
242 :
"=a" (val),
"=qm" (rc)
249 if (size >=
sizeof(val))
251 #if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32)
252 *((word64*)(
void *)output) = val;
253 #elif defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && (CRYPTOPP_BOOL_X86)
254 *((word32*)(
void *)output) = val;
256 memcpy(output, &val,
sizeof(val));
258 output +=
sizeof(val);
263 memcpy(output, &val, size);
279 return int(size == 0);
282 #endif // GCC_RDRAND_ASM_AVAILABLE
284 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
287 CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size);
291 throw NotImplemented(
"RDRAND: rdrand is not available on this platform");
293 int rc; CRYPTOPP_UNUSED(rc);
294 #if MASM_RDRAND_ASM_AVAILABLE
295 rc = MASM_RRA_GenerateBlock(output, size, m_retries);
296 if (!rc) {
throw RDRAND_Err(
"MASM_RRA_GenerateBlock"); }
297 #elif NASM_RDRAND_ASM_AVAILABLE
298 rc = NASM_RRA_GenerateBlock(output, size, m_retries);
299 if (!rc) {
throw RDRAND_Err(
"NASM_RRA_GenerateBlock"); }
300 #elif ALL_RDRAND_INTRIN_AVAILABLE
301 rc = ALL_RRI_GenerateBlock(output, size, m_retries);
302 if (!rc) {
throw RDRAND_Err(
"ALL_RRI_GenerateBlock"); }
303 #elif GCC_RDRAND_ASM_AVAILABLE
304 rc = GCC_RRA_GenerateBlock(output, size, m_retries);
305 if (!rc) {
throw RDRAND_Err(
"GCC_RRA_GenerateBlock"); }
308 throw NotImplemented(
"RDRAND: failed to find a suitable implementation???");
309 #endif // CRYPTOPP_CPUID_AVAILABLE
317 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
333 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
338 #if ALL_RDSEED_INTRIN_AVAILABLE
339 static int ALL_RSI_GenerateBlock(
byte *output,
size_t size,
unsigned int safety)
342 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
348 while (size >=
sizeof(val))
350 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
351 if (_rdseed32_step((word32*)output))
354 if (_rdseed64_step(
reinterpret_cast<unsigned long long*
>(output)))
357 output +=
sizeof(val);
372 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32
373 if (_rdseed32_step(&val))
376 if (_rdseed64_step(
reinterpret_cast<unsigned long long*
>(&val)))
379 memcpy(output, &val, size);
394 return int(size == 0);
396 #endif // ALL_RDSEED_INTRIN_AVAILABLE
398 #if GCC_RDSEED_ASM_AVAILABLE
399 static int GCC_RSA_GenerateBlock(
byte *output,
size_t size,
unsigned int safety)
402 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
411 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
412 ".byte 0x48, 0x0f, 0xc7, 0xf8;\n"
414 ".byte 0x0f, 0xc7, 0xf8;\n"
417 :
"=a" (val),
"=qm" (rc)
424 if (size >=
sizeof(val))
426 #if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32)
427 *((word64*)(
void *)output) = val;
428 #elif defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS) && (CRYPTOPP_BOOL_X86)
429 *((word32*)(
void *)output) = val;
431 memcpy(output, &val,
sizeof(val));
433 output +=
sizeof(val);
438 memcpy(output, &val, size);
454 return int(size == 0);
456 #endif // GCC_RDSEED_ASM_AVAILABLE
458 #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
461 CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size);
465 throw NotImplemented(
"RDSEED: rdseed is not available on this platform");
467 int rc; CRYPTOPP_UNUSED(rc);
468 #if MASM_RDSEED_ASM_AVAILABLE
469 rc = MASM_RSA_GenerateBlock(output, size, m_retries);
470 if (!rc) {
throw RDSEED_Err(
"MASM_RSA_GenerateBlock"); }
471 #elif NASM_RDSEED_ASM_AVAILABLE
472 rc = NASM_RSA_GenerateBlock(output, size, m_retries);
473 if (!rc) {
throw RDRAND_Err(
"NASM_RSA_GenerateBlock"); }
474 #elif ALL_RDSEED_INTRIN_AVAILABLE
475 rc = ALL_RSI_GenerateBlock(output, size, m_retries);
476 if (!rc) {
throw RDSEED_Err(
"ALL_RSI_GenerateBlock"); }
477 #elif GCC_RDSEED_ASM_AVAILABLE
478 rc = GCC_RSA_GenerateBlock(output, size, m_retries);
479 if (!rc) {
throw RDSEED_Err(
"GCC_RSA_GenerateBlock"); }
482 throw NotImplemented(
"RDSEED: failed to find a suitable implementation???");
491 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32
507 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64