Botan  2.10.0
Crypto and TLS for C++11
rdrand_rng.cpp
Go to the documentation of this file.
1 /*
2 * RDRAND RNG
3 * (C) 2016 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 
19  {
21  throw Invalid_State("Current CPU does not support RDRAND instruction");
22  }
23 
24 //static
26  {
27  return CPUID::has_rdrand();
28  }
29 
30 //static
32  {
33  for(;;)
34  {
35  bool ok = false;
36  uint32_t r = rdrand_status(ok);
37  if(ok)
38  return r;
39  }
40  }
41 
42 //static
43 BOTAN_FUNC_ISA("rdrnd")
44 uint32_t RDRAND_RNG::rdrand_status(bool& ok)
45  {
46  ok = false;
47  uint32_t r = 0;
48 
49  for(size_t i = 0; i != BOTAN_ENTROPY_RDRAND_RETRIES; ++i)
50  {
51 #if defined(BOTAN_USE_GCC_INLINE_ASM)
52  int cf = 0;
53 
54  // Encoding of rdrand %eax
55  asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" :
56  "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc");
57 #else
58  int cf = _rdrand32_step(&r);
59 #endif
60  if(1 == cf)
61  {
62  ok = true;
63  break;
64  }
65  }
66 
67  return r;
68  }
69 
70 void RDRAND_RNG::randomize(uint8_t out[], size_t out_len)
71  {
72  while(out_len >= 4)
73  {
74  uint32_t r = RDRAND_RNG::rdrand();
75 
76  store_le(r, out);
77  out += 4;
78  out_len -= 4;
79  }
80 
81  if(out_len) // between 1 and 3 trailing bytes
82  {
83  uint32_t r = RDRAND_RNG::rdrand();
84  for(size_t i = 0; i != out_len; ++i)
85  out[i] = get_byte(i, r);
86  }
87  }
88 
89 }
static bool available()
Definition: rdrand_rng.cpp:25
void randomize(uint8_t out[], size_t out_len) override
Definition: rdrand_rng.cpp:70
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
static uint32_t rdrand_status(bool &ok)
Definition: rdrand_rng.cpp:44
#define BOTAN_FUNC_ISA(isa)
Definition: compiler.h:71
Definition: alg_id.cpp:13
static uint32_t rdrand()
Definition: rdrand_rng.cpp:31
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:452