1*80ee5cbfSDavid du Colombier #include "os.h"
2*80ee5cbfSDavid du Colombier #include <mp.h>
3*80ee5cbfSDavid du Colombier #include <libsec.h>
4*80ee5cbfSDavid du Colombier
5*80ee5cbfSDavid du Colombier typedef struct State{
6*80ee5cbfSDavid du Colombier QLock lock;
7*80ee5cbfSDavid du Colombier int seeded;
8*80ee5cbfSDavid du Colombier uvlong seed;
9*80ee5cbfSDavid du Colombier DES3state des3;
10*80ee5cbfSDavid du Colombier } State;
11*80ee5cbfSDavid du Colombier static State x917state;
12*80ee5cbfSDavid du Colombier
13*80ee5cbfSDavid du Colombier static void
X917(uchar * rand,int nrand)14*80ee5cbfSDavid du Colombier X917(uchar *rand, int nrand)
15*80ee5cbfSDavid du Colombier {
16*80ee5cbfSDavid du Colombier int i, m, n8;
17*80ee5cbfSDavid du Colombier uvlong I, x;
18*80ee5cbfSDavid du Colombier
19*80ee5cbfSDavid du Colombier /* 1. Compute intermediate value I = Ek(time). */
20*80ee5cbfSDavid du Colombier I = nsec();
21*80ee5cbfSDavid du Colombier triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */
22*80ee5cbfSDavid du Colombier
23*80ee5cbfSDavid du Colombier /* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */
24*80ee5cbfSDavid du Colombier m = (nrand+7)/8;
25*80ee5cbfSDavid du Colombier for(i=0; i<m; i++){
26*80ee5cbfSDavid du Colombier x = I ^ x917state.seed;
27*80ee5cbfSDavid du Colombier triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
28*80ee5cbfSDavid du Colombier n8 = (nrand>8) ? 8 : nrand;
29*80ee5cbfSDavid du Colombier memcpy(rand, (uchar*)&x, n8);
30*80ee5cbfSDavid du Colombier rand += 8;
31*80ee5cbfSDavid du Colombier nrand -= 8;
32*80ee5cbfSDavid du Colombier x ^= I;
33*80ee5cbfSDavid du Colombier triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
34*80ee5cbfSDavid du Colombier x917state.seed = x;
35*80ee5cbfSDavid du Colombier }
36*80ee5cbfSDavid du Colombier }
37*80ee5cbfSDavid du Colombier
38*80ee5cbfSDavid du Colombier static void
X917init(void)39*80ee5cbfSDavid du Colombier X917init(void)
40*80ee5cbfSDavid du Colombier {
41*80ee5cbfSDavid du Colombier int n;
42*80ee5cbfSDavid du Colombier uchar mix[128];
43*80ee5cbfSDavid du Colombier uchar key3[3][8];
44*80ee5cbfSDavid du Colombier ulong *ulp;
45*80ee5cbfSDavid du Colombier
46*80ee5cbfSDavid du Colombier ulp = (ulong*)key3;
47*80ee5cbfSDavid du Colombier for(n = 0; n < sizeof(key3)/sizeof(ulong); n++)
48*80ee5cbfSDavid du Colombier ulp[n] = truerand();
49*80ee5cbfSDavid du Colombier setupDES3state(&x917state.des3, key3, nil);
50*80ee5cbfSDavid du Colombier X917(mix, sizeof mix);
51*80ee5cbfSDavid du Colombier x917state.seeded = 1;
52*80ee5cbfSDavid du Colombier }
53*80ee5cbfSDavid du Colombier
54*80ee5cbfSDavid du Colombier void
genrandom(uchar * p,int n)55*80ee5cbfSDavid du Colombier genrandom(uchar *p, int n)
56*80ee5cbfSDavid du Colombier {
57*80ee5cbfSDavid du Colombier qlock(&x917state.lock);
58*80ee5cbfSDavid du Colombier if(x917state.seeded == 0)
59*80ee5cbfSDavid du Colombier X917init();
60*80ee5cbfSDavid du Colombier X917(p, n);
61*80ee5cbfSDavid du Colombier qunlock(&x917state.lock);
62*80ee5cbfSDavid du Colombier }
63