diff options
author | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2004-03-14 03:01:08 +0000 |
---|---|---|
committer | bjh <bjh@13f79535-47bb-0310-9956-ffa450edef68> | 2004-03-14 03:01:08 +0000 |
commit | 5b507a910413e784e51222a5c37d8906e7ecf2a5 (patch) | |
tree | c030018f5f3908b50846efdc3ec45f311cd381b0 /misc/unix | |
parent | 44a69f2dcf6d14b35a1658605026b2d3b9c05d35 (diff) | |
download | libapr-5b507a910413e784e51222a5c37d8906e7ecf2a5.tar.gz |
Reorganise the OS/2 random byte generation code to work with the new build scheme.
This is needed so buildconf uses misc/unix for OS/2.
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64985 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'misc/unix')
-rw-r--r-- | misc/unix/rand.c | 2 | ||||
-rw-r--r-- | misc/unix/randbyte_os2.inc | 122 |
2 files changed, 123 insertions, 1 deletions
diff --git a/misc/unix/rand.c b/misc/unix/rand.c index d29c5581d..894022f6d 100644 --- a/misc/unix/rand.c +++ b/misc/unix/rand.c @@ -198,7 +198,7 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf, #undef XSTR #ifdef OS2 -#include "../os2/randbyte.c" +#include "randbyte_os2.inc" #endif #endif /* APR_HAS_RANDOM */ diff --git a/misc/unix/randbyte_os2.inc b/misc/unix/randbyte_os2.inc new file mode 100644 index 000000000..e5c9bcb45 --- /dev/null +++ b/misc/unix/randbyte_os2.inc @@ -0,0 +1,122 @@ +/* Copyright 2000-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* The high resolution timer API provides access to the hardware timer + * running at around 1.1MHz. The amount this changes in a time slice is + * varies randomly due to system events, hardware interrupts etc + */ +static UCHAR randbyte_hrtimer() +{ + QWORD t1, t2; + UCHAR byte; + + DosTmrQueryTime(&t1); + DosSleep(5); + DosTmrQueryTime(&t2); + + byte = (t2.ulLo - t1.ulLo) & 0xFF; + byte ^= (t2.ulLo - t1.ulLo) >> 8; + return byte; +} + + + +/* A bunch of system information like memory & process stats. + * Not highly random but every bit helps.... + */ +static UCHAR randbyte_sysinfo() +{ + UCHAR byte = 0; + UCHAR SysVars[100]; + int b; + + DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); + + for (b = 0; b < 100; b++) { + byte ^= SysVars[b]; + } + + return byte; +} + + + +/* Similar in concept to randbyte_hrtimer() but accesses the CPU's internal + * counters which run at the CPU's MHz speed. We get separate + * idle / busy / interrupt cycle counts which should provide very good + * randomness due to interference of hardware events. + * This only works on newer CPUs (at least PPro or K6) and newer OS/2 versions + * which is why it's run-time linked. + */ + +static APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, + ULONG ulParm2, ULONG ulParm3) = NULL; +static HMODULE hDoscalls = 0; +#define CMD_KI_RDCNT (0x63) + +typedef struct _CPUUTIL { + ULONG ulTimeLow; /* Low 32 bits of time stamp */ + ULONG ulTimeHigh; /* High 32 bits of time stamp */ + ULONG ulIdleLow; /* Low 32 bits of idle time */ + ULONG ulIdleHigh; /* High 32 bits of idle time */ + ULONG ulBusyLow; /* Low 32 bits of busy time */ + ULONG ulBusyHigh; /* High 32 bits of busy time */ + ULONG ulIntrLow; /* Low 32 bits of interrupt time */ + ULONG ulIntrHigh; /* High 32 bits of interrupt time */ +} CPUUTIL; + + +static UCHAR randbyte_perf() +{ + UCHAR byte = 0; + CPUUTIL util; + int c; + + if (hDoscalls == 0) { + char failed_module[20]; + ULONG rc; + + rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", + &hDoscalls); + + if (rc == 0) { + rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall); + + if (rc) { + DosPerfSysCall = NULL; + } + } + } + + if (DosPerfSysCall) { + if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) { + for (c = 0; c < sizeof(util); c++) { + byte ^= ((UCHAR *)&util)[c]; + } + } + else { + DosPerfSysCall = NULL; + } + } + + return byte; +} + + + +static UCHAR randbyte() +{ + return randbyte_hrtimer() ^ randbyte_sysinfo() ^ randbyte_perf(); +} |