tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

win_rand.c (4373B)


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