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 #ifndef ERROR_INCORRECT_SIZE
28 # define ERROR_INCORRECT_SIZE 0x000005B6
30 #if defined(USE_MS_CRYPTOAPI)
32 #ifndef CRYPT_NEWKEYSET
33 # define CRYPT_NEWKEYSET 0x00000008
35 #ifndef CRYPT_MACHINE_KEYSET
36 # define CRYPT_MACHINE_KEYSET 0x00000020
38 #elif defined(USE_MS_CNGAPI)
40 #ifndef BCRYPT_SUCCESS
41 # define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
43 #ifndef STATUS_INVALID_PARAMETER
44 # define STATUS_INVALID_PARAMETER 0xC000000D
46 #ifndef STATUS_INVALID_HANDLE
47 # define STATUS_INVALID_HANDLE 0xC0000008
52 #ifdef CRYPTOPP_UNIX_AVAILABLE
60 #if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE)
62 :
Exception(OTHER_ERROR,
"OS_Rng: " + operation +
" operation failed with error " +
63 #ifdef CRYPTOPP_WIN32_AVAILABLE
73 #ifdef NONBLOCKING_RNG_AVAILABLE
75 #ifdef CRYPTOPP_WIN32_AVAILABLE
77 #if defined(USE_MS_CNGAPI)
78 inline DWORD NtStatusToErrorCode(NTSTATUS status)
80 if (status == STATUS_INVALID_PARAMETER)
81 return ERROR_INVALID_PARAMETER;
82 else if (status == STATUS_INVALID_HANDLE)
83 return ERROR_INVALID_HANDLE;
89 #if defined(UNICODE) || defined(_UNICODE)
90 # define CRYPTOPP_CONTAINER L"Crypto++ RNG"
92 # define CRYPTOPP_CONTAINER "Crypto++ RNG"
97 #if defined(USE_MS_CRYPTOAPI)
99 if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
101 const DWORD firstErr = GetLastError();
102 if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET ) &&
103 !CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET))
106 SetLastError(firstErr);
110 #elif defined(USE_MS_CNGAPI)
111 NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
112 if (!(BCRYPT_SUCCESS(ret)))
115 SetLastError(NtStatusToErrorCode(ret));
116 throw OS_RNG_Err(
"BCryptOpenAlgorithmProvider");
121 MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
123 #if defined(USE_MS_CRYPTOAPI)
125 CryptReleaseContext(m_hProvider, 0);
126 #elif defined(USE_MS_CNGAPI)
128 BCryptCloseAlgorithmProvider(m_hProvider, 0);
132 #endif // CRYPTOPP_WIN32_AVAILABLE
136 #ifndef CRYPTOPP_WIN32_AVAILABLE
137 m_fd = open(
"/dev/urandom",O_RDONLY);
146 NonblockingRng::~NonblockingRng()
148 #ifndef CRYPTOPP_WIN32_AVAILABLE
155 #ifdef CRYPTOPP_WIN32_AVAILABLE
157 # if defined(CRYPTOPP_CXX11_STATIC_INIT)
162 # if defined(USE_MS_CRYPTOAPI)
167 SetLastError(ERROR_INCORRECT_SIZE);
174 # elif defined(USE_MS_CNGAPI)
179 SetLastError(ERROR_INCORRECT_SIZE);
182 NTSTATUS ret = BCryptGenRandom(hProvider.
GetProviderHandle(), output, ulSize, 0);
184 if (!(BCRYPT_SUCCESS(ret)))
187 SetLastError(NtStatusToErrorCode(ret));
194 ssize_t len = read(m_fd, output, size);
198 if (errno != EINTR && errno != EAGAIN)
207 #endif // CRYPTOPP_WIN32_AVAILABLE
210 #endif // NONBLOCKING_RNG_AVAILABLE
214 #ifdef BLOCKING_RNG_AVAILABLE
216 #ifndef CRYPTOPP_BLOCKING_RNG_FILENAME
218 #define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/srandom"
220 #define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/random"
226 m_fd = open(CRYPTOPP_BLOCKING_RNG_FILENAME,O_RDONLY);
228 throw OS_RNG_Err(
"open " CRYPTOPP_BLOCKING_RNG_FILENAME);
234 BlockingRng::~BlockingRng()
245 ssize_t len = read(m_fd, output, size);
249 if (errno != EINTR && errno != EAGAIN)
250 throw OS_RNG_Err(
"read " CRYPTOPP_BLOCKING_RNG_FILENAME);
262 #endif // BLOCKING_RNG_AVAILABLE
268 #ifdef NONBLOCKING_RNG_AVAILABLE
272 #ifdef BLOCKING_RNG_AVAILABLE
278 #ifdef BLOCKING_RNG_AVAILABLE
282 #ifdef NONBLOCKING_RNG_AVAILABLE
298 #endif // OS_RNG_AVAILABLE
300 #endif // CRYPTOPP_IMPORTS