uxrng.c (2506B)
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 #include "primpl.h" 7 8 #include <string.h> 9 #include <unistd.h> 10 #include <errno.h> 11 #include <sys/time.h> 12 13 #if defined(SOLARIS) 14 15 static size_t GetHighResClock(void* buf, size_t maxbytes) { 16 hrtime_t t; 17 t = gethrtime(); 18 if (t) { 19 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); 20 } 21 return 0; 22 } 23 24 #elif defined(AIX) 25 26 static size_t GetHighResClock(void* buf, size_t maxbytes) { return 0; } 27 28 #elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) || \ 29 defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) || \ 30 defined(__GNU__)) 31 # include <sys/types.h> 32 # include <sys/stat.h> 33 # include <fcntl.h> 34 35 static int fdDevURandom; 36 static PRCallOnceType coOpenDevURandom; 37 38 static PRStatus OpenDevURandom(void) { 39 fdDevURandom = open("/dev/urandom", O_RDONLY); 40 return ((-1 == fdDevURandom) ? PR_FAILURE : PR_SUCCESS); 41 } /* end OpenDevURandom() */ 42 43 static size_t GetDevURandom(void* buf, size_t size) { 44 int bytesIn; 45 int rc; 46 47 rc = PR_CallOnce(&coOpenDevURandom, OpenDevURandom); 48 if (PR_FAILURE == rc) { 49 _PR_MD_MAP_OPEN_ERROR(errno); 50 return (0); 51 } 52 53 bytesIn = read(fdDevURandom, buf, size); 54 if (-1 == bytesIn) { 55 _PR_MD_MAP_READ_ERROR(errno); 56 return (0); 57 } 58 59 return (bytesIn); 60 } /* end GetDevURandom() */ 61 62 static size_t GetHighResClock(void* buf, size_t maxbytes) { 63 return (GetDevURandom(buf, maxbytes)); 64 } 65 66 #elif defined(NTO) || defined(QNX) || defined(DARWIN) || defined(RISCOS) 67 # include <sys/times.h> 68 69 static size_t GetHighResClock(void* buf, size_t maxbytes) { 70 int ticks; 71 struct tms buffer; 72 73 ticks = times(&buffer); 74 return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks)); 75 } 76 #else 77 # error ! Platform undefined 78 #endif /* defined(SOLARIS) */ 79 80 extern PRSize _PR_MD_GetRandomNoise(void* buf, PRSize size) { 81 struct timeval tv; 82 int n = 0; 83 int s; 84 85 n += GetHighResClock(buf, size); 86 size -= n; 87 88 GETTIMEOFDAY(&tv); 89 90 if (size > 0) { 91 s = _pr_CopyLowBits((char*)buf + n, size, &tv.tv_usec, sizeof(tv.tv_usec)); 92 size -= s; 93 n += s; 94 } 95 if (size > 0) { 96 s = _pr_CopyLowBits((char*)buf + n, size, &tv.tv_sec, sizeof(tv.tv_usec)); 97 size -= s; 98 n += s; 99 } 100 101 return n; 102 } /* end _PR_MD_GetRandomNoise() */