xref: /netbsd-src/external/bsd/elftosb/dist/common/Random.cpp (revision 993229b6fea628ff8b1fa09146c80b0cfb2768eb)
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