Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

osrng.cpp

00001 // osrng.cpp - written and placed in the public domain by Wei Dai
00002 
00003 // Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool.
00004 
00005 #include "pch.h"
00006 #include "osrng.h"
00007 
00008 #if (defined(_WIN32) && defined(USE_MS_CRYPTOAPI))
00009 #ifndef _WIN32_WINNT
00010 #define _WIN32_WINNT 0x0400
00011 #endif
00012 #include <windows.h>
00013 #include <wincrypt.h>
00014 #elif defined(__FreeBSD__) || defined(__linux__)
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017 #endif
00018 
00019 NAMESPACE_BEGIN(CryptoPP)
00020 
00021 #ifdef NONBLOCKING_RNG_AVAILABLE
00022 
00023 NonblockingRng::NonblockingRng()
00024 {
00025 #ifdef _WIN32
00026         if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
00027                 throw OS_RNG_Err("NonblockingRng: CryptAcquireContext failed");
00028 #else
00029         m_fd = open("/dev/urandom",O_RDONLY);
00030         if (m_fd == -1)
00031                 throw OS_RNG_Err("NonblockingRng: could not open /dev/urandom");
00032 #endif
00033 }
00034 
00035 NonblockingRng::~NonblockingRng()
00036 {
00037 #ifdef _WIN32
00038         CryptReleaseContext(m_hProvider, 0);
00039 #else
00040         close(m_fd);
00041 #endif
00042 }
00043 
00044 byte NonblockingRng::GenerateByte()
00045 {
00046         byte b;
00047         GenerateBlock(&b, 1);
00048         return b;
00049 }
00050 
00051 void NonblockingRng::GenerateBlock(byte *output, unsigned int size)
00052 {
00053 #ifdef _WIN32
00054         if (!CryptGenRandom(m_hProvider, size, output))
00055                 throw OS_RNG_Err("NonblockingRng: CryptGenRandom failed");
00056 #else
00057         if (read(m_fd, output, size) != size)
00058                 throw OS_RNG_Err("NonblockingRng: error reading from /dev/urandom");
00059 #endif
00060 }
00061 
00062 #endif
00063 
00064 // *************************************************************
00065 
00066 #ifdef BLOCKING_RNG_AVAILABLE
00067 
00068 BlockingRng::BlockingRng()
00069 {
00070         m_fd = open("/dev/random",O_RDONLY);
00071         if (m_fd == -1)
00072                 throw OS_RNG_Err("BlockingRng: could not open /dev/random");
00073 }
00074 
00075 BlockingRng::~BlockingRng()
00076 {
00077         close(m_fd);
00078 }
00079 
00080 byte BlockingRng::GenerateByte()
00081 {
00082         byte b;
00083         GenerateBlock(&b, 1);
00084         return b;
00085 }
00086 
00087 void BlockingRng::GenerateBlock(byte *output, unsigned int size)
00088 {
00089         while (size)
00090         {
00091                 // on some systems /dev/random will block until all bytes
00092                 // are available, on others it will returns immediately
00093                 int len = read(m_fd, output, STDMIN(size, (unsigned int)INT_MAX));
00094                 if (len == -1)
00095                         throw OS_RNG_Err("BlockingRng: error reading from /dev/random");
00096                 size -= len;
00097                 output += len;
00098                 if (size)
00099                         sleep(1);
00100         }
00101 }
00102 
00103 #endif
00104 
00105 // *************************************************************
00106 
00107 #ifdef AUTO_SEEDED_RANDOM_POOL_AVAILABLE
00108 
00109 void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize)
00110 {
00111 #ifdef NONBLOCKING_RNG_AVAILABLE
00112         if (blocking)
00113 #endif
00114         {
00115 #ifdef BLOCKING_RNG_AVAILABLE
00116                 BlockingRng rng;
00117                 SecByteBlock seed(seedSize);
00118                 rng.GenerateBlock(seed, seedSize);
00119                 Put(seed, seedSize);
00120 #endif
00121         }
00122 
00123 #ifdef BLOCKING_RNG_AVAILABLE
00124         if (!blocking)
00125 #endif
00126         {
00127 #ifdef NONBLOCKING_RNG_AVAILABLE
00128                 NonblockingRng rng;
00129                 SecByteBlock seed(seedSize);
00130                 rng.GenerateBlock(seed, seedSize);
00131                 Put(seed, seedSize);
00132 #endif
00133         }
00134 }
00135 
00136 #endif
00137 
00138 NAMESPACE_END

Generated at Mon Jan 15 01:16:34 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000