comparison nspr/pr/src/md/unix/uxrng.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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
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
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
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(OSF1)
58
59 #include <c_asm.h>
60
61 /*
62 * Use the "get the cycle counter" instruction on the alpha.
63 * The low 32 bits completely turn over in less than a minute.
64 * The high 32 bits are some non-counter gunk that changes sometimes.
65 */
66 static size_t
67 GetHighResClock(void *buf, size_t maxbytes)
68 {
69 unsigned long t;
70
71 #ifdef __GNUC__
72 __asm__("rpcc %0" : "=r" (t));
73 #else
74 t = asm("rpcc %v0");
75 #endif
76 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
77 }
78
79 #elif defined(AIX)
80
81 static size_t
82 GetHighResClock(void *buf, size_t maxbytes)
83 {
84 return 0;
85 }
86
87 #elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \
88 || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \
89 || defined(SYMBIAN) || defined(__GNU__))
90 #include <sys/types.h>
91 #include <sys/stat.h>
92 #include <fcntl.h>
93
94 static int fdDevURandom;
95 static PRCallOnceType coOpenDevURandom;
96
97 static PRStatus OpenDevURandom( void )
98 {
99 fdDevURandom = open( "/dev/urandom", O_RDONLY );
100 return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS );
101 } /* end OpenDevURandom() */
102
103 static size_t GetDevURandom( void *buf, size_t size )
104 {
105 int bytesIn;
106 int rc;
107
108 rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom );
109 if ( PR_FAILURE == rc ) {
110 _PR_MD_MAP_OPEN_ERROR( errno );
111 return(0);
112 }
113
114 bytesIn = read( fdDevURandom, buf, size );
115 if ( -1 == bytesIn ) {
116 _PR_MD_MAP_READ_ERROR( errno );
117 return(0);
118 }
119
120 return( bytesIn );
121 } /* end GetDevURandom() */
122
123 static size_t
124 GetHighResClock(void *buf, size_t maxbytes)
125 {
126 return(GetDevURandom( buf, maxbytes ));
127 }
128
129 #elif defined(IRIX)
130 #include <fcntl.h>
131 #undef PRIVATE
132 #include <sys/mman.h>
133 #include <sys/syssgi.h>
134 #include <sys/immu.h>
135 #include <sys/systeminfo.h>
136 #include <sys/utsname.h>
137
138 static size_t GetHighResClock(void *buf, size_t maxbuf)
139 {
140 unsigned phys_addr, raddr, cycleval;
141 static volatile unsigned *iotimer_addr = NULL;
142 static int tries = 0;
143 static int cntr_size;
144 int mfd;
145 unsigned s0[2];
146
147 #ifndef SGI_CYCLECNTR_SIZE
148 #define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */
149 #endif
150
151 if (iotimer_addr == NULL) {
152 if (tries++ > 1) {
153 /* Don't keep trying if it didn't work */
154 return 0;
155 }
156
157 /*
158 ** For SGI machines we can use the cycle counter, if it has one,
159 ** to generate some truly random numbers
160 */
161 phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
162 if (phys_addr) {
163 int pgsz = getpagesize();
164 int pgoffmask = pgsz - 1;
165
166 raddr = phys_addr & ~pgoffmask;
167 mfd = open("/dev/mmem", O_RDONLY);
168 if (mfd < 0) {
169 return 0;
170 }
171 iotimer_addr = (unsigned *)
172 mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
173 if (iotimer_addr == (unsigned*)-1) {
174 close(mfd);
175 iotimer_addr = NULL;
176 return 0;
177 }
178 iotimer_addr = (unsigned*)
179 ((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
180 /*
181 * The file 'mfd' is purposefully not closed.
182 */
183 cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
184 if (cntr_size < 0) {
185 struct utsname utsinfo;
186
187 /*
188 * We must be executing on a 6.0 or earlier system, since the
189 * SGI_CYCLECNTR_SIZE call is not supported.
190 *
191 * The only pre-6.1 platforms with 64-bit counters are
192 * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
193 */
194 uname(&utsinfo);
195 if (!strncmp(utsinfo.machine, "IP19", 4) ||
196 !strncmp(utsinfo.machine, "IP21", 4))
197 cntr_size = 64;
198 else
199 cntr_size = 32;
200 }
201 cntr_size /= 8; /* Convert from bits to bytes */
202 }
203 }
204
205 s0[0] = *iotimer_addr;
206 if (cntr_size > 4)
207 s0[1] = *(iotimer_addr + 1);
208 memcpy(buf, (char *)&s0[0], cntr_size);
209 return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size);
210 }
211
212 #elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
213 || defined(QNX) || defined(DARWIN) || defined(RISCOS)
214 #include <sys/times.h>
215
216 static size_t
217 GetHighResClock(void *buf, size_t maxbytes)
218 {
219 int ticks;
220 struct tms buffer;
221
222 ticks=times(&buffer);
223 return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
224 }
225 #else
226 #error! Platform undefined
227 #endif /* defined(SOLARIS) */
228
229 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
230 {
231 struct timeval tv;
232 int n = 0;
233 int s;
234
235 n += GetHighResClock(buf, size);
236 size -= n;
237
238 GETTIMEOFDAY(&tv);
239
240 if ( size > 0 ) {
241 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
242 size -= s;
243 n += s;
244 }
245 if ( size > 0 ) {
246 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
247 size -= s;
248 n += s;
249 }
250
251 return n;
252 } /* end _PR_MD_GetRandomNoise() */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)