/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "primpl.h" #include #include #include #include #if defined(SOLARIS) static size_t GetHighResClock(void* buf, size_t maxbytes) { hrtime_t t; t = gethrtime(); if (t) { return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t)); } return 0; } #elif defined(AIX) static size_t GetHighResClock(void* buf, size_t maxbytes) { return 0; } #elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) || \ defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) || \ defined(__GNU__)) # include # include # include static int fdDevURandom; static PRCallOnceType coOpenDevURandom; static PRStatus OpenDevURandom(void) { fdDevURandom = open("/dev/urandom", O_RDONLY); return ((-1 == fdDevURandom) ? PR_FAILURE : PR_SUCCESS); } /* end OpenDevURandom() */ static size_t GetDevURandom(void* buf, size_t size) { int bytesIn; int rc; rc = PR_CallOnce(&coOpenDevURandom, OpenDevURandom); if (PR_FAILURE == rc) { _PR_MD_MAP_OPEN_ERROR(errno); return (0); } bytesIn = read(fdDevURandom, buf, size); if (-1 == bytesIn) { _PR_MD_MAP_READ_ERROR(errno); return (0); } return (bytesIn); } /* end GetDevURandom() */ static size_t GetHighResClock(void* buf, size_t maxbytes) { return (GetDevURandom(buf, maxbytes)); } #elif defined(NTO) || defined(QNX) || defined(DARWIN) || defined(RISCOS) # include static size_t GetHighResClock(void* buf, size_t maxbytes) { int ticks; struct tms buffer; ticks = times(&buffer); return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks)); } #else # error ! Platform undefined #endif /* defined(SOLARIS) */ extern PRSize _PR_MD_GetRandomNoise(void* buf, PRSize size) { struct timeval tv; int n = 0; int s; n += GetHighResClock(buf, size); size -= n; GETTIMEOFDAY(&tv); if (size > 0) { s = _pr_CopyLowBits((char*)buf + n, size, &tv.tv_usec, sizeof(tv.tv_usec)); size -= s; n += s; } if (size > 0) { s = _pr_CopyLowBits((char*)buf + n, size, &tv.tv_sec, sizeof(tv.tv_usec)); size -= s; n += s; } return n; } /* end _PR_MD_GetRandomNoise() */