security/nss/lib/freebl/win_rand.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial