148 lines
3.2 KiB
C
148 lines
3.2 KiB
C
/* -*- 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 <string.h>
|
||
#include <unistd.h>
|
||
#include <errno.h>
|
||
#include <sys/time.h>
|
||
|
||
|
||
#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(HPUX)
|
||
|
||
#ifdef __ia64
|
||
#include <ia64/sys/inline.h>
|
||
|
||
static size_t
|
||
GetHighResClock(void *buf, size_t maxbytes)
|
||
{
|
||
PRUint64 t;
|
||
|
||
#ifdef __GNUC__
|
||
__asm__ __volatile__("mov %0 = ar.itc" : "=r" (t));
|
||
#else
|
||
t = _Asm_mov_from_ar(_AREG44);
|
||
#endif
|
||
return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
|
||
}
|
||
#else
|
||
static size_t
|
||
GetHighResClock(void *buf, size_t maxbytes)
|
||
{
|
||
extern int ret_cr16();
|
||
int cr16val;
|
||
|
||
cr16val = ret_cr16();
|
||
return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));
|
||
}
|
||
#endif
|
||
|
||
#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 <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <fcntl.h>
|
||
|
||
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(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
|
||
|| defined(QNX) || defined(DARWIN) || defined(RISCOS)
|
||
#include <sys/times.h>
|
||
|
||
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() */
|