1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
/* The high resolution timer API provides access to the hardware timer
18
* running at around 1.1MHz. The amount this changes in a time slice is
19
* varies randomly due to system events, hardware interrupts etc
21
static UCHAR randbyte_hrtimer()
30
byte = (t2.ulLo - t1.ulLo) & 0xFF;
31
byte ^= (t2.ulLo - t1.ulLo) >> 8;
37
/* A bunch of system information like memory & process stats.
38
* Not highly random but every bit helps....
40
static UCHAR randbyte_sysinfo()
46
DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
48
for (b = 0; b < 100; b++) {
57
/* Similar in concept to randbyte_hrtimer() but accesses the CPU's internal
58
* counters which run at the CPU's MHz speed. We get separate
59
* idle / busy / interrupt cycle counts which should provide very good
60
* randomness due to interference of hardware events.
61
* This only works on newer CPUs (at least PPro or K6) and newer OS/2 versions
62
* which is why it's run-time linked.
65
static APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1,
66
ULONG ulParm2, ULONG ulParm3) = NULL;
67
static HMODULE hDoscalls = 0;
68
#define CMD_KI_RDCNT (0x63)
70
typedef struct _CPUUTIL {
71
ULONG ulTimeLow; /* Low 32 bits of time stamp */
72
ULONG ulTimeHigh; /* High 32 bits of time stamp */
73
ULONG ulIdleLow; /* Low 32 bits of idle time */
74
ULONG ulIdleHigh; /* High 32 bits of idle time */
75
ULONG ulBusyLow; /* Low 32 bits of busy time */
76
ULONG ulBusyHigh; /* High 32 bits of busy time */
77
ULONG ulIntrLow; /* Low 32 bits of interrupt time */
78
ULONG ulIntrHigh; /* High 32 bits of interrupt time */
82
static UCHAR randbyte_perf()
89
char failed_module[20];
92
rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS",
96
rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
99
DosPerfSysCall = NULL;
104
if (DosPerfSysCall) {
105
if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
106
for (c = 0; c < sizeof(util); c++) {
107
byte ^= ((UCHAR *)&util)[c];
111
DosPerfSysCall = NULL;
120
static UCHAR randbyte()
122
return randbyte_hrtimer() ^ randbyte_sysinfo() ^ randbyte_perf();