?? pgprndmsdos.c
字號:
/*
* Get high-resolution timing information to seed the random number
* generator. MS-DOS version.
*
* $Id: pgpRndMSDOS.c,v 1.6 1997/06/25 17:58:54 lloyd Exp $
*/
#include "pgpConfig.h"
#include <time.h> /* For time measurement code */
#if __BORLANDC__
#ifndef far
#define far __far /* Borland C++ 3.1's <dos.h> kacks in ANSI mode. Ugh! */
#endif
#endif
#include <dos.h> /* for enable() and disable() */
#include <conio.h> /* for inp() and outp() */
#include "pgpRndom.h"
#include "pgpUsuals.h"
#include "pgpRnd.h"
/*
* This code gets as much information as possible out of 8253/8254 timer 0,
* which ticks every .84 microseconds. There are three cases:
* 1) Original 8253. 15 bits available, as the low bit is unused.
* 2) 8254, in mode 3. The 16th bit is available from the status register.
* 3) 8254, in mode 2. All 16 bits of the counters are available.
* (This is not documented anywhere, but I've seen it!)
*
* This code repeatedly tries to latch the status (ignored by an 8253) and
* sees if it looks like xx1101x0. If not, it's definitely not an 8254.
* Repeat this a few times to make sure it is an 8254.
*/
static int
has8254(void)
{
int i, s1, s2;
for (i = 0; i < 5; i++) {
_disable();
outp(0x43, 0xe2); /* Latch status for timer 0 */
s1 = inp(0x40); /* If 8253, read timer low PGPByte */
outp(0x43, 0xe2); /* Latch status for timer 0 */
s2 = inp(0x40); /* If 8253, read timer high PGPByte */
_enable();
if ((s1 & 0x3d) != 0x34 || (s2 & 0x3d) != 0x34)
return 0; /* Ignoring status latch; 8253 */
}
return 1; /* Status reads as expected; 8254 */
}
static unsigned
read8254(void)
{
unsigned status, count;
_disable();
outp(0x43, 0xc2); /* Latch status and count for timer 0 */
status = inp(0x40);
count = inp(0x40);
count |= inp(0x40) << 8;
_enable();
/* The timer is usually in mode 3, but some motherboards use mode 2. */
if (status & 2)
count = count>>1 | (status & 0x80)<<8;
return count;
}
static unsigned
read8253(void)
{
unsigned count;
_disable();
outp(0x43, 0x00); /* Latch count for timer 0 */
count = (inp(0x40) & 0xff);
count |= (inp(0x40) & 0xff) << 8;
_enable();
return count >> 1;
}
/*
* Add as much timing-dependent random noise as possible
* to the randPool. Typically, this involves reading the most
* accurate system clocks available.
*
* Returns the number of ticks that have passed since the last call,
* for entropy estimation purposes.
*/
PGPUInt32
ranGetEntropy(PGPRandomContext const *rc)
{
PGPUInt32 delta;
static unsigned deltamask = 0;
static unsigned prevt;
unsigned t;
time_t tnow;
clock_t cnow;
if (deltamask == 0)
deltamask = has8254() ? 0xffff : 0x7fff;
t = (deltamask & 0x8000) ? read8254() : read8253();
pgpRandomAddBytes(rc, (PGPByte const *)&t, sizeof(t));
delta = deltamask & (t - prevt);
prevt = t;
/* Add more-significant time components. */
cnow = clock();
pgpRandomAddBytes(rc, (PGPByte *)&cnow, sizeof(cnow));
tnow = time((time_t *)0);
pgpRandomAddBytes(rc, (PGPByte *)&tnow, sizeof(tnow));
return delta;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -