#include "os.h" | |
#include <mp.h> | |
#include <libsec.h> | |
typedef struct State{ | |
QLock lock; | |
int seeded; | |
uvlong seed; | |
DES3state des3; | |
} State; | |
static State x917state; | |
static void | |
X917(uchar *rand, int nrand) | |
{ | |
int i, m, n8; | |
uvlong I, x; | |
/* 1. Compute intermediate value I = Ek(time). */ | |
I = nsec(); | |
triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */ | |
/* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */ | |
m = (nrand+7)/8; | |
for(i=0; i<m; i++){ | |
x = I ^ x917state.seed; | |
triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0); | |
n8 = (nrand>8) ? 8 : nrand; | |
memcpy(rand, (uchar*)&x, n8); | |
rand += 8; | |
nrand -= 8; | |
x ^= I; | |
triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0); | |
x917state.seed = x; | |
} | |
} | |
static void | |
X917init(void) | |
{ | |
int n; | |
uchar mix[128]; | |
uchar key3[3][8]; | |
ulong *ulp; | |
ulp = (ulong*)key3; | |
for(n = 0; n < sizeof(key3)/sizeof(ulong); n++) | |
ulp[n] = truerand(); | |
setupDES3state(&x917state.des3, key3, nil); | |
X917(mix, sizeof mix); | |
x917state.seeded = 1; | |
} | |
void | |
genrandom(uchar *p, int n) | |
{ | |
qlock(&x917state.lock); | |
if(x917state.seeded == 0) | |
X917init(); | |
X917(p, n); | |
qunlock(&x917state.lock); | |
} |