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