00001
#ifndef CRYPTOPP_OSRNG_H
00002
#define CRYPTOPP_OSRNG_H
00003
00004
#include "cryptopp_config.h"
00005
00006
#ifdef OS_RNG_AVAILABLE
00007
00008
#include "randpool.h"
00009
#include "rng.h"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013
00014 class
OS_RNG_Err : public
Exception
00015 {
00016
public:
00017
OS_RNG_Err(
const std::string &operation);
00018 };
00019
00020
#ifdef NONBLOCKING_RNG_AVAILABLE
00021
00022
#ifdef CRYPTOPP_WIN32_AVAILABLE
00023
class MicrosoftCryptoProvider
00024 {
00025
public:
00026 MicrosoftCryptoProvider();
00027 ~MicrosoftCryptoProvider();
00028
#if defined(_WIN64)
00029
typedef unsigned __int64 ProviderHandle;
00030
#else
00031
typedef unsigned long ProviderHandle;
00032
#endif
00033
ProviderHandle GetProviderHandle()
const {
return m_hProvider;}
00034
private:
00035 ProviderHandle m_hProvider;
00036 };
00037
#endif
00038
00039
00040 class NonblockingRng :
public RandomNumberGenerator
00041 {
00042
public:
00043
NonblockingRng();
00044 ~
NonblockingRng();
00045 byte
GenerateByte();
00046
void GenerateBlock(byte *output,
unsigned int size);
00047
00048
protected:
00049
#ifdef CRYPTOPP_WIN32_AVAILABLE
00050
# ifndef WORKAROUND_MS_BUG_Q258000
00051
MicrosoftCryptoProvider m_Provider;
00052
# endif
00053
#else
00054
int m_fd;
00055
#endif
00056
};
00057
00058
#endif
00059
00060
#ifdef BLOCKING_RNG_AVAILABLE
00061
00062
00063
class BlockingRng :
public RandomNumberGenerator
00064 {
00065
public:
00066 BlockingRng();
00067 ~BlockingRng();
00068 byte
GenerateByte();
00069
void GenerateBlock(byte *output,
unsigned int size);
00070
00071
protected:
00072
int m_fd;
00073 };
00074
00075
#endif
00076
00077
void OS_GenerateRandomBlock(
bool blocking, byte *output,
unsigned int size);
00078
00079
00080
00081 class AutoSeededRandomPool :
public RandomPool
00082 {
00083
public:
00084
00085 explicit AutoSeededRandomPool(
bool blocking =
false,
unsigned int seedSize = 32)
00086 {Reseed(blocking, seedSize);}
00087
void Reseed(
bool blocking =
false,
unsigned int seedSize = 32);
00088 };
00089
00090
00091
template <
class BLOCK_CIPHER>
00092 class AutoSeededX917RNG :
public RandomNumberGenerator
00093 {
00094
public:
00095
00096 explicit AutoSeededX917RNG(
bool blocking =
false)
00097 {Reseed(blocking);}
00098
void Reseed(
bool blocking =
false);
00099
00100
void Reseed(
const byte *key,
unsigned int keylength,
const byte *seed,
unsigned long timeVector);
00101
00102 byte
GenerateByte();
00103
00104
private:
00105 member_ptr<RandomNumberGenerator> m_rng;
00106
SecByteBlock m_lastBlock;
00107
bool m_isDifferent;
00108
unsigned int m_counter;
00109 };
00110
00111
template <
class BLOCK_CIPHER>
00112
void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(
const byte *key,
unsigned int keylength,
const byte *seed,
unsigned long timeVector)
00113 {
00114 m_rng.reset(
new X917RNG(
new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00115
00116
00117 m_lastBlock.
resize(16);
00118 m_rng->GenerateBlock(m_lastBlock, m_lastBlock.
size());
00119 m_counter = 0;
00120 m_isDifferent =
false;
00121 }
00122
00123
template <
class BLOCK_CIPHER>
00124
void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(
bool blocking)
00125 {
00126
SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00127
const byte *key;
00128
do
00129 {
00130 OS_GenerateRandomBlock(blocking, seed, seed.
size());
00131 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00132 }
00133
while (memcmp(key, seed, STDMIN((
unsigned int)BLOCK_CIPHER::BLOCKSIZE, (
unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00134
00135 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0);
00136 }
00137
00138
template <
class BLOCK_CIPHER>
00139 byte
AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
00140 {
00141 byte b = m_rng->GenerateByte();
00142
00143
00144 m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
00145 m_lastBlock[m_counter] = b;
00146 ++m_counter;
00147
if (m_counter == m_lastBlock.
size())
00148 {
00149
if (!m_isDifferent)
00150
throw SelfTestFailure(
"AutoSeededX917RNG: Continuous random number generator test failed.");
00151 m_counter = 0;
00152 m_isDifferent =
false;
00153 }
00154
00155
return b;
00156 }
00157
00158 NAMESPACE_END
00159
00160
#endif
00161
00162
#endif