- Timestamp:
- Dec 16, 2008, 4:18:05 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.0/source/lib/os2ea.c
r56 r160 31 31 #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) 32 32 #define CMD_KI_RDCNT (0x63) 33 34 typedef struct _CPUUTIL {35 ULONG ulTimeLow; /* Low 32 bits of time stamp */36 ULONG ulTimeHigh; /* High 32 bits of time stamp */37 ULONG ulIdleLow; /* Low 32 bits of idle time */38 ULONG ulIdleHigh; /* High 32 bits of idle time */39 ULONG ulBusyLow; /* Low 32 bits of busy time */40 ULONG ulBusyHigh; /* High 32 bits of busy time */41 ULONG ulIntrLow; /* Low 32 bits of interrupt time */42 ULONG ulIntrHigh; /* High 32 bits of interrupt time */43 } CPUUTIL;44 33 45 34 #include "local.h" … … 108 97 } 109 98 110 // very simple random data gatherer derived from openssl 99 /* Functions below are based on APR random code */ 100 /* Licensed to the Apache Software Foundation (ASF) under one or more 101 * contributor license agreements. See the NOTICE file distributed with 102 * this work for additional information regarding copyright ownership. 103 * The ASF licenses this file to You under the Apache License, Version 2.0 104 * (the "License"); you may not use this file except in compliance with 105 * the License. You may obtain a copy of the License at 106 * 107 * http://www.apache.org/licenses/LICENSE-2.0 108 * 109 * Unless required by applicable law or agreed to in writing, software 110 * distributed under the License is distributed on an "AS IS" BASIS, 111 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 112 * See the License for the specific language governing permissions and 113 * limitations under the License. 114 */ 115 116 /* The high resolution timer API provides access to the hardware timer 117 * running at around 1.1MHz. The amount this changes in a time slice is 118 * varies randomly due to system events, hardware interrupts etc 119 */ 120 111 121 void os2_randget(char * buffer, int length) 112 122 { 113 QWORD qwTime; 114 ULONG SysVars[QSV_FOREGROUND_PROCESS]; 115 int done = 0; 116 117 if (!buffer || length <= 0) 118 { 119 return; 120 } 121 122 DosTmrQueryTime(&qwTime); 123 memcpy(buffer, &qwTime, sizeof(qwTime) > length ? length : sizeof(qwTime)); 124 done += sizeof(qwTime); 125 if (done >= length) 126 { 127 return; 128 } 129 130 if (DosPerfSysCall) 131 { 132 CPUUTIL util; 133 if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) 134 { 135 memcpy(buffer + done, &util, sizeof(util) > length - done ? length - done : sizeof(util)); 136 done += sizeof(util); 137 if (done >= length) 138 { 139 return; 140 } 141 } 142 } 143 144 DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); 145 memcpy(buffer + done, SysVars, sizeof(SysVars) > length - done ? length - done : sizeof(SysVars)); 123 UCHAR randbyte(); 124 unsigned int idx; 125 126 for (idx=0; idx<length; idx++) 127 buffer[idx] = randbyte(); 128 129 } 130 131 static UCHAR randbyte_hrtimer() 132 { 133 QWORD t1, t2; 134 UCHAR byte; 135 136 DosTmrQueryTime(&t1); 137 DosSleep(5); 138 DosTmrQueryTime(&t2); 139 140 byte = (t2.ulLo - t1.ulLo) & 0xFF; 141 byte ^= (t2.ulLo - t1.ulLo) >> 8; 142 return byte; 143 } 144 145 146 147 /* A bunch of system information like memory & process stats. 148 * Not highly random but every bit helps.... 149 */ 150 static UCHAR randbyte_sysinfo() 151 { 152 UCHAR byte = 0; 153 UCHAR SysVars[100]; 154 int b; 155 156 DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); 157 158 for (b = 0; b < 100; b++) { 159 byte ^= SysVars[b]; 160 } 161 162 return byte; 163 } 164 165 166 167 /* Similar in concept to randbyte_hrtimer() but accesses the CPU's internal 168 * counters which run at the CPU's MHz speed. We get separate 169 * idle / busy / interrupt cycle counts which should provide very good 170 * randomness due to interference of hardware events. 171 * This only works on newer CPUs (at least PPro or K6) and newer OS/2 versions 172 * which is why it's run-time linked. 173 */ 174 175 static HMODULE hDoscalls = 0; 176 #define CMD_KI_RDCNT (0x63) 177 178 typedef struct _CPUUTIL { 179 ULONG ulTimeLow; /* Low 32 bits of time stamp */ 180 ULONG ulTimeHigh; /* High 32 bits of time stamp */ 181 ULONG ulIdleLow; /* Low 32 bits of idle time */ 182 ULONG ulIdleHigh; /* High 32 bits of idle time */ 183 ULONG ulBusyLow; /* Low 32 bits of busy time */ 184 ULONG ulBusyHigh; /* High 32 bits of busy time */ 185 ULONG ulIntrLow; /* Low 32 bits of interrupt time */ 186 ULONG ulIntrHigh; /* High 32 bits of interrupt time */ 187 } CPUUTIL; 188 189 190 static UCHAR randbyte_perf() 191 { 192 UCHAR byte = 0; 193 CPUUTIL util; 194 int c; 195 196 #ifndef __INNOTEK_LIBC__ 197 if (hDoscalls == 0) { 198 char failed_module[20]; 199 ULONG rc; 200 201 rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", 202 &hDoscalls); 203 204 if (rc == 0) { 205 rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall); 206 207 if (rc) { 208 DosPerfSysCall = NULL; 209 } 210 } 211 } 212 213 if (DosPerfSysCall) { 214 if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) { 215 for (c = 0; c < sizeof(util); c++) { 216 byte ^= ((UCHAR *)&util)[c]; 217 } 218 } 219 else { 220 DosPerfSysCall = NULL; 221 } 222 } 223 #endif 224 return byte; 225 } 226 227 228 229 UCHAR randbyte() 230 { 231 return randbyte_hrtimer() ^ randbyte_sysinfo() ^ randbyte_perf(); 146 232 } 147 233
Note:
See TracChangeset
for help on using the changeset viewer.