Wed, 31 Dec 2014 06:09:35 +0100
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 }