monotone

monotone Mtn Source Tree

Root/cryptopp/osrng.h

1#ifndef CRYPTOPP_OSRNG_H
2#define CRYPTOPP_OSRNG_H
3
4#include "config.h"
5
6#ifdef OS_RNG_AVAILABLE
7
8#include "randpool.h"
9#include "rng.h"
10
11NAMESPACE_BEGIN(CryptoPP)
12
13//! Exception class for Operating-System Random Number Generator.
14class OS_RNG_Err : public Exception
15{
16public:
17OS_RNG_Err(const std::string &operation);
18};
19
20#ifdef NONBLOCKING_RNG_AVAILABLE
21
22#ifdef CRYPTOPP_WIN32_AVAILABLE
23class MicrosoftCryptoProvider
24{
25public:
26MicrosoftCryptoProvider();
27~MicrosoftCryptoProvider();
28#if defined(_WIN64)
29typedef unsigned __int64 ProviderHandle;// type HCRYPTPROV, avoid #include <windows.h>
30#else
31typedef unsigned long ProviderHandle;
32#endif
33ProviderHandle GetProviderHandle() const {return m_hProvider;}
34private:
35ProviderHandle m_hProvider;
36};
37#endif
38
39//! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
40class NonblockingRng : public RandomNumberGenerator
41{
42public:
43NonblockingRng();
44~NonblockingRng();
45byte GenerateByte();
46void GenerateBlock(byte *output, unsigned int size);
47
48protected:
49#ifdef CRYPTOPP_WIN32_AVAILABLE
50#ifndef WORKAROUND_MS_BUG_Q258000
51MicrosoftCryptoProvider m_Provider;
52#endif
53#else
54int m_fd;
55#endif
56};
57
58#endif
59
60#ifdef BLOCKING_RNG_AVAILABLE
61
62//! encapsulate /dev/random
63class BlockingRng : public RandomNumberGenerator
64{
65public:
66BlockingRng();
67~BlockingRng();
68byte GenerateByte();
69void GenerateBlock(byte *output, unsigned int size);
70
71protected:
72int m_fd;
73};
74
75#endif
76
77void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
78
79//! Automaticly Seeded Randomness Pool
80/*! This class seeds itself using an operating system provided RNG. */
81class AutoSeededRandomPool : public RandomPool
82{
83public:
84//! blocking will be ignored if the prefered RNG isn't available
85explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
86{Reseed(blocking, seedSize);}
87void Reseed(bool blocking = false, unsigned int seedSize = 32);
88};
89
90//! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
91template <class BLOCK_CIPHER>
92class AutoSeededX917RNG : public RandomNumberGenerator
93{
94public:
95//! blocking will be ignored if the prefered RNG isn't available
96explicit AutoSeededX917RNG(bool blocking = false)
97{Reseed(blocking);}
98void Reseed(bool blocking = false);
99// exposed for testing
100void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector);
101
102byte GenerateByte();
103
104private:
105member_ptr<RandomNumberGenerator> m_rng;
106SecByteBlock m_lastBlock;
107bool m_isDifferent;
108unsigned int m_counter;
109};
110
111template <class BLOCK_CIPHER>
112void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector)
113{
114m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
115
116// for FIPS 140-2
117m_lastBlock.resize(16);
118m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
119m_counter = 0;
120m_isDifferent = false;
121}
122
123template <class BLOCK_CIPHER>
124void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
125{
126SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
127const byte *key;
128do
129{
130OS_GenerateRandomBlock(blocking, seed, seed.size());
131key = seed + BLOCK_CIPHER::BLOCKSIZE;
132}// check that seed and key don't have same value
133while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
134
135Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0);
136}
137
138template <class BLOCK_CIPHER>
139byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
140{
141byte b = m_rng->GenerateByte();
142
143// for FIPS 140-2
144m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
145m_lastBlock[m_counter] = b;
146++m_counter;
147if (m_counter == m_lastBlock.size())
148{
149if (!m_isDifferent)
150throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
151m_counter = 0;
152m_isDifferent = false;
153}
154
155return b;
156}
157
158NAMESPACE_END
159
160#endif
161
162#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status