Botan
1.11.15
|
00001 /* 00002 * RandomNumberGenerator 00003 * (C) 1999-2009 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_RANDOM_NUMBER_GENERATOR_H__ 00009 #define BOTAN_RANDOM_NUMBER_GENERATOR_H__ 00010 00011 #include <botan/entropy_src.h> 00012 #include <botan/exceptn.h> 00013 #include <string> 00014 #include <mutex> 00015 00016 namespace Botan { 00017 00018 /** 00019 * This class represents a random number (RNG) generator object. 00020 */ 00021 class BOTAN_DLL RandomNumberGenerator 00022 { 00023 public: 00024 /** 00025 * Create a seeded and active RNG object for general application use 00026 * Added in 1.8.0 00027 */ 00028 static RandomNumberGenerator* make_rng(); 00029 00030 /** 00031 * Randomize a byte array. 00032 * @param output the byte array to hold the random output. 00033 * @param length the length of the byte array output. 00034 */ 00035 virtual void randomize(byte output[], size_t length) = 0; 00036 00037 /** 00038 * Return a random vector 00039 * @param bytes number of bytes in the result 00040 * @return randomized vector of length bytes 00041 */ 00042 virtual secure_vector<byte> random_vec(size_t bytes) 00043 { 00044 secure_vector<byte> output(bytes); 00045 randomize(&output[0], output.size()); 00046 return output; 00047 } 00048 00049 /** 00050 * Return a random byte 00051 * @return random byte 00052 */ 00053 byte next_byte() 00054 { 00055 byte out; 00056 this->randomize(&out, 1); 00057 return out; 00058 } 00059 00060 /** 00061 * Check whether this RNG is seeded. 00062 * @return true if this RNG was already seeded, false otherwise. 00063 */ 00064 virtual bool is_seeded() const = 0; 00065 00066 /** 00067 * Clear all internally held values of this RNG. 00068 */ 00069 virtual void clear() = 0; 00070 00071 /** 00072 * Return the name of this object 00073 */ 00074 virtual std::string name() const = 0; 00075 00076 /** 00077 * Seed this RNG using the entropy sources it contains. 00078 * @param bits_to_collect is the number of bits of entropy to 00079 attempt to gather from the entropy sources 00080 */ 00081 virtual void reseed(size_t bits_to_collect) = 0; 00082 00083 /** 00084 * Add entropy to this RNG. 00085 * @param in a byte array containg the entropy to be added 00086 * @param length the length of the byte array in 00087 */ 00088 virtual void add_entropy(const byte in[], size_t length) = 0; 00089 00090 /* 00091 * Never copy a RNG, create a new one 00092 */ 00093 RandomNumberGenerator(const RandomNumberGenerator& rng) = delete; 00094 RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete; 00095 00096 RandomNumberGenerator() {} 00097 virtual ~RandomNumberGenerator() {} 00098 }; 00099 00100 /** 00101 * Null/stub RNG - fails if you try to use it for anything 00102 */ 00103 class BOTAN_DLL Null_RNG : public RandomNumberGenerator 00104 { 00105 public: 00106 void randomize(byte[], size_t) override { throw PRNG_Unseeded("Null_RNG"); } 00107 00108 void clear() override {} 00109 00110 std::string name() const override { return "Null_RNG"; } 00111 00112 void reseed(size_t) override {} 00113 bool is_seeded() const override { return false; } 00114 void add_entropy(const byte[], size_t) override {} 00115 }; 00116 00117 /** 00118 * Wraps access to a RNG in a mutex 00119 */ 00120 class BOTAN_DLL Serialized_RNG : public RandomNumberGenerator 00121 { 00122 public: 00123 void randomize(byte out[], size_t len) 00124 { 00125 std::lock_guard<std::mutex> lock(m_mutex); 00126 m_rng->randomize(out, len); 00127 } 00128 00129 bool is_seeded() const 00130 { 00131 std::lock_guard<std::mutex> lock(m_mutex); 00132 return m_rng->is_seeded(); 00133 } 00134 00135 void clear() 00136 { 00137 std::lock_guard<std::mutex> lock(m_mutex); 00138 m_rng->clear(); 00139 } 00140 00141 std::string name() const 00142 { 00143 std::lock_guard<std::mutex> lock(m_mutex); 00144 return m_rng->name(); 00145 } 00146 00147 void reseed(size_t poll_bits) 00148 { 00149 std::lock_guard<std::mutex> lock(m_mutex); 00150 m_rng->reseed(poll_bits); 00151 } 00152 00153 void add_entropy(const byte in[], size_t len) 00154 { 00155 std::lock_guard<std::mutex> lock(m_mutex); 00156 m_rng->add_entropy(in, len); 00157 } 00158 00159 Serialized_RNG() : m_rng(RandomNumberGenerator::make_rng()) {} 00160 private: 00161 mutable std::mutex m_mutex; 00162 std::unique_ptr<RandomNumberGenerator> m_rng; 00163 }; 00164 00165 } 00166 00167 #endif