security/nss/lib/freebl/os2_rand.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #define INCL_DOS
     6 #define INCL_DOSERRORS
     7 #include <os2.h>
     8 #include "secrng.h"
     9 #include "prerror.h"
    10 #include <stdlib.h>
    11 #include <time.h>
    12 #include <stdio.h>
    13 #include <sys/stat.h>
    15 static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
    16 {
    17     APIRET rc = NO_ERROR;
    18     QWORD qword = {0,0};
    20     rc = DosTmrQueryTime(&qword);
    21     if (rc != NO_ERROR)
    22        return FALSE;
    24     *phigh = qword.ulHi;
    25     *plow  = qword.ulLo;
    27     return TRUE;
    28 }
    30 size_t RNG_GetNoise(void *buf, size_t maxbuf)
    31 {
    32     unsigned long high = 0;
    33     unsigned long low  = 0;
    34     clock_t val = 0;
    35     int n = 0;
    36     int nBytes = 0;
    37     time_t sTime;
    39     if (maxbuf <= 0)
    40        return 0;
    42     clockTickTime(&high, &low);
    44     /* get the maximally changing bits first */
    45     nBytes = sizeof(low) > maxbuf ? maxbuf : sizeof(low);
    46     memcpy(buf, &low, nBytes);
    47     n += nBytes;
    48     maxbuf -= nBytes;
    50     if (maxbuf <= 0)
    51        return n;
    53     nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high);
    54     memcpy(((char *)buf) + n, &high, nBytes);
    55     n += nBytes;
    56     maxbuf -= nBytes;
    58     if (maxbuf <= 0)
    59        return n;
    61     /* get the number of milliseconds that have elapsed since application started */
    62     val = clock();
    64     nBytes = sizeof(val) > maxbuf ? maxbuf : sizeof(val);
    65     memcpy(((char *)buf) + n, &val, nBytes);
    66     n += nBytes;
    67     maxbuf -= nBytes;
    69     if (maxbuf <= 0)
    70        return n;
    72     /* get the time in seconds since midnight Jan 1, 1970 */
    73     time(&sTime);
    74     nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
    75     memcpy(((char *)buf) + n, &sTime, nBytes);
    76     n += nBytes;
    78     return n;
    79 }
    81 static BOOL
    82 EnumSystemFiles(void (*func)(const char *))
    83 {
    84     APIRET              rc;
    85     ULONG               sysInfo = 0;
    86     char                bootLetter[2];
    87     char                sysDir[_MAX_PATH] = "";
    88     char                filename[_MAX_PATH];
    89     HDIR                hdir = HDIR_CREATE;
    90     ULONG               numFiles = 1;
    91     FILEFINDBUF3        fileBuf = {0};
    92     ULONG               buflen = sizeof(FILEFINDBUF3);
    94     if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo,
    95                         sizeof(ULONG)) == NO_ERROR)
    96     {
    97       bootLetter[0] = sysInfo + 'A' -1;
    98       bootLetter[1] = '\0';
    99       strcpy(sysDir, bootLetter);
   100       strcpy(sysDir+1, ":\\OS2\\");
   102       strcpy( filename, sysDir );
   103       strcat( filename, "*.*" );
   104     }
   106     rc =DosFindFirst( filename, &hdir, FILE_NORMAL, &fileBuf, buflen,
   107                       &numFiles, FIL_STANDARD );
   108     if( rc == NO_ERROR )
   109     {
   110       do {
   111         // pass the full pathname to the callback
   112         sprintf( filename, "%s%s", sysDir, fileBuf.achName );
   113         (*func)(filename);
   115         numFiles = 1;
   116         rc = DosFindNext( hdir, &fileBuf, buflen, &numFiles );
   117         if( rc != NO_ERROR && rc != ERROR_NO_MORE_FILES )
   118           printf( "DosFindNext errod code = %d\n", rc );
   119       } while ( rc == NO_ERROR );
   121       rc = DosFindClose(hdir);
   122       if( rc != NO_ERROR )
   123         printf( "DosFindClose error code = %d", rc );
   124     }
   125     else
   126       printf( "DosFindFirst error code = %d", rc );
   128     return TRUE;
   129 }
   131 static int    dwNumFiles, dwReadEvery, dwFileToRead=0;
   133 static void
   134 CountFiles(const char *file)
   135 {
   136     dwNumFiles++;
   137 }
   139 static void
   140 ReadFiles(const char *file)
   141 {
   142     if ((dwNumFiles % dwReadEvery) == 0)
   143         RNG_FileForRNG(file);
   145     dwNumFiles++;
   146 }
   148 static void 
   149 ReadSingleFile(const char *filename)
   150 {
   151     unsigned char buffer[1024];
   152     FILE *file; 
   154     file = fopen((char *)filename, "rb");
   155     if (file != NULL) {
   156 	while (fread(buffer, 1, sizeof(buffer), file) > 0) 
   157 	    ;
   158 	fclose(file);
   159     }
   160 }
   162 static void
   163 ReadOneFile(const char *file)
   164 {
   165     if (dwNumFiles == dwFileToRead) {
   166         ReadSingleFile(file);
   167     }
   169     dwNumFiles++;
   170 }
   172 static void
   173 ReadSystemFiles(void)
   174 {
   175     // first count the number of files
   176     dwNumFiles = 0;
   177     if (!EnumSystemFiles(CountFiles))
   178         return;
   180     RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
   182     // now read 10 files
   183     if (dwNumFiles == 0)
   184         return;
   186     dwReadEvery = dwNumFiles / 10;
   187     if (dwReadEvery == 0)
   188         dwReadEvery = 1;  // less than 10 files
   190     dwNumFiles = 0;
   191     EnumSystemFiles(ReadFiles);
   192 }
   194 void RNG_SystemInfoForRNG(void)
   195 {
   196    unsigned long *plong = 0;
   197    PTIB ptib;
   198    PPIB ppib;
   199    APIRET rc = NO_ERROR;
   200    DATETIME dt;
   201    COUNTRYCODE cc = {0};
   202    COUNTRYINFO ci = {0};
   203    unsigned long actual = 0;
   204    char path[_MAX_PATH]="";
   205    char fullpath[_MAX_PATH]="";
   206    unsigned long pathlength = sizeof(path);
   207    FSALLOCATE fsallocate;
   208    FILESTATUS3 fstatus;
   209    unsigned long defaultdrive = 0;
   210    unsigned long logicaldrives = 0;
   211    unsigned long sysInfo[QSV_MAX] = {0};
   212    char buffer[20];
   213    int nBytes = 0;
   215    nBytes = RNG_GetNoise(buffer, sizeof(buffer));
   216    RNG_RandomUpdate(buffer, nBytes);
   218    /* allocate memory and use address and memory */
   219    plong = (unsigned long *)malloc(sizeof(*plong));
   220    RNG_RandomUpdate(&plong, sizeof(plong));
   221    RNG_RandomUpdate(plong, sizeof(*plong));
   222    free(plong);
   224    /* process info */
   225    rc = DosGetInfoBlocks(&ptib, &ppib);
   226    if (rc == NO_ERROR)
   227    {
   228       RNG_RandomUpdate(ptib, sizeof(*ptib));
   229       RNG_RandomUpdate(ppib, sizeof(*ppib));
   230    }
   232    /* time */
   233    rc = DosGetDateTime(&dt);
   234    if (rc == NO_ERROR)
   235    {
   236       RNG_RandomUpdate(&dt, sizeof(dt));
   237    }
   239    /* country */
   240    rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual);
   241    if (rc == NO_ERROR)
   242    {
   243       RNG_RandomUpdate(&cc, sizeof(cc));
   244       RNG_RandomUpdate(&ci, sizeof(ci));
   245       RNG_RandomUpdate(&actual, sizeof(actual));
   246    }
   248    /* current directory */
   249    rc = DosQueryCurrentDir(0, path, &pathlength);
   250    strcat(fullpath, "\\");
   251    strcat(fullpath, path);
   252    if (rc == NO_ERROR)
   253    {
   254       RNG_RandomUpdate(fullpath, strlen(fullpath));
   255       // path info
   256       rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus));
   257       if (rc == NO_ERROR)
   258       {
   259          RNG_RandomUpdate(&fstatus, sizeof(fstatus));
   260       }
   261    }
   263    /* file system info */
   264    rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate));
   265    if (rc == NO_ERROR)
   266    {
   267       RNG_RandomUpdate(&fsallocate, sizeof(fsallocate));
   268    }
   270    /* drive info */
   271    rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives);
   272    if (rc == NO_ERROR)
   273    {
   274       RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive));
   275       RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives));
   276    }
   278    /* system info */
   279    rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG)*QSV_MAX);
   280    if (rc == NO_ERROR)
   281    {
   282       RNG_RandomUpdate(&sysInfo, sizeof(sysInfo));
   283    }
   285    // now let's do some files
   286    ReadSystemFiles();
   288    /* more noise */
   289    nBytes = RNG_GetNoise(buffer, sizeof(buffer));
   290    RNG_RandomUpdate(buffer, nBytes);
   291 }
   293 void RNG_FileForRNG(const char *filename)
   294 {
   295     struct stat stat_buf;
   296     unsigned char buffer[1024];
   297     FILE *file = 0;
   298     int nBytes = 0;
   299     static int totalFileBytes = 0;
   301     if (stat((char *)filename, &stat_buf) < 0)
   302        return;
   304     RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf));
   306     file = fopen((char *)filename, "r");
   307     if (file != NULL)
   308     {
   309        for (;;)
   310        {
   311            size_t bytes = fread(buffer, 1, sizeof(buffer), file);
   313            if (bytes == 0)
   314               break;
   316            RNG_RandomUpdate(buffer, bytes);
   317            totalFileBytes += bytes;
   318            if (totalFileBytes > 250000)
   319               break;
   320        }
   321        fclose(file);
   322     }
   324     nBytes = RNG_GetNoise(buffer, 20); 
   325     RNG_RandomUpdate(buffer, nBytes);
   326 }
   328 static void rng_systemJitter(void)
   329 {
   330     dwNumFiles = 0;
   331     EnumSystemFiles(ReadOneFile);
   332     dwFileToRead++;
   333     if (dwFileToRead >= dwNumFiles) {
   334 	dwFileToRead = 0;
   335     }
   336 }
   338 size_t RNG_SystemRNG(void *dest, size_t maxLen)
   339 {
   340     return rng_systemFromNoise(dest,maxLen);
   341 }

mercurial