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