Botan  1.11.15
src/lib/rng/rng.h
Go to the documentation of this file.
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