8 #ifndef CRYPTOPP_IMPORTS
15 #if defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(OS_RNG_AVAILABLE)
16 # pragma message("WARNING: Compiling for Windows but an OS RNG is not available. This is likely a Windows Phone 8 or Windows Store 8 app.")
19 #if !defined(NO_OS_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
24 #ifdef CRYPTOPP_WIN32_AVAILABLE
25 #define WIN32_LEAN_AND_MEAN
27 #if defined(USE_MS_CRYPTOAPI)
29 #ifndef CRYPT_NEWKEYSET
30 # define CRYPT_NEWKEYSET 0x00000008
32 #ifndef CRYPT_MACHINE_KEYSET
33 # define CRYPT_MACHINE_KEYSET 0x00000020
35 #elif defined(USE_MS_CNGAPI)
37 #ifndef BCRYPT_SUCCESS
38 # define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
40 #ifndef STATUS_INVALID_PARAMETER
41 # define STATUS_INVALID_PARAMETER 0xC000000D
43 #ifndef STATUS_INVALID_HANDLE
44 # define STATUS_INVALID_HANDLE 0xC0000008
49 #ifdef CRYPTOPP_UNIX_AVAILABLE
57 #if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE)
59 :
Exception(OTHER_ERROR,
"OS_Rng: " + operation +
" operation failed with error " +
60 #ifdef CRYPTOPP_WIN32_AVAILABLE
70 #ifdef NONBLOCKING_RNG_AVAILABLE
72 #ifdef CRYPTOPP_WIN32_AVAILABLE
74 #if defined(USE_MS_CNGAPI)
75 inline DWORD NtStatusToErrorCode(NTSTATUS status)
77 if (status == STATUS_INVALID_PARAMETER)
78 return ERROR_INVALID_PARAMETER;
79 else if (status == STATUS_INVALID_HANDLE)
80 return ERROR_INVALID_HANDLE;
86 #if defined(UNICODE) || defined(_UNICODE)
87 # define CRYPTOPP_CONTAINER L"Crypto++ RNG"
89 # define CRYPTOPP_CONTAINER "Crypto++ RNG"
94 #if defined(USE_MS_CRYPTOAPI)
96 if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
98 const DWORD firstErr = GetLastError();
99 if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET ) &&
100 !CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET))
103 SetLastError(firstErr);
107 #elif defined(USE_MS_CNGAPI)
108 NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
109 if (!(BCRYPT_SUCCESS(ret)))
112 SetLastError(NtStatusToErrorCode(ret));
113 throw OS_RNG_Err(
"BCryptOpenAlgorithmProvider");
118 MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
120 #if defined(USE_MS_CRYPTOAPI)
122 CryptReleaseContext(m_hProvider, 0);
123 #elif defined(USE_MS_CNGAPI)
125 BCryptCloseAlgorithmProvider(m_hProvider, 0);
129 #endif // CRYPTOPP_WIN32_AVAILABLE
133 #ifndef CRYPTOPP_WIN32_AVAILABLE
134 m_fd = open(
"/dev/urandom",O_RDONLY);
140 NonblockingRng::~NonblockingRng()
142 #ifndef CRYPTOPP_WIN32_AVAILABLE
149 #ifdef CRYPTOPP_WIN32_AVAILABLE
152 # if defined(USE_MS_CRYPTOAPI)
155 # elif defined(USE_MS_CNGAPI)
156 NTSTATUS ret = BCryptGenRandom(hProvider.
GetProviderHandle(), output, (ULONG)size, 0);
157 if (!(BCRYPT_SUCCESS(ret)))
160 SetLastError(NtStatusToErrorCode(ret));
167 ssize_t len = read(m_fd, output, size);
171 if (errno != EINTR && errno != EAGAIN)
180 #endif // CRYPTOPP_WIN32_AVAILABLE
183 #endif // NONBLOCKING_RNG_AVAILABLE
187 #ifdef BLOCKING_RNG_AVAILABLE
189 #ifndef CRYPTOPP_BLOCKING_RNG_FILENAME
191 #define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/srandom"
193 #define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/random"
199 m_fd = open(CRYPTOPP_BLOCKING_RNG_FILENAME,O_RDONLY);
201 throw OS_RNG_Err(
"open " CRYPTOPP_BLOCKING_RNG_FILENAME);
204 BlockingRng::~BlockingRng()
215 ssize_t len = read(m_fd, output, size);
219 if (errno != EINTR && errno != EAGAIN)
220 throw OS_RNG_Err(
"read " CRYPTOPP_BLOCKING_RNG_FILENAME);
232 #endif // BLOCKING_RNG_AVAILABLE
238 #ifdef NONBLOCKING_RNG_AVAILABLE
242 #ifdef BLOCKING_RNG_AVAILABLE
248 #ifdef BLOCKING_RNG_AVAILABLE
252 #ifdef NONBLOCKING_RNG_AVAILABLE
268 #endif // OS_RNG_AVAILABLE
270 #endif // CRYPTOPP_IMPORTS