diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libsec/port/genrandom.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libsec/port/genrandom.c')
-rwxr-xr-x | sys/src/libsec/port/genrandom.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/sys/src/libsec/port/genrandom.c b/sys/src/libsec/port/genrandom.c new file mode 100755 index 000000000..2cbaeb8c4 --- /dev/null +++ b/sys/src/libsec/port/genrandom.c @@ -0,0 +1,62 @@ +#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); +} |