ref: 668318b2e69edd4aa71a21ff31731fa81dbe7095
dir: /sys/src/libsec/port/genrandom.c/
#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); }