Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

rdrand_rng.cpp
Go to the documentation of this file.
1 /*
2 * RDRAND RNG
3 * (C) 2016,2019 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/rdrand_rng.h>
9 #include <botan/loadstor.h>
10 #include <botan/cpuid.h>
11
12 #if !defined(BOTAN_USE_GCC_INLINE_ASM)
13 #include <immintrin.h>
14 #endif
15
16 namespace Botan {
17
18 namespace {
19
20 #if defined(BOTAN_TARGET_ARCH_IS_X86_64)
21 typedef uint64_t rdrand_output;
22 #else
23 typedef uint32_t rdrand_output;
24 #endif
25
26 BOTAN_FUNC_ISA("rdrnd")
27 rdrand_output read_rdrand()
28 {
29 /*
30 * According to Intel, RDRAND is guaranteed to generate a random
31 * number within 10 retries on a working CPU
32 */
33 const size_t RDRAND_RETRIES = 10;
34
35 for(size_t i = 0; i < RDRAND_RETRIES; ++i)
36 {
37 rdrand_output r = 0;
38 int cf = 0;
39
40 #if defined(BOTAN_USE_GCC_INLINE_ASM)
41 // same asm seq works for 32 and 64 bit
42 asm("rdrand %0; adcl $0,%1" :
43 "=r" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc");
44 #elif defined(BOTAN_TARGET_ARCH_IS_X86_64)
45 cf = _rdrand64_step(&r);
46 #else
47 cf = _rdrand32_step(&r);
48 #endif
49 if(1 == cf)
50 {
51 return r;
52 }
53 }
54
55 throw PRNG_Unseeded("RDRAND read failed");
56 }
57
58 }
59
60 void RDRAND_RNG::randomize(uint8_t out[], size_t out_len)
61 {
62 while(out_len >= sizeof(rdrand_output))
63 {
64 const rdrand_output r = read_rdrand();
65 store_le(r, out);
66 out += sizeof(rdrand_output);
67 out_len -= sizeof(rdrand_output);
68 }
69
70 if(out_len > 0) // at most sizeof(rdrand_output)-1
71 {
72 const rdrand_output r = read_rdrand();
73 for(size_t i = 0; i != out_len; ++i)
74 out[i] = get_byte(i, r);
75 }
76 }
77
78 RDRAND_RNG::RDRAND_RNG()
79 {
80 if(!RDRAND_RNG::available())
81 throw Invalid_State("Current CPU does not support RDRAND instruction");
82 }
83
84 //static
85 bool RDRAND_RNG::available()
86 {
87 return CPUID::has_rdrand();
88 }
89
90 //static
91 uint32_t RDRAND_RNG::rdrand()
92 {
93 return static_cast<uint32_t>(read_rdrand());
94 }
95
96 //static
97 BOTAN_FUNC_ISA("rdrnd")
98 uint32_t RDRAND_RNG::rdrand_status(bool& ok)
99 {
100 ok = false;
101
102 try
103 {
104 const uint32_t r = static_cast<uint32_t>(read_rdrand());
105 ok = true;
106 return r;
107 }
108 catch(PRNG_Unseeded&) {}
109
110 return 0;
111 }
112
113 }
Botan::RDRAND_RNG::available
static bool available()
Definition: rdrand_rng.cpp:85
Botan::RDRAND_RNG::randomize
void randomize(uint8_t out[], size_t out_len) override
Definition: rdrand_rng.cpp:60
Botan::get_byte
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
Botan::RDRAND_RNG
Definition: rdrand_rng.h:15
Botan::PRNG_Unseeded
Definition: exceptn.h:226
BOTAN_FUNC_ISA
#define BOTAN_FUNC_ISA(isa)
Definition: compiler.h:71
Botan
Definition: alg_id.cpp:13
Botan::RDRAND_RNG::rdrand
static uint32_t rdrand()
Definition: rdrand_rng.cpp:91
Botan::Invalid_State
Definition: exceptn.h:215
Botan::RDRAND_RNG::RDRAND_RNG
RDRAND_RNG()
Definition: rdrand_rng.cpp:78
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:454