/mordor/streams/random.cpp
C++ | 51 lines | 44 code | 7 blank | 0 comment | 10 complexity | 7b62db54f2c0018e8bc0d118c654413e MD5 | raw file
Possible License(s): BSD-3-Clause
1#include "random.h" 2 3#ifndef WINDOWS 4#include <openssl/rand.h> 5#include "ssl.h" 6#endif 7 8#include "mordor/endian.h" 9#include "mordor/exception.h" 10 11namespace Mordor { 12 13RandomStream::RandomStream() 14{ 15#ifdef WINDOWS 16 BOOL ret = ::CryptAcquireContext(&m_hCP, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 17 if(!ret || !m_hCP) { 18 if(lastError() == NTE_BAD_KEYSET) { 19 ret = ::CryptAcquireContext(&m_hCP, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT); 20 if(!ret || !m_hCP) { 21 MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptAcquireContext"); 22 } 23 } else { 24 MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptAcquireContext"); 25 } 26 } 27#endif 28} 29 30RandomStream::~RandomStream() 31{ 32#ifdef WINDOWS 33 ::CryptReleaseContext(m_hCP, 0); 34#endif 35} 36 37size_t RandomStream::read(void *buffer, size_t length) 38{ 39#ifdef WINDOWS 40 if (length >= 0xffffffffu) 41 length = 0xffffffffu; 42 if (!::CryptGenRandom(m_hCP, static_cast<DWORD>(length), static_cast<BYTE *>(buffer))) 43 MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptGenRandom"); 44#else 45 if (!RAND_bytes(static_cast<unsigned char *>(buffer), length)) 46 MORDOR_THROW_EXCEPTION(OpenSSLException()); 47#endif 48 return length; 49} 50 51}