Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Crypto/RandGen.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Crypto/RandGen.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,107 @@ 1.4 +// RandGen.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include <stdio.h> 1.9 +#include "Windows/Synchronization.h" 1.10 +#include "RandGen.h" 1.11 + 1.12 +#ifndef _WIN32 1.13 +#include <unistd.h> 1.14 +#define USE_POSIX_TIME 1.15 +#define USE_POSIX_TIME2 1.16 +#endif 1.17 + 1.18 +#ifdef USE_POSIX_TIME 1.19 +#include <time.h> 1.20 +#ifdef USE_POSIX_TIME2 1.21 +#include <sys/time.h> 1.22 +#endif 1.23 +#endif 1.24 + 1.25 +// This is not very good random number generator. 1.26 +// Please use it only for salt. 1.27 +// First generated data block depends from timer and processID. 1.28 +// Other generated data blocks depend from previous state 1.29 +// Maybe it's possible to restore original timer value from generated value. 1.30 + 1.31 +void CRandomGenerator::Init() 1.32 +{ 1.33 + NCrypto::NSha1::CContext hash; 1.34 + hash.Init(); 1.35 + 1.36 + #ifdef _WIN32 1.37 + DWORD w = ::GetCurrentProcessId(); 1.38 + hash.Update((const Byte *)&w, sizeof(w)); 1.39 + w = ::GetCurrentThreadId(); 1.40 + hash.Update((const Byte *)&w, sizeof(w)); 1.41 + #else 1.42 + pid_t pid = getpid(); 1.43 + hash.Update((const Byte *)&pid, sizeof(pid)); 1.44 + pid = getppid(); 1.45 + hash.Update((const Byte *)&pid, sizeof(pid)); 1.46 + #endif 1.47 + 1.48 + for (int i = 0; i < 1000; i++) 1.49 + { 1.50 + #ifdef _WIN32 1.51 + LARGE_INTEGER v; 1.52 + if (::QueryPerformanceCounter(&v)) 1.53 + hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart)); 1.54 + #endif 1.55 + 1.56 + #ifdef USE_POSIX_TIME 1.57 + #ifdef USE_POSIX_TIME2 1.58 + timeval v; 1.59 + if (gettimeofday(&v, 0) == 0) 1.60 + { 1.61 + hash.Update((const Byte *)&v.tv_sec, sizeof(v.tv_sec)); 1.62 + hash.Update((const Byte *)&v.tv_usec, sizeof(v.tv_usec)); 1.63 + } 1.64 + #endif 1.65 + time_t v2 = time(NULL); 1.66 + hash.Update((const Byte *)&v2, sizeof(v2)); 1.67 + #endif 1.68 + 1.69 + DWORD tickCount = ::GetTickCount(); 1.70 + hash.Update((const Byte *)&tickCount, sizeof(tickCount)); 1.71 + 1.72 + for (int j = 0; j < 100; j++) 1.73 + { 1.74 + hash.Final(_buff); 1.75 + hash.Init(); 1.76 + hash.Update(_buff, NCrypto::NSha1::kDigestSize); 1.77 + } 1.78 + } 1.79 + hash.Final(_buff); 1.80 + _needInit = false; 1.81 +} 1.82 + 1.83 +static NWindows::NSynchronization::CCriticalSection g_CriticalSection; 1.84 + 1.85 +void CRandomGenerator::Generate(Byte *data, unsigned int size) 1.86 +{ 1.87 + g_CriticalSection.Enter(); 1.88 + if (_needInit) 1.89 + Init(); 1.90 + while (size > 0) 1.91 + { 1.92 + NCrypto::NSha1::CContext hash; 1.93 + 1.94 + hash.Init(); 1.95 + hash.Update(_buff, NCrypto::NSha1::kDigestSize); 1.96 + hash.Final(_buff); 1.97 + 1.98 + hash.Init(); 1.99 + UInt32 salt = 0xF672ABD1; 1.100 + hash.Update((const Byte *)&salt, sizeof(salt)); 1.101 + hash.Update(_buff, NCrypto::NSha1::kDigestSize); 1.102 + Byte buff[NCrypto::NSha1::kDigestSize]; 1.103 + hash.Final(buff); 1.104 + for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--) 1.105 + *data++ = buff[i]; 1.106 + } 1.107 + g_CriticalSection.Leave(); 1.108 +} 1.109 + 1.110 +CRandomGenerator g_RandomGenerator;