]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libsec/port/genrandom.c
libsec: generalize pbkdf2_hmac_sha1() to pbkdf2_x() passing the hmac as an argument
[plan9front.git] / sys / src / libsec / port / genrandom.c
1 #include "os.h"
2 #include <mp.h>
3 #include <libsec.h>
4
5 typedef struct State{
6         QLock           lock;
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         qlock(&x917state.lock);
58         if(x917state.seeded == 0)
59                 X917init();
60         X917(p, n);
61         qunlock(&x917state.lock);
62 }