1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
7 #include "primpl.h"
8
9 #include <string.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <sys/time.h>
13
14
15 #if defined(SOLARIS)
16
17 static size_t
GetHighResClock(void * buf,size_t maxbytes)18 GetHighResClock(void *buf, size_t maxbytes)
19 {
20 hrtime_t t;
21 t = gethrtime();
22 if (t) {
23 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
24 }
25 return 0;
26 }
27
28 #elif defined(HPUX)
29
30 #ifdef __ia64
31 #include <ia64/sys/inline.h>
32
33 static size_t
GetHighResClock(void * buf,size_t maxbytes)34 GetHighResClock(void *buf, size_t maxbytes)
35 {
36 PRUint64 t;
37
38 #ifdef __GNUC__
39 __asm__ __volatile__("mov %0 = ar.itc" : "=r" (t));
40 #else
41 t = _Asm_mov_from_ar(_AREG44);
42 #endif
43 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
44 }
45 #else
46 static size_t
GetHighResClock(void * buf,size_t maxbytes)47 GetHighResClock(void *buf, size_t maxbytes)
48 {
49 extern int ret_cr16();
50 int cr16val;
51
52 cr16val = ret_cr16();
53 return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));
54 }
55 #endif
56
57 #elif defined(AIX)
58
59 static size_t
GetHighResClock(void * buf,size_t maxbytes)60 GetHighResClock(void *buf, size_t maxbytes)
61 {
62 return 0;
63 }
64
65 #elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \
66 || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \
67 || defined(__GNU__))
68 #include <sys/types.h>
69 #include <sys/stat.h>
70 #include <fcntl.h>
71
72 static int fdDevURandom;
73 static PRCallOnceType coOpenDevURandom;
74
OpenDevURandom(void)75 static PRStatus OpenDevURandom( void )
76 {
77 fdDevURandom = open( "/dev/urandom", O_RDONLY );
78 return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS );
79 } /* end OpenDevURandom() */
80
GetDevURandom(void * buf,size_t size)81 static size_t GetDevURandom( void *buf, size_t size )
82 {
83 int bytesIn;
84 int rc;
85
86 rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom );
87 if ( PR_FAILURE == rc ) {
88 _PR_MD_MAP_OPEN_ERROR( errno );
89 return(0);
90 }
91
92 bytesIn = read( fdDevURandom, buf, size );
93 if ( -1 == bytesIn ) {
94 _PR_MD_MAP_READ_ERROR( errno );
95 return(0);
96 }
97
98 return( bytesIn );
99 } /* end GetDevURandom() */
100
101 static size_t
GetHighResClock(void * buf,size_t maxbytes)102 GetHighResClock(void *buf, size_t maxbytes)
103 {
104 return(GetDevURandom( buf, maxbytes ));
105 }
106
107 #elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
108 || defined(QNX) || defined(DARWIN) || defined(RISCOS)
109 #include <sys/times.h>
110
111 static size_t
GetHighResClock(void * buf,size_t maxbytes)112 GetHighResClock(void *buf, size_t maxbytes)
113 {
114 int ticks;
115 struct tms buffer;
116
117 ticks=times(&buffer);
118 return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
119 }
120 #else
121 #error! Platform undefined
122 #endif /* defined(SOLARIS) */
123
_PR_MD_GetRandomNoise(void * buf,PRSize size)124 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
125 {
126 struct timeval tv;
127 int n = 0;
128 int s;
129
130 n += GetHighResClock(buf, size);
131 size -= n;
132
133 GETTIMEOFDAY(&tv);
134
135 if ( size > 0 ) {
136 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
137 size -= s;
138 n += s;
139 }
140 if ( size > 0 ) {
141 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
142 size -= s;
143 n += s;
144 }
145
146 return n;
147 } /* end _PR_MD_GetRandomNoise() */
148