Coverage Report

Created: 2020-02-14 15:38

/src/botan/src/lib/entropy/entropy_srcs.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Entropy Source Polling
3
* (C) 2008-2010,2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/entropy_src.h>
9
#include <botan/rng.h>
10
11
#if defined(BOTAN_HAS_SYSTEM_RNG)
12
  #include <botan/system_rng.h>
13
#endif
14
15
#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
16
  #include <botan/internal/rdrand.h>
17
#endif
18
19
#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
20
  #include <botan/internal/rdseed.h>
21
#endif
22
23
#if defined(BOTAN_HAS_ENTROPY_SRC_DARN)
24
  #include <botan/internal/p9_darn.h>
25
#endif
26
27
#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
28
  #include <botan/internal/dev_random.h>
29
#endif
30
31
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
32
  #include <botan/internal/es_win32.h>
33
#endif
34
35
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
36
  #include <botan/internal/proc_walk.h>
37
  #include <botan/internal/os_utils.h>
38
#endif
39
40
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
41
  #include <botan/internal/getentropy.h>
42
#endif
43
44
namespace Botan {
45
46
#if defined(BOTAN_HAS_SYSTEM_RNG)
47
48
namespace {
49
50
class System_RNG_EntropySource final : public Entropy_Source
51
   {
52
   public:
53
      size_t poll(RandomNumberGenerator& rng) override
54
0
         {
55
0
         const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS;
56
0
         rng.reseed_from_rng(system_rng(), poll_bits);
57
0
         return poll_bits;
58
0
         }
59
60
0
      std::string name() const override { return "system_rng"; }
61
   };
62
63
}
64
65
#endif
66
67
std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
68
0
   {
69
0
#if defined(BOTAN_HAS_SYSTEM_RNG)
70
0
   if(name == "system_rng" || name == "win32_cryptoapi")
71
0
      {
72
0
      return std::unique_ptr<Entropy_Source>(new System_RNG_EntropySource);
73
0
      }
74
0
#endif
75
0
76
0
#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
77
0
   if(name == "rdrand")
78
0
      {
79
0
      return std::unique_ptr<Entropy_Source>(new Intel_Rdrand);
80
0
      }
81
0
#endif
82
0
83
0
#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
84
0
   if(name == "rdseed")
85
0
      {
86
0
      return std::unique_ptr<Entropy_Source>(new Intel_Rdseed);
87
0
      }
88
0
#endif
89
0
90
#if defined(BOTAN_HAS_ENTROPY_SRC_DARN)
91
   if(name == "p9_darn")
92
      {
93
      return std::unique_ptr<Entropy_Source>(new POWER9_DARN);
94
      }
95
#endif
96
97
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
98
   if(name == "getentropy")
99
      {
100
      return std::unique_ptr<Entropy_Source>(new Getentropy);
101
      }
102
#endif
103
104
0
#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
105
0
   if(name == "dev_random")
106
0
      {
107
0
      return std::unique_ptr<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES));
108
0
      }
109
0
#endif
110
0
111
0
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
112
0
   if(name == "proc_walk" && OS::running_in_privileged_state() == false)
113
0
      {
114
0
      const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
115
0
      if(!root_dir.empty())
116
0
         return std::unique_ptr<Entropy_Source>(new ProcWalking_EntropySource(root_dir));
117
0
      }
118
0
#endif
119
0
120
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
121
   if(name == "system_stats")
122
      {
123
      return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
124
      }
125
#endif
126
127
0
   BOTAN_UNUSED(name);
128
0
   return std::unique_ptr<Entropy_Source>();
129
0
   }
130
131
void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src)
132
0
   {
133
0
   if(src.get())
134
0
      {
135
0
      m_srcs.push_back(std::move(src));
136
0
      }
137
0
   }
138
139
std::vector<std::string> Entropy_Sources::enabled_sources() const
140
0
   {
141
0
   std::vector<std::string> sources;
142
0
   for(size_t i = 0; i != m_srcs.size(); ++i)
143
0
      {
144
0
      sources.push_back(m_srcs[i]->name());
145
0
      }
146
0
   return sources;
147
0
   }
148
149
size_t Entropy_Sources::poll(RandomNumberGenerator& rng,
150
                             size_t poll_bits,
151
                             std::chrono::milliseconds timeout)
152
0
   {
153
0
   typedef std::chrono::system_clock clock;
154
0
155
0
   auto deadline = clock::now() + timeout;
156
0
157
0
   size_t bits_collected = 0;
158
0
159
0
   for(size_t i = 0; i != m_srcs.size(); ++i)
160
0
      {
161
0
      bits_collected += m_srcs[i]->poll(rng);
162
0
163
0
      if (bits_collected >= poll_bits || clock::now() > deadline)
164
0
         break;
165
0
      }
166
0
167
0
   return bits_collected;
168
0
   }
169
170
size_t Entropy_Sources::poll_just(RandomNumberGenerator& rng, const std::string& the_src)
171
0
   {
172
0
   for(size_t i = 0; i != m_srcs.size(); ++i)
173
0
      {
174
0
      if(m_srcs[i]->name() == the_src)
175
0
         {
176
0
         return m_srcs[i]->poll(rng);
177
0
         }
178
0
      }
179
0
180
0
   return 0;
181
0
   }
182
183
Entropy_Sources::Entropy_Sources(const std::vector<std::string>& sources)
184
0
   {
185
0
   for(auto&& src_name : sources)
186
0
      {
187
0
      add_source(Entropy_Source::create(src_name));
188
0
      }
189
0
   }
190
191
Entropy_Sources& Entropy_Sources::global_sources()
192
0
   {
193
0
   static Entropy_Sources global_entropy_sources(BOTAN_ENTROPY_DEFAULT_SOURCES);
194
0
195
0
   return global_entropy_sources;
196
0
   }
197
198
}
199