xref: /plan9-contrib/sys/src/cmd/unix/u9fs/random.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include <plan9.h>
2*9a747e4fSDavid du Colombier #include <fcall.h>
3*9a747e4fSDavid du Colombier #include <u9fs.h>
4*9a747e4fSDavid du Colombier #include <stdlib.h>
5*9a747e4fSDavid du Colombier #include <sys/time.h>
6*9a747e4fSDavid du Colombier #include <fcntl.h>
7*9a747e4fSDavid du Colombier 
8*9a747e4fSDavid du Colombier static long
9*9a747e4fSDavid du Colombier getseed(void)
10*9a747e4fSDavid du Colombier {
11*9a747e4fSDavid du Colombier 	struct timeval tv;
12*9a747e4fSDavid du Colombier 	long seed;
13*9a747e4fSDavid du Colombier 	int fd, len;
14*9a747e4fSDavid du Colombier 
15*9a747e4fSDavid du Colombier 	len = 0;
16*9a747e4fSDavid du Colombier 	fd = open("/dev/urandom", O_RDONLY);
17*9a747e4fSDavid du Colombier 	if(fd > 0){
18*9a747e4fSDavid du Colombier 		len = readn(fd, &seed, sizeof(seed));
19*9a747e4fSDavid du Colombier 		close(fd);
20*9a747e4fSDavid du Colombier 	}
21*9a747e4fSDavid du Colombier 	if(len != sizeof(seed)){
22*9a747e4fSDavid du Colombier 		gettimeofday(&tv, nil);
23*9a747e4fSDavid du Colombier 		seed = tv.tv_sec ^ tv.tv_usec ^ (getpid()<<8);
24*9a747e4fSDavid du Colombier 	}
25*9a747e4fSDavid du Colombier 	return seed;
26*9a747e4fSDavid du Colombier }
27*9a747e4fSDavid du Colombier 
28*9a747e4fSDavid du Colombier static int seeded;
29*9a747e4fSDavid du Colombier 
30*9a747e4fSDavid du Colombier void
31*9a747e4fSDavid du Colombier randombytes(uchar *r, uint nr)
32*9a747e4fSDavid du Colombier {
33*9a747e4fSDavid du Colombier 	int i;
34*9a747e4fSDavid du Colombier 	ulong l;
35*9a747e4fSDavid du Colombier 
36*9a747e4fSDavid du Colombier 	if(!seeded){
37*9a747e4fSDavid du Colombier 		seeded=1;
38*9a747e4fSDavid du Colombier 		srand48(getseed());
39*9a747e4fSDavid du Colombier 	}
40*9a747e4fSDavid du Colombier 	for(i=0; i+4<=nr; i+=4,r+=4){
41*9a747e4fSDavid du Colombier 		l = (ulong)mrand48();
42*9a747e4fSDavid du Colombier 		r[0] = l;
43*9a747e4fSDavid du Colombier 		r[1] = l>>8;
44*9a747e4fSDavid du Colombier 		r[2] = l>>16;
45*9a747e4fSDavid du Colombier 		r[3] = l>>24;
46*9a747e4fSDavid du Colombier 	}
47*9a747e4fSDavid du Colombier 	if(i<nr){
48*9a747e4fSDavid du Colombier 		l = (ulong)mrand48();
49*9a747e4fSDavid du Colombier 		switch(nr-i){
50*9a747e4fSDavid du Colombier 		case 3:
51*9a747e4fSDavid du Colombier 			r[2] = l>>16;
52*9a747e4fSDavid du Colombier 		case 2:
53*9a747e4fSDavid du Colombier 			r[1] = l>>8;
54*9a747e4fSDavid du Colombier 		case 1:
55*9a747e4fSDavid du Colombier 			r[0] = l;
56*9a747e4fSDavid du Colombier 		}
57*9a747e4fSDavid du Colombier 	}
58*9a747e4fSDavid du Colombier }
59