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