diff options
| -rw-r--r-- | sys/man/2/rand | 9 | ||||
| -rw-r--r-- | sys/src/libsec/port/genrandom.c | 75 |
2 files changed, 32 insertions, 52 deletions
diff --git a/sys/man/2/rand b/sys/man/2/rand index c091d1521..d0a7b4f21 100644 --- a/sys/man/2/rand +++ b/sys/man/2/rand @@ -31,8 +31,6 @@ ulong truerand(void) .B ulong ntruerand(ulong val) .sp -.B #include <mp.h> -.br .B #include <libsec.h> .PP .B @@ -117,10 +115,9 @@ returns a uniform random integer .if n 0≤ x < val ≤ 2^32-1. .PP .I Genrandom -fills a buffer with bytes from the X9.17 pseudo-random -number generator. The X9.17 generator is seeded by 24 -truly random bytes read from -.BR /dev/random . +fills a buffer with bytes from the cryptographic pseudo-random +number generator. The generator is automatically seeded by +.IR truerand . .PP .I Prng uses the native diff --git a/sys/src/libsec/port/genrandom.c b/sys/src/libsec/port/genrandom.c index 294111e26..f4fdebbd9 100644 --- a/sys/src/libsec/port/genrandom.c +++ b/sys/src/libsec/port/genrandom.c @@ -1,61 +1,44 @@ #include "os.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) +init(Chachastate *cs) { - 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; - } + ulong seed[11]; + int i; + + for(i=0; i<nelem(seed); i++) + seed[i] = truerand(); + + setupChachastate(cs, (uchar*)&seed[0], 32, (uchar*)&seed[8], 12, 20); + memset(seed, 0, sizeof(seed)); } static void -X917init(void) +fill(Chachastate *cs, uchar *p, int n) { - 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; + Chachastate c; + + c = *cs; + chacha_encrypt((uchar*)&cs->input[4], 32, &c); + if(++cs->input[13] == 0) + if(++cs->input[14] == 0) + ++cs->input[15]; + + chacha_encrypt(p, n, &c); + memset(&c, 0, sizeof(c)); } void genrandom(uchar *p, int n) { - qlock(&x917state.lock); - if(x917state.seeded == 0) - X917init(); - X917(p, n); - qunlock(&x917state.lock); + static QLock lk; + static Chachastate cs; + + qlock(&lk); + if(cs.rounds == 0) + init(&cs); + cs.input[4] ^= getpid(); /* fork protection */ + fill(&cs, p, n); + qunlock(&lk); } |
