unix_rand.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 792 行 · 第 1/2 页
C
792 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include <stdio.h>#include <string.h>#include <signal.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <sys/time.h>#include <sys/wait.h>#include <sys/stat.h>#include <assert.h>#include "secrng.h"/* * When copying data to the buffer we want the least signicant bytes * from the input since those bits are changing the fastest. The address * of least significant byte depends upon whether we are running on * a big-endian or little-endian machine. * * Does this mean the least signicant bytes are the most significant * to us? :-) */ static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen){ union endianness { int32 i; char c[4]; } u; if (srclen <= dstlen) { memcpy(dst, src, srclen); return srclen; } u.i = 0x01020304; if (u.c[0] == 0x01) { /* big-endian case */ memcpy(dst, (char*)src + (srclen - dstlen), dstlen); } else { /* little-endian case */ memcpy(dst, src, dstlen); } return dstlen;}#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) \ || defined(NETBSD)#include <sys/times.h>#define getdtablesize() sysconf(_SC_OPEN_MAX)static size_tGetHighResClock(void *buf, size_t maxbytes){ int ticks; struct tms buffer; ticks=times(&buffer); return CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));}static voidGiveSystemInfo(void){ long si; /* * Is this really necessary? Why not use rand48 or something? */ si = sysconf(_SC_CHILD_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_STREAM_MAX); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_OPEN_MAX); RNG_RandomUpdate(&si, sizeof(si));}#endif#if defined(__sun)#if defined(__svr4) || defined(SVR4)#include <sys/systeminfo.h>#include <sys/times.h>#include <wait.h>int gettimeofday(struct timeval *);int gethostname(char *, int);#define getdtablesize() sysconf(_SC_OPEN_MAX)static voidGiveSystemInfo(void){ int rv; char buf[2000]; rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); }}static size_tGetHighResClock(void *buf, size_t maxbytes){ hrtime_t t; t = gethrtime(); if (t) { return CopyLowBits(buf, maxbytes, &t, sizeof(t)); } return 0;}#else /* SunOS (Sun, but not SVR4) */#include <sys/wait.h>extern long sysconf(int name);static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}static voidGiveSystemInfo(void){ long si; /* This is not very good */ si = sysconf(_SC_CHILD_MAX); RNG_RandomUpdate(&si, sizeof(si));}#endif#endif /* Sun */#if defined(__hpux)#include <sys/unistd.h>#include <sys/wait.h>#define getdtablesize() sysconf(_SC_OPEN_MAX)static size_tGetHighResClock(void *buf, size_t maxbytes){ extern int ret_cr16(); int cr16val; cr16val = ret_cr16(); return CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val));}static voidGiveSystemInfo(void){ long si; /* This is not very good */ si = sysconf(_AES_OS_VERSION); RNG_RandomUpdate(&si, sizeof(si)); si = sysconf(_SC_CPU_VERSION); RNG_RandomUpdate(&si, sizeof(si));}#endif /* HPUX */#if defined(OSF1)#include <sys/types.h>#include <sys/sysinfo.h>#include <sys/wait.h>#include <sys/systeminfo.h>#include <c_asm.h>static voidGiveSystemInfo(void){ char buf[BUFSIZ]; int rv; int off = 0; rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); }}/* * Use the "get the cycle counter" instruction on the alpha. * The low 32 bits completely turn over in less than a minute. * The high 32 bits are some non-counter gunk that changes sometimes. */static size_tGetHighResClock(void *buf, size_t maxbytes){ unsigned long t; t = asm("rpcc %v0"); return CopyLowBits(buf, maxbytes, &t, sizeof(t));}#endif /* Alpha */#if defined(_IBMR2)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}static voidGiveSystemInfo(void){ /* XXX haven't found any yet! */}#endif /* IBM R2 */#if defined(__linux)#include <linux/kernel.h>static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}static voidGiveSystemInfo(void){ /* XXX sysinfo() does not seem be implemented anywhwere */#if 0 struct sysinfo si; char hn[2000]; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); }#endif}#endif /* __linux */#if defined(NCR)#include <sys/utsname.h>#include <sys/systeminfo.h>#define getdtablesize() sysconf(_SC_OPEN_MAX)static size_tGetHighResClock(void *buf, size_t maxbytes){ return 0;}static voidGiveSystemInfo(void){ int rv; char buf[2000]; rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); }}#endif /* NCR */#if defined(sgi)#include <fcntl.h>#undef PRIVATE#include <sys/mman.h>#include <sys/syssgi.h>#include <sys/immu.h>#include <sys/systeminfo.h>#include <sys/utsname.h>#include <wait.h>static voidGiveSystemInfo(void){ int rv; char buf[4096]; rv = syssgi(SGI_SYSID, &buf[0]); if (rv > 0) { RNG_RandomUpdate(buf, MAXSYSIDSIZE); }#ifdef SGI_RDUBLK rv = syssgi(SGI_RDUBLK, getpid(), &buf[0], sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, sizeof(buf)); }#endif /* SGI_RDUBLK */ rv = syssgi(SGI_INVENT, SGI_INV_READ, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, sizeof(buf)); } rv = sysinfo(SI_MACHINE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); } rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf)); if (rv > 0) { RNG_RandomUpdate(buf, rv); }}static size_t GetHighResClock(void *buf, size_t maxbuf){ unsigned phys_addr, raddr, cycleval; static volatile unsigned *iotimer_addr = NULL; static int tries = 0; static int cntr_size; int mfd; long s0[2]; struct timeval tv;#ifndef SGI_CYCLECNTR_SIZE#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */#endif if (iotimer_addr == NULL) { if (tries++ > 1) { /* Don't keep trying if it didn't work */ return 0; } /* ** For SGI machines we can use the cycle counter, if it has one, ** to generate some truly random numbers */ phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval); if (phys_addr) { int pgsz = getpagesize(); int pgoffmask = pgsz - 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?