1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/freebl/win_rand.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "secrng.h" 1.9 + 1.10 +#ifdef XP_WIN 1.11 +#include <windows.h> 1.12 +#include <time.h> 1.13 + 1.14 +static BOOL 1.15 +CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) 1.16 +{ 1.17 + LARGE_INTEGER liCount; 1.18 + 1.19 + if (!QueryPerformanceCounter(&liCount)) 1.20 + return FALSE; 1.21 + 1.22 + *lpdwHigh = liCount.u.HighPart; 1.23 + *lpdwLow = liCount.u.LowPart; 1.24 + return TRUE; 1.25 +} 1.26 + 1.27 +size_t RNG_GetNoise(void *buf, size_t maxbuf) 1.28 +{ 1.29 + DWORD dwHigh, dwLow, dwVal; 1.30 + int n = 0; 1.31 + int nBytes; 1.32 + time_t sTime; 1.33 + 1.34 + if (maxbuf <= 0) 1.35 + return 0; 1.36 + 1.37 + CurrentClockTickTime(&dwHigh, &dwLow); 1.38 + 1.39 + // get the maximally changing bits first 1.40 + nBytes = sizeof(dwLow) > maxbuf ? maxbuf : sizeof(dwLow); 1.41 + memcpy((char *)buf, &dwLow, nBytes); 1.42 + n += nBytes; 1.43 + maxbuf -= nBytes; 1.44 + 1.45 + if (maxbuf <= 0) 1.46 + return n; 1.47 + 1.48 + nBytes = sizeof(dwHigh) > maxbuf ? maxbuf : sizeof(dwHigh); 1.49 + memcpy(((char *)buf) + n, &dwHigh, nBytes); 1.50 + n += nBytes; 1.51 + maxbuf -= nBytes; 1.52 + 1.53 + if (maxbuf <= 0) 1.54 + return n; 1.55 + 1.56 + // get the number of milliseconds that have elapsed since Windows started 1.57 + dwVal = GetTickCount(); 1.58 + 1.59 + nBytes = sizeof(dwVal) > maxbuf ? maxbuf : sizeof(dwVal); 1.60 + memcpy(((char *)buf) + n, &dwVal, nBytes); 1.61 + n += nBytes; 1.62 + maxbuf -= nBytes; 1.63 + 1.64 + if (maxbuf <= 0) 1.65 + return n; 1.66 + 1.67 + // get the time in seconds since midnight Jan 1, 1970 1.68 + time(&sTime); 1.69 + nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); 1.70 + memcpy(((char *)buf) + n, &sTime, nBytes); 1.71 + n += nBytes; 1.72 + 1.73 + return n; 1.74 +} 1.75 + 1.76 +void RNG_SystemInfoForRNG(void) 1.77 +{ 1.78 + DWORD dwVal; 1.79 + char buffer[256]; 1.80 + int nBytes; 1.81 + MEMORYSTATUS sMem; 1.82 + HANDLE hVal; 1.83 + DWORD dwSerialNum; 1.84 + DWORD dwComponentLen; 1.85 + DWORD dwSysFlags; 1.86 + char volName[128]; 1.87 + DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters; 1.88 + 1.89 + nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes 1.90 + RNG_RandomUpdate(buffer, nBytes); 1.91 + 1.92 + sMem.dwLength = sizeof(sMem); 1.93 + GlobalMemoryStatus(&sMem); // assorted memory stats 1.94 + RNG_RandomUpdate(&sMem, sizeof(sMem)); 1.95 + 1.96 + dwVal = GetLogicalDrives(); 1.97 + RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25 1.98 + 1.99 + dwVal = sizeof(buffer); 1.100 + if (GetComputerName(buffer, &dwVal)) 1.101 + RNG_RandomUpdate(buffer, dwVal); 1.102 + 1.103 + hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a 1.104 + // constant!) of current process 1.105 + RNG_RandomUpdate(&hVal, sizeof(hVal)); 1.106 + 1.107 + dwVal = GetCurrentProcessId(); // process ID (4 bytes) 1.108 + RNG_RandomUpdate(&dwVal, sizeof(dwVal)); 1.109 + 1.110 + dwVal = GetCurrentThreadId(); // thread ID (4 bytes) 1.111 + RNG_RandomUpdate(&dwVal, sizeof(dwVal)); 1.112 + 1.113 + volName[0] = '\0'; 1.114 + buffer[0] = '\0'; 1.115 + GetVolumeInformation(NULL, 1.116 + volName, 1.117 + sizeof(volName), 1.118 + &dwSerialNum, 1.119 + &dwComponentLen, 1.120 + &dwSysFlags, 1.121 + buffer, 1.122 + sizeof(buffer)); 1.123 + 1.124 + RNG_RandomUpdate(volName, strlen(volName)); 1.125 + RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum)); 1.126 + RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen)); 1.127 + RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags)); 1.128 + RNG_RandomUpdate(buffer, strlen(buffer)); 1.129 + 1.130 + if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters, 1.131 + &dwNumClusters)) { 1.132 + RNG_RandomUpdate(&dwSectors, sizeof(dwSectors)); 1.133 + RNG_RandomUpdate(&dwBytes, sizeof(dwBytes)); 1.134 + RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters)); 1.135 + RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters)); 1.136 + } 1.137 + 1.138 + nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes 1.139 + RNG_RandomUpdate(buffer, nBytes); 1.140 +} 1.141 + 1.142 + 1.143 +/* 1.144 + * The RtlGenRandom function is declared in <ntsecapi.h>, but the 1.145 + * declaration is missing a calling convention specifier. So we 1.146 + * declare it manually here. 1.147 + */ 1.148 +#define RtlGenRandom SystemFunction036 1.149 +DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom( 1.150 + PVOID RandomBuffer, 1.151 + ULONG RandomBufferLength); 1.152 + 1.153 +size_t RNG_SystemRNG(void *dest, size_t maxLen) 1.154 +{ 1.155 + size_t bytes = 0; 1.156 + 1.157 + if (RtlGenRandom(dest, maxLen)) { 1.158 + bytes = maxLen; 1.159 + } 1.160 + return bytes; 1.161 +} 1.162 +#endif /* is XP_WIN */