Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #include "secrng.h" |
michael@0 | 6 | |
michael@0 | 7 | #ifdef XP_WIN |
michael@0 | 8 | #include <windows.h> |
michael@0 | 9 | #include <time.h> |
michael@0 | 10 | |
michael@0 | 11 | static BOOL |
michael@0 | 12 | CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) |
michael@0 | 13 | { |
michael@0 | 14 | LARGE_INTEGER liCount; |
michael@0 | 15 | |
michael@0 | 16 | if (!QueryPerformanceCounter(&liCount)) |
michael@0 | 17 | return FALSE; |
michael@0 | 18 | |
michael@0 | 19 | *lpdwHigh = liCount.u.HighPart; |
michael@0 | 20 | *lpdwLow = liCount.u.LowPart; |
michael@0 | 21 | return TRUE; |
michael@0 | 22 | } |
michael@0 | 23 | |
michael@0 | 24 | size_t RNG_GetNoise(void *buf, size_t maxbuf) |
michael@0 | 25 | { |
michael@0 | 26 | DWORD dwHigh, dwLow, dwVal; |
michael@0 | 27 | int n = 0; |
michael@0 | 28 | int nBytes; |
michael@0 | 29 | time_t sTime; |
michael@0 | 30 | |
michael@0 | 31 | if (maxbuf <= 0) |
michael@0 | 32 | return 0; |
michael@0 | 33 | |
michael@0 | 34 | CurrentClockTickTime(&dwHigh, &dwLow); |
michael@0 | 35 | |
michael@0 | 36 | // get the maximally changing bits first |
michael@0 | 37 | nBytes = sizeof(dwLow) > maxbuf ? maxbuf : sizeof(dwLow); |
michael@0 | 38 | memcpy((char *)buf, &dwLow, nBytes); |
michael@0 | 39 | n += nBytes; |
michael@0 | 40 | maxbuf -= nBytes; |
michael@0 | 41 | |
michael@0 | 42 | if (maxbuf <= 0) |
michael@0 | 43 | return n; |
michael@0 | 44 | |
michael@0 | 45 | nBytes = sizeof(dwHigh) > maxbuf ? maxbuf : sizeof(dwHigh); |
michael@0 | 46 | memcpy(((char *)buf) + n, &dwHigh, nBytes); |
michael@0 | 47 | n += nBytes; |
michael@0 | 48 | maxbuf -= nBytes; |
michael@0 | 49 | |
michael@0 | 50 | if (maxbuf <= 0) |
michael@0 | 51 | return n; |
michael@0 | 52 | |
michael@0 | 53 | // get the number of milliseconds that have elapsed since Windows started |
michael@0 | 54 | dwVal = GetTickCount(); |
michael@0 | 55 | |
michael@0 | 56 | nBytes = sizeof(dwVal) > maxbuf ? maxbuf : sizeof(dwVal); |
michael@0 | 57 | memcpy(((char *)buf) + n, &dwVal, nBytes); |
michael@0 | 58 | n += nBytes; |
michael@0 | 59 | maxbuf -= nBytes; |
michael@0 | 60 | |
michael@0 | 61 | if (maxbuf <= 0) |
michael@0 | 62 | return n; |
michael@0 | 63 | |
michael@0 | 64 | // get the time in seconds since midnight Jan 1, 1970 |
michael@0 | 65 | time(&sTime); |
michael@0 | 66 | nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); |
michael@0 | 67 | memcpy(((char *)buf) + n, &sTime, nBytes); |
michael@0 | 68 | n += nBytes; |
michael@0 | 69 | |
michael@0 | 70 | return n; |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | void RNG_SystemInfoForRNG(void) |
michael@0 | 74 | { |
michael@0 | 75 | DWORD dwVal; |
michael@0 | 76 | char buffer[256]; |
michael@0 | 77 | int nBytes; |
michael@0 | 78 | MEMORYSTATUS sMem; |
michael@0 | 79 | HANDLE hVal; |
michael@0 | 80 | DWORD dwSerialNum; |
michael@0 | 81 | DWORD dwComponentLen; |
michael@0 | 82 | DWORD dwSysFlags; |
michael@0 | 83 | char volName[128]; |
michael@0 | 84 | DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters; |
michael@0 | 85 | |
michael@0 | 86 | nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes |
michael@0 | 87 | RNG_RandomUpdate(buffer, nBytes); |
michael@0 | 88 | |
michael@0 | 89 | sMem.dwLength = sizeof(sMem); |
michael@0 | 90 | GlobalMemoryStatus(&sMem); // assorted memory stats |
michael@0 | 91 | RNG_RandomUpdate(&sMem, sizeof(sMem)); |
michael@0 | 92 | |
michael@0 | 93 | dwVal = GetLogicalDrives(); |
michael@0 | 94 | RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25 |
michael@0 | 95 | |
michael@0 | 96 | dwVal = sizeof(buffer); |
michael@0 | 97 | if (GetComputerName(buffer, &dwVal)) |
michael@0 | 98 | RNG_RandomUpdate(buffer, dwVal); |
michael@0 | 99 | |
michael@0 | 100 | hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a |
michael@0 | 101 | // constant!) of current process |
michael@0 | 102 | RNG_RandomUpdate(&hVal, sizeof(hVal)); |
michael@0 | 103 | |
michael@0 | 104 | dwVal = GetCurrentProcessId(); // process ID (4 bytes) |
michael@0 | 105 | RNG_RandomUpdate(&dwVal, sizeof(dwVal)); |
michael@0 | 106 | |
michael@0 | 107 | dwVal = GetCurrentThreadId(); // thread ID (4 bytes) |
michael@0 | 108 | RNG_RandomUpdate(&dwVal, sizeof(dwVal)); |
michael@0 | 109 | |
michael@0 | 110 | volName[0] = '\0'; |
michael@0 | 111 | buffer[0] = '\0'; |
michael@0 | 112 | GetVolumeInformation(NULL, |
michael@0 | 113 | volName, |
michael@0 | 114 | sizeof(volName), |
michael@0 | 115 | &dwSerialNum, |
michael@0 | 116 | &dwComponentLen, |
michael@0 | 117 | &dwSysFlags, |
michael@0 | 118 | buffer, |
michael@0 | 119 | sizeof(buffer)); |
michael@0 | 120 | |
michael@0 | 121 | RNG_RandomUpdate(volName, strlen(volName)); |
michael@0 | 122 | RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum)); |
michael@0 | 123 | RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen)); |
michael@0 | 124 | RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags)); |
michael@0 | 125 | RNG_RandomUpdate(buffer, strlen(buffer)); |
michael@0 | 126 | |
michael@0 | 127 | if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters, |
michael@0 | 128 | &dwNumClusters)) { |
michael@0 | 129 | RNG_RandomUpdate(&dwSectors, sizeof(dwSectors)); |
michael@0 | 130 | RNG_RandomUpdate(&dwBytes, sizeof(dwBytes)); |
michael@0 | 131 | RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters)); |
michael@0 | 132 | RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters)); |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes |
michael@0 | 136 | RNG_RandomUpdate(buffer, nBytes); |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | |
michael@0 | 140 | /* |
michael@0 | 141 | * The RtlGenRandom function is declared in <ntsecapi.h>, but the |
michael@0 | 142 | * declaration is missing a calling convention specifier. So we |
michael@0 | 143 | * declare it manually here. |
michael@0 | 144 | */ |
michael@0 | 145 | #define RtlGenRandom SystemFunction036 |
michael@0 | 146 | DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom( |
michael@0 | 147 | PVOID RandomBuffer, |
michael@0 | 148 | ULONG RandomBufferLength); |
michael@0 | 149 | |
michael@0 | 150 | size_t RNG_SystemRNG(void *dest, size_t maxLen) |
michael@0 | 151 | { |
michael@0 | 152 | size_t bytes = 0; |
michael@0 | 153 | |
michael@0 | 154 | if (RtlGenRandom(dest, maxLen)) { |
michael@0 | 155 | bytes = maxLen; |
michael@0 | 156 | } |
michael@0 | 157 | return bytes; |
michael@0 | 158 | } |
michael@0 | 159 | #endif /* is XP_WIN */ |