1370b324cSopenharmony_ci// RandGen.cpp 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#include "StdAfx.h" 4370b324cSopenharmony_ci 5370b324cSopenharmony_ci#include "RandGen.h" 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#ifndef USE_STATIC_SYSTEM_RAND 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci#ifndef Z7_ST 10370b324cSopenharmony_ci#include "../../Windows/Synchronization.h" 11370b324cSopenharmony_ci#endif 12370b324cSopenharmony_ci 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci#ifdef _WIN32 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci#ifdef _WIN64 17370b324cSopenharmony_ci#define USE_STATIC_RtlGenRandom 18370b324cSopenharmony_ci#endif 19370b324cSopenharmony_ci 20370b324cSopenharmony_ci#ifdef USE_STATIC_RtlGenRandom 21370b324cSopenharmony_ci 22370b324cSopenharmony_ci// #include <NTSecAPI.h> 23370b324cSopenharmony_ci 24370b324cSopenharmony_ciEXTERN_C_BEGIN 25370b324cSopenharmony_ci#ifndef RtlGenRandom 26370b324cSopenharmony_ci #define RtlGenRandom SystemFunction036 27370b324cSopenharmony_ci BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); 28370b324cSopenharmony_ci#endif 29370b324cSopenharmony_ciEXTERN_C_END 30370b324cSopenharmony_ci 31370b324cSopenharmony_ci#else 32370b324cSopenharmony_ciEXTERN_C_BEGIN 33370b324cSopenharmony_citypedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength); 34370b324cSopenharmony_ciEXTERN_C_END 35370b324cSopenharmony_ci#endif 36370b324cSopenharmony_ci 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci#else 39370b324cSopenharmony_ci#include <unistd.h> 40370b324cSopenharmony_ci#include <sys/types.h> 41370b324cSopenharmony_ci#include <sys/stat.h> 42370b324cSopenharmony_ci#include <fcntl.h> 43370b324cSopenharmony_ci#define USE_POSIX_TIME 44370b324cSopenharmony_ci#define USE_POSIX_TIME2 45370b324cSopenharmony_ci#endif 46370b324cSopenharmony_ci 47370b324cSopenharmony_ci#ifdef USE_POSIX_TIME 48370b324cSopenharmony_ci#include <time.h> 49370b324cSopenharmony_ci#ifdef USE_POSIX_TIME2 50370b324cSopenharmony_ci#include <sys/time.h> 51370b324cSopenharmony_ci#endif 52370b324cSopenharmony_ci#endif 53370b324cSopenharmony_ci 54370b324cSopenharmony_ci// The seed and first generated data block depend from processID, 55370b324cSopenharmony_ci// theadID, timer and system random generator, if available. 56370b324cSopenharmony_ci// Other generated data blocks depend from previous state 57370b324cSopenharmony_ci 58370b324cSopenharmony_ci#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x)); 59370b324cSopenharmony_ci 60370b324cSopenharmony_civoid CRandomGenerator::Init() 61370b324cSopenharmony_ci{ 62370b324cSopenharmony_ci MY_ALIGN (16) 63370b324cSopenharmony_ci CSha256 hash; 64370b324cSopenharmony_ci Sha256_Init(&hash); 65370b324cSopenharmony_ci 66370b324cSopenharmony_ci unsigned numIterations = 1000; 67370b324cSopenharmony_ci 68370b324cSopenharmony_ci { 69370b324cSopenharmony_ci #ifndef UNDER_CE 70370b324cSopenharmony_ci const unsigned kNumIterations_Small = 100; 71370b324cSopenharmony_ci const unsigned kBufSize = 32; 72370b324cSopenharmony_ci MY_ALIGN (16) 73370b324cSopenharmony_ci Byte buf[kBufSize]; 74370b324cSopenharmony_ci #endif 75370b324cSopenharmony_ci 76370b324cSopenharmony_ci #ifdef _WIN32 77370b324cSopenharmony_ci 78370b324cSopenharmony_ci DWORD w = ::GetCurrentProcessId(); 79370b324cSopenharmony_ci HASH_UPD(w) 80370b324cSopenharmony_ci w = ::GetCurrentThreadId(); 81370b324cSopenharmony_ci HASH_UPD(w) 82370b324cSopenharmony_ci 83370b324cSopenharmony_ci #ifdef UNDER_CE 84370b324cSopenharmony_ci /* 85370b324cSopenharmony_ci if (CeGenRandom(kBufSize, buf)) 86370b324cSopenharmony_ci { 87370b324cSopenharmony_ci numIterations = kNumIterations_Small; 88370b324cSopenharmony_ci Sha256_Update(&hash, buf, kBufSize); 89370b324cSopenharmony_ci } 90370b324cSopenharmony_ci */ 91370b324cSopenharmony_ci #elif defined(USE_STATIC_RtlGenRandom) 92370b324cSopenharmony_ci if (RtlGenRandom(buf, kBufSize)) 93370b324cSopenharmony_ci { 94370b324cSopenharmony_ci numIterations = kNumIterations_Small; 95370b324cSopenharmony_ci Sha256_Update(&hash, buf, kBufSize); 96370b324cSopenharmony_ci } 97370b324cSopenharmony_ci #else 98370b324cSopenharmony_ci { 99370b324cSopenharmony_ci const HMODULE hModule = ::LoadLibrary(TEXT("advapi32.dll")); 100370b324cSopenharmony_ci if (hModule) 101370b324cSopenharmony_ci { 102370b324cSopenharmony_ci // SystemFunction036() is real name of RtlGenRandom() function 103370b324cSopenharmony_ci const 104370b324cSopenharmony_ci Func_RtlGenRandom 105370b324cSopenharmony_ci my_RtlGenRandom = Z7_GET_PROC_ADDRESS( 106370b324cSopenharmony_ci Func_RtlGenRandom, hModule, "SystemFunction036"); 107370b324cSopenharmony_ci if (my_RtlGenRandom) 108370b324cSopenharmony_ci { 109370b324cSopenharmony_ci if (my_RtlGenRandom(buf, kBufSize)) 110370b324cSopenharmony_ci { 111370b324cSopenharmony_ci numIterations = kNumIterations_Small; 112370b324cSopenharmony_ci Sha256_Update(&hash, buf, kBufSize); 113370b324cSopenharmony_ci } 114370b324cSopenharmony_ci } 115370b324cSopenharmony_ci ::FreeLibrary(hModule); 116370b324cSopenharmony_ci } 117370b324cSopenharmony_ci } 118370b324cSopenharmony_ci #endif 119370b324cSopenharmony_ci 120370b324cSopenharmony_ci #else 121370b324cSopenharmony_ci 122370b324cSopenharmony_ci pid_t pid = getpid(); 123370b324cSopenharmony_ci HASH_UPD(pid) 124370b324cSopenharmony_ci pid = getppid(); 125370b324cSopenharmony_ci HASH_UPD(pid) 126370b324cSopenharmony_ci 127370b324cSopenharmony_ci { 128370b324cSopenharmony_ci int f = open("/dev/urandom", O_RDONLY); 129370b324cSopenharmony_ci unsigned numBytes = kBufSize; 130370b324cSopenharmony_ci if (f >= 0) 131370b324cSopenharmony_ci { 132370b324cSopenharmony_ci do 133370b324cSopenharmony_ci { 134370b324cSopenharmony_ci ssize_t n = read(f, buf, numBytes); 135370b324cSopenharmony_ci if (n <= 0) 136370b324cSopenharmony_ci break; 137370b324cSopenharmony_ci Sha256_Update(&hash, buf, (size_t)n); 138370b324cSopenharmony_ci numBytes -= (unsigned)n; 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci while (numBytes); 141370b324cSopenharmony_ci close(f); 142370b324cSopenharmony_ci if (numBytes == 0) 143370b324cSopenharmony_ci numIterations = kNumIterations_Small; 144370b324cSopenharmony_ci } 145370b324cSopenharmony_ci } 146370b324cSopenharmony_ci /* 147370b324cSopenharmony_ci { 148370b324cSopenharmony_ci int n = getrandom(buf, kBufSize, 0); 149370b324cSopenharmony_ci if (n > 0) 150370b324cSopenharmony_ci { 151370b324cSopenharmony_ci Sha256_Update(&hash, buf, n); 152370b324cSopenharmony_ci if (n == kBufSize) 153370b324cSopenharmony_ci numIterations = kNumIterations_Small; 154370b324cSopenharmony_ci } 155370b324cSopenharmony_ci } 156370b324cSopenharmony_ci */ 157370b324cSopenharmony_ci 158370b324cSopenharmony_ci #endif 159370b324cSopenharmony_ci } 160370b324cSopenharmony_ci 161370b324cSopenharmony_ci #ifdef _DEBUG 162370b324cSopenharmony_ci numIterations = 2; 163370b324cSopenharmony_ci #endif 164370b324cSopenharmony_ci 165370b324cSopenharmony_ci do 166370b324cSopenharmony_ci { 167370b324cSopenharmony_ci #ifdef _WIN32 168370b324cSopenharmony_ci LARGE_INTEGER v; 169370b324cSopenharmony_ci if (::QueryPerformanceCounter(&v)) 170370b324cSopenharmony_ci HASH_UPD(v.QuadPart) 171370b324cSopenharmony_ci #endif 172370b324cSopenharmony_ci 173370b324cSopenharmony_ci #ifdef USE_POSIX_TIME 174370b324cSopenharmony_ci #ifdef USE_POSIX_TIME2 175370b324cSopenharmony_ci timeval v; 176370b324cSopenharmony_ci if (gettimeofday(&v, NULL) == 0) 177370b324cSopenharmony_ci { 178370b324cSopenharmony_ci HASH_UPD(v.tv_sec) 179370b324cSopenharmony_ci HASH_UPD(v.tv_usec) 180370b324cSopenharmony_ci } 181370b324cSopenharmony_ci #endif 182370b324cSopenharmony_ci const time_t v2 = time(NULL); 183370b324cSopenharmony_ci HASH_UPD(v2) 184370b324cSopenharmony_ci #endif 185370b324cSopenharmony_ci 186370b324cSopenharmony_ci #ifdef _WIN32 187370b324cSopenharmony_ci const DWORD tickCount = ::GetTickCount(); 188370b324cSopenharmony_ci HASH_UPD(tickCount) 189370b324cSopenharmony_ci #endif 190370b324cSopenharmony_ci 191370b324cSopenharmony_ci for (unsigned j = 0; j < 100; j++) 192370b324cSopenharmony_ci { 193370b324cSopenharmony_ci Sha256_Final(&hash, _buff); 194370b324cSopenharmony_ci Sha256_Init(&hash); 195370b324cSopenharmony_ci Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); 196370b324cSopenharmony_ci } 197370b324cSopenharmony_ci } 198370b324cSopenharmony_ci while (--numIterations); 199370b324cSopenharmony_ci 200370b324cSopenharmony_ci Sha256_Final(&hash, _buff); 201370b324cSopenharmony_ci _needInit = false; 202370b324cSopenharmony_ci} 203370b324cSopenharmony_ci 204370b324cSopenharmony_ci#ifndef Z7_ST 205370b324cSopenharmony_ci static NWindows::NSynchronization::CCriticalSection g_CriticalSection; 206370b324cSopenharmony_ci #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection); 207370b324cSopenharmony_ci#else 208370b324cSopenharmony_ci #define MT_LOCK 209370b324cSopenharmony_ci#endif 210370b324cSopenharmony_ci 211370b324cSopenharmony_civoid CRandomGenerator::Generate(Byte *data, unsigned size) 212370b324cSopenharmony_ci{ 213370b324cSopenharmony_ci MT_LOCK 214370b324cSopenharmony_ci 215370b324cSopenharmony_ci if (_needInit) 216370b324cSopenharmony_ci Init(); 217370b324cSopenharmony_ci while (size != 0) 218370b324cSopenharmony_ci { 219370b324cSopenharmony_ci MY_ALIGN (16) 220370b324cSopenharmony_ci CSha256 hash; 221370b324cSopenharmony_ci 222370b324cSopenharmony_ci Sha256_Init(&hash); 223370b324cSopenharmony_ci Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); 224370b324cSopenharmony_ci Sha256_Final(&hash, _buff); 225370b324cSopenharmony_ci 226370b324cSopenharmony_ci Sha256_Init(&hash); 227370b324cSopenharmony_ci UInt32 salt = 0xF672ABD1; 228370b324cSopenharmony_ci HASH_UPD(salt) 229370b324cSopenharmony_ci Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE); 230370b324cSopenharmony_ci MY_ALIGN (16) 231370b324cSopenharmony_ci Byte buff[SHA256_DIGEST_SIZE]; 232370b324cSopenharmony_ci Sha256_Final(&hash, buff); 233370b324cSopenharmony_ci for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--) 234370b324cSopenharmony_ci *data++ = buff[i]; 235370b324cSopenharmony_ci } 236370b324cSopenharmony_ci} 237370b324cSopenharmony_ci 238370b324cSopenharmony_ciMY_ALIGN (16) 239370b324cSopenharmony_ciCRandomGenerator g_RandomGenerator; 240370b324cSopenharmony_ci 241370b324cSopenharmony_ci#endif 242