annotate 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
rev   line source
rlm@1 1 // RandGen.cpp
rlm@1 2
rlm@1 3 #include "StdAfx.h"
rlm@1 4
rlm@1 5 #include <stdio.h>
rlm@1 6 #include "Windows/Synchronization.h"
rlm@1 7 #include "RandGen.h"
rlm@1 8
rlm@1 9 #ifndef _WIN32
rlm@1 10 #include <unistd.h>
rlm@1 11 #define USE_POSIX_TIME
rlm@1 12 #define USE_POSIX_TIME2
rlm@1 13 #endif
rlm@1 14
rlm@1 15 #ifdef USE_POSIX_TIME
rlm@1 16 #include <time.h>
rlm@1 17 #ifdef USE_POSIX_TIME2
rlm@1 18 #include <sys/time.h>
rlm@1 19 #endif
rlm@1 20 #endif
rlm@1 21
rlm@1 22 // This is not very good random number generator.
rlm@1 23 // Please use it only for salt.
rlm@1 24 // First generated data block depends from timer and processID.
rlm@1 25 // Other generated data blocks depend from previous state
rlm@1 26 // Maybe it's possible to restore original timer value from generated value.
rlm@1 27
rlm@1 28 void CRandomGenerator::Init()
rlm@1 29 {
rlm@1 30 NCrypto::NSha1::CContext hash;
rlm@1 31 hash.Init();
rlm@1 32
rlm@1 33 #ifdef _WIN32
rlm@1 34 DWORD w = ::GetCurrentProcessId();
rlm@1 35 hash.Update((const Byte *)&w, sizeof(w));
rlm@1 36 w = ::GetCurrentThreadId();
rlm@1 37 hash.Update((const Byte *)&w, sizeof(w));
rlm@1 38 #else
rlm@1 39 pid_t pid = getpid();
rlm@1 40 hash.Update((const Byte *)&pid, sizeof(pid));
rlm@1 41 pid = getppid();
rlm@1 42 hash.Update((const Byte *)&pid, sizeof(pid));
rlm@1 43 #endif
rlm@1 44
rlm@1 45 for (int i = 0; i < 1000; i++)
rlm@1 46 {
rlm@1 47 #ifdef _WIN32
rlm@1 48 LARGE_INTEGER v;
rlm@1 49 if (::QueryPerformanceCounter(&v))
rlm@1 50 hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart));
rlm@1 51 #endif
rlm@1 52
rlm@1 53 #ifdef USE_POSIX_TIME
rlm@1 54 #ifdef USE_POSIX_TIME2
rlm@1 55 timeval v;
rlm@1 56 if (gettimeofday(&v, 0) == 0)
rlm@1 57 {
rlm@1 58 hash.Update((const Byte *)&v.tv_sec, sizeof(v.tv_sec));
rlm@1 59 hash.Update((const Byte *)&v.tv_usec, sizeof(v.tv_usec));
rlm@1 60 }
rlm@1 61 #endif
rlm@1 62 time_t v2 = time(NULL);
rlm@1 63 hash.Update((const Byte *)&v2, sizeof(v2));
rlm@1 64 #endif
rlm@1 65
rlm@1 66 DWORD tickCount = ::GetTickCount();
rlm@1 67 hash.Update((const Byte *)&tickCount, sizeof(tickCount));
rlm@1 68
rlm@1 69 for (int j = 0; j < 100; j++)
rlm@1 70 {
rlm@1 71 hash.Final(_buff);
rlm@1 72 hash.Init();
rlm@1 73 hash.Update(_buff, NCrypto::NSha1::kDigestSize);
rlm@1 74 }
rlm@1 75 }
rlm@1 76 hash.Final(_buff);
rlm@1 77 _needInit = false;
rlm@1 78 }
rlm@1 79
rlm@1 80 static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
rlm@1 81
rlm@1 82 void CRandomGenerator::Generate(Byte *data, unsigned int size)
rlm@1 83 {
rlm@1 84 g_CriticalSection.Enter();
rlm@1 85 if (_needInit)
rlm@1 86 Init();
rlm@1 87 while (size > 0)
rlm@1 88 {
rlm@1 89 NCrypto::NSha1::CContext hash;
rlm@1 90
rlm@1 91 hash.Init();
rlm@1 92 hash.Update(_buff, NCrypto::NSha1::kDigestSize);
rlm@1 93 hash.Final(_buff);
rlm@1 94
rlm@1 95 hash.Init();
rlm@1 96 UInt32 salt = 0xF672ABD1;
rlm@1 97 hash.Update((const Byte *)&salt, sizeof(salt));
rlm@1 98 hash.Update(_buff, NCrypto::NSha1::kDigestSize);
rlm@1 99 Byte buff[NCrypto::NSha1::kDigestSize];
rlm@1 100 hash.Final(buff);
rlm@1 101 for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--)
rlm@1 102 *data++ = buff[i];
rlm@1 103 }
rlm@1 104 g_CriticalSection.Leave();
rlm@1 105 }
rlm@1 106
rlm@1 107 CRandomGenerator g_RandomGenerator;