monotone

monotone Mtn Source Tree

Root/cryptopp/osrng.cpp

1// osrng.cpp - written and placed in the public domain by Wei Dai
2
3// Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool.
4
5#include "pch.h"
6#include "osrng.h"
7
8#ifdef OS_RNG_AVAILABLE
9
10#include "rng.h"
11
12#ifdef CRYPTOPP_WIN32_AVAILABLE
13#ifndef _WIN32_WINNT
14#define _WIN32_WINNT 0x0400
15#endif
16#include <windows.h>
17#include <wincrypt.h>
18#endif
19
20#ifdef CRYPTOPP_UNIX_AVAILABLE
21#include <errno.h>
22#include <fcntl.h>
23#include <unistd.h>
24#endif
25
26NAMESPACE_BEGIN(CryptoPP)
27
28#if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE)
29OS_RNG_Err::OS_RNG_Err(const std::string &operation)
30: Exception(OTHER_ERROR, "OS_Rng: " + operation + " operation failed with error " +
31#ifdef CRYPTOPP_WIN32_AVAILABLE
32"0x" + IntToString(GetLastError(), 16)
33#else
34IntToString(errno)
35#endif
36)
37{
38}
39#endif
40
41#ifdef NONBLOCKING_RNG_AVAILABLE
42
43#ifdef CRYPTOPP_WIN32_AVAILABLE
44
45MicrosoftCryptoProvider::MicrosoftCryptoProvider()
46{
47if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
48throw OS_RNG_Err("CryptAcquireContext");
49}
50
51MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
52{
53CryptReleaseContext(m_hProvider, 0);
54}
55
56#endif
57
58NonblockingRng::NonblockingRng()
59{
60#ifndef CRYPTOPP_WIN32_AVAILABLE
61m_fd = open("/dev/urandom",O_RDONLY);
62if (m_fd == -1)
63throw OS_RNG_Err("open /dev/urandom");
64#endif
65}
66
67NonblockingRng::~NonblockingRng()
68{
69#ifndef CRYPTOPP_WIN32_AVAILABLE
70close(m_fd);
71#endif
72}
73
74byte NonblockingRng::GenerateByte()
75{
76byte b;
77GenerateBlock(&b, 1);
78return b;
79}
80
81void NonblockingRng::GenerateBlock(byte *output, unsigned int size)
82{
83 int n = 0;
84#ifdef CRYPTOPP_WIN32_AVAILABLE
85#ifdef WORKAROUND_MS_BUG_Q258000
86static MicrosoftCryptoProvider m_Provider;
87#endif
88if (!CryptGenRandom(m_Provider.GetProviderHandle(), size, output))
89throw OS_RNG_Err("CryptGenRandom");
90#else
91while (true)
92 {
93 n = read(m_fd, output, size);
94 if (n == -1)
95 throw OS_RNG_Err("read /dev/urandom");
96 size -= n;
97 output += n;
98 if (size <= 0)
99 break;
100 }
101#endif
102}
103
104#endif
105
106// *************************************************************
107
108#ifdef BLOCKING_RNG_AVAILABLE
109
110BlockingRng::BlockingRng()
111{
112m_fd = open("/dev/random",O_RDONLY);
113if (m_fd == -1)
114throw OS_RNG_Err("open /dev/random");
115}
116
117BlockingRng::~BlockingRng()
118{
119close(m_fd);
120}
121
122byte BlockingRng::GenerateByte()
123{
124byte b;
125GenerateBlock(&b, 1);
126return b;
127}
128
129void BlockingRng::GenerateBlock(byte *output, unsigned int size)
130{
131while (size)
132{
133// on some systems /dev/random will block until all bytes
134// are available, on others it will returns immediately
135int len = read(m_fd, output, STDMIN(size, (unsigned int)INT_MAX));
136if (len == -1)
137throw OS_RNG_Err("read /dev/random");
138size -= len;
139output += len;
140if (size)
141sleep(1);
142}
143}
144
145#endif
146
147// *************************************************************
148
149void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size)
150{
151#ifdef NONBLOCKING_RNG_AVAILABLE
152if (blocking)
153#endif
154{
155#ifdef BLOCKING_RNG_AVAILABLE
156BlockingRng rng;
157rng.GenerateBlock(output, size);
158#endif
159}
160
161#ifdef BLOCKING_RNG_AVAILABLE
162if (!blocking)
163#endif
164{
165#ifdef NONBLOCKING_RNG_AVAILABLE
166NonblockingRng rng;
167rng.GenerateBlock(output, size);
168#endif
169}
170}
171
172void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize)
173{
174SecByteBlock seed(seedSize);
175OS_GenerateRandomBlock(blocking, seed, seedSize);
176Put(seed, seedSize);
177}
178
179NAMESPACE_END
180
181#endif

Archive Download this file

Branches

Tags

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