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