зеркало из https://github.com/mozilla/gecko-dev.git
160 строки
4.5 KiB
C
160 строки
4.5 KiB
C
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "secrng.h"
|
|
|
|
#ifdef XP_WIN
|
|
#include <windows.h>
|
|
#include <time.h>
|
|
|
|
static BOOL
|
|
CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
|
|
{
|
|
LARGE_INTEGER liCount;
|
|
|
|
if (!QueryPerformanceCounter(&liCount))
|
|
return FALSE;
|
|
|
|
*lpdwHigh = liCount.u.HighPart;
|
|
*lpdwLow = liCount.u.LowPart;
|
|
return TRUE;
|
|
}
|
|
|
|
size_t RNG_GetNoise(void *buf, size_t maxbuf)
|
|
{
|
|
DWORD dwHigh, dwLow, dwVal;
|
|
int n = 0;
|
|
int nBytes;
|
|
time_t sTime;
|
|
|
|
if (maxbuf <= 0)
|
|
return 0;
|
|
|
|
CurrentClockTickTime(&dwHigh, &dwLow);
|
|
|
|
// get the maximally changing bits first
|
|
nBytes = sizeof(dwLow) > maxbuf ? maxbuf : sizeof(dwLow);
|
|
memcpy((char *)buf, &dwLow, nBytes);
|
|
n += nBytes;
|
|
maxbuf -= nBytes;
|
|
|
|
if (maxbuf <= 0)
|
|
return n;
|
|
|
|
nBytes = sizeof(dwHigh) > maxbuf ? maxbuf : sizeof(dwHigh);
|
|
memcpy(((char *)buf) + n, &dwHigh, nBytes);
|
|
n += nBytes;
|
|
maxbuf -= nBytes;
|
|
|
|
if (maxbuf <= 0)
|
|
return n;
|
|
|
|
// get the number of milliseconds that have elapsed since Windows started
|
|
dwVal = GetTickCount();
|
|
|
|
nBytes = sizeof(dwVal) > maxbuf ? maxbuf : sizeof(dwVal);
|
|
memcpy(((char *)buf) + n, &dwVal, nBytes);
|
|
n += nBytes;
|
|
maxbuf -= nBytes;
|
|
|
|
if (maxbuf <= 0)
|
|
return n;
|
|
|
|
// get the time in seconds since midnight Jan 1, 1970
|
|
time(&sTime);
|
|
nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
|
|
memcpy(((char *)buf) + n, &sTime, nBytes);
|
|
n += nBytes;
|
|
|
|
return n;
|
|
}
|
|
|
|
void RNG_SystemInfoForRNG(void)
|
|
{
|
|
DWORD dwVal;
|
|
char buffer[256];
|
|
int nBytes;
|
|
MEMORYSTATUS sMem;
|
|
HANDLE hVal;
|
|
DWORD dwSerialNum;
|
|
DWORD dwComponentLen;
|
|
DWORD dwSysFlags;
|
|
char volName[128];
|
|
DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters;
|
|
|
|
nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
|
|
RNG_RandomUpdate(buffer, nBytes);
|
|
|
|
sMem.dwLength = sizeof(sMem);
|
|
GlobalMemoryStatus(&sMem); // assorted memory stats
|
|
RNG_RandomUpdate(&sMem, sizeof(sMem));
|
|
|
|
dwVal = GetLogicalDrives();
|
|
RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25
|
|
|
|
dwVal = sizeof(buffer);
|
|
if (GetComputerName(buffer, &dwVal))
|
|
RNG_RandomUpdate(buffer, dwVal);
|
|
|
|
hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a
|
|
// constant!) of current process
|
|
RNG_RandomUpdate(&hVal, sizeof(hVal));
|
|
|
|
dwVal = GetCurrentProcessId(); // process ID (4 bytes)
|
|
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
|
|
|
|
dwVal = GetCurrentThreadId(); // thread ID (4 bytes)
|
|
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
|
|
|
|
volName[0] = '\0';
|
|
buffer[0] = '\0';
|
|
GetVolumeInformation(NULL,
|
|
volName,
|
|
sizeof(volName),
|
|
&dwSerialNum,
|
|
&dwComponentLen,
|
|
&dwSysFlags,
|
|
buffer,
|
|
sizeof(buffer));
|
|
|
|
RNG_RandomUpdate(volName, strlen(volName));
|
|
RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum));
|
|
RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen));
|
|
RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags));
|
|
RNG_RandomUpdate(buffer, strlen(buffer));
|
|
|
|
if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters,
|
|
&dwNumClusters)) {
|
|
RNG_RandomUpdate(&dwSectors, sizeof(dwSectors));
|
|
RNG_RandomUpdate(&dwBytes, sizeof(dwBytes));
|
|
RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters));
|
|
RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
|
|
}
|
|
|
|
nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
|
|
RNG_RandomUpdate(buffer, nBytes);
|
|
}
|
|
|
|
|
|
/*
|
|
* The RtlGenRandom function is declared in <ntsecapi.h>, but the
|
|
* declaration is missing a calling convention specifier. So we
|
|
* declare it manually here.
|
|
*/
|
|
#define RtlGenRandom SystemFunction036
|
|
DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom(
|
|
PVOID RandomBuffer,
|
|
ULONG RandomBufferLength);
|
|
|
|
size_t RNG_SystemRNG(void *dest, size_t maxLen)
|
|
{
|
|
size_t bytes = 0;
|
|
|
|
if (RtlGenRandom(dest, maxLen)) {
|
|
bytes = maxLen;
|
|
}
|
|
return bytes;
|
|
}
|
|
#endif /* is XP_WIN */
|