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