| #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); |
| } |