1 /*
2 * File: Random.cpp
3 *
4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5 * See included license file for license details.
6 */
7
8 #include "Random.h"
9 #include <stdexcept>
10
11 #ifdef WIN32
12 #ifndef _WIN32_WINNT
13 #define _WIN32_WINNT 0x0400
14 #endif
15 #include <windows.h>
16 #include <wincrypt.h>
17 #else // WIN32
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #endif // WIN32
22
23
24
25 #ifdef WIN32
26
MicrosoftCryptoProvider()27 MicrosoftCryptoProvider::MicrosoftCryptoProvider()
28 {
29 if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
30 {
31 throw std::runtime_error("CryptAcquireContext");
32 }
33 }
34
~MicrosoftCryptoProvider()35 MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
36 {
37 CryptReleaseContext(m_hProvider, 0);
38 }
39
40 #endif // WIN32
41
RandomNumberGenerator()42 RandomNumberGenerator::RandomNumberGenerator()
43 {
44 #ifndef WIN32
45 m_fd = open("/dev/urandom",O_RDONLY);
46 if (m_fd == -1)
47 {
48 throw std::runtime_error("open /dev/urandom");
49 }
50 #endif // WIN32
51 }
52
~RandomNumberGenerator()53 RandomNumberGenerator::~RandomNumberGenerator()
54 {
55 #ifndef WIN32
56 close(m_fd);
57 #endif // WIN32
58 }
59
generateByte()60 uint8_t RandomNumberGenerator::generateByte()
61 {
62 uint8_t result;
63 generateBlock(&result, 1);
64 return result;
65 }
66
generateBlock(uint8_t * output,unsigned count)67 void RandomNumberGenerator::generateBlock(uint8_t * output, unsigned count)
68 {
69 #ifdef WIN32
70 # ifdef WORKAROUND_MS_BUG_Q258000
71 static MicrosoftCryptoProvider m_provider;
72 # endif
73 if (!CryptGenRandom(m_provider.GetProviderHandle(), count, output))
74 {
75 throw std::runtime_error("CryptGenRandom");
76 }
77 #else // WIN32
78 if (read(m_fd, output, count) != count)
79 {
80 throw std::runtime_error("read /dev/urandom");
81 }
82 #endif // WIN32
83 }
84
85
86