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