Fix compile and test on Linux.

git-svn-id: file:///svn/unbound/trunk@3159 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2014-07-11 09:39:13 +00:00
parent e445cc74af
commit 9f0a53e79b
6 changed files with 12 additions and 242 deletions

View File

@ -17,6 +17,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "config.h"
/* /*
* ChaCha based random number generator for OpenBSD. * ChaCha based random number generator for OpenBSD.
@ -34,8 +35,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "thread_private.h"
#define KEYSTREAM_ONLY #define KEYSTREAM_ONLY
#include "chacha_private.h" #include "chacha_private.h"
@ -211,39 +210,3 @@ arc4random_buf(void *buf, size_t n)
_rs_random_buf(buf, n); _rs_random_buf(buf, n);
_ARC4_UNLOCK(); _ARC4_UNLOCK();
} }
/*
* Calculate a uniformly distributed random number less than upper_bound
* avoiding "modulo bias".
*
* Uniformity is achieved by generating new random numbers until the one
* returned is outside the range [0, 2**32 % upper_bound). This
* guarantees the selected random number will be inside
* [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
* after reduction modulo upper_bound.
*/
uint32_t
arc4random_uniform(uint32_t upper_bound)
{
uint32_t r, min;
if (upper_bound < 2)
return 0;
/* 2**32 % x == (2**32 - x) % x */
min = -upper_bound % upper_bound;
/*
* This could theoretically loop forever but each retry has
* p > 0.5 (worst case, usually far better) of selecting a
* number inside the range we need, so it should rarely need
* to re-roll.
*/
for (;;) {
r = arc4random();
if (r >= min)
break;
}
return r % upper_bound;
}

View File

@ -17,200 +17,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "config.h"
/*
* ChaCha based random number generator for OpenBSD.
*/
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/mman.h>
#include "thread_private.h"
#define KEYSTREAM_ONLY
#include "chacha_private.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
#ifdef __GNUC__
#define inline __inline
#else /* !__GNUC__ */
#define inline
#endif /* !__GNUC__ */
#define KEYSZ 32
#define IVSZ 8
#define BLOCKSZ 64
#define RSBUFSZ (16*BLOCKSZ)
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
static struct {
size_t rs_have; /* valid bytes at end of rs_buf */
size_t rs_count; /* bytes till reseed */
} *rs;
/* Preserved in fork children. */
static struct {
chacha_ctx rs_chacha; /* chacha context for random keystream */
u_char rs_buf[RSBUFSZ]; /* keystream blocks */
} *rsx;
static inline void _rs_rekey(u_char *dat, size_t datlen);
static inline void
_rs_init(u_char *buf, size_t n)
{
if (n < KEYSZ + IVSZ)
return;
if (rs == NULL) {
if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
abort();
#ifdef MAP_INHERIT_ZERO
if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
abort();
#endif
}
if (rsx == NULL) {
if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
abort();
}
chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
}
static void
_rs_stir(void)
{
u_char rnd[KEYSZ + IVSZ];
if (getentropy(rnd, sizeof rnd) == -1)
raise(SIGKILL);
if (!rs)
_rs_init(rnd, sizeof(rnd));
else
_rs_rekey(rnd, sizeof(rnd));
explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
/* invalidate rs_buf */
rs->rs_have = 0;
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
rs->rs_count = 1600000;
}
static inline void
_rs_stir_if_needed(size_t len)
{
#ifndef MAP_INHERIT_ZERO
static pid_t _rs_pid = 0;
pid_t pid = getpid();
/* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
if (_rs_pid == 0 || _rs_pid != pid) {
_rs_pid = pid;
if (rs)
rs->rs_count = 0;
}
#endif
if (!rs || rs->rs_count <= len)
_rs_stir();
if (rs->rs_count <= len)
rs->rs_count = 0;
else
rs->rs_count -= len;
}
static inline void
_rs_rekey(u_char *dat, size_t datlen)
{
#ifndef KEYSTREAM_ONLY
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
#endif
/* fill rs_buf with the keystream */
chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
rsx->rs_buf, sizeof(rsx->rs_buf));
/* mix in optional user provided data */
if (dat) {
size_t i, m;
m = min(datlen, KEYSZ + IVSZ);
for (i = 0; i < m; i++)
rsx->rs_buf[i] ^= dat[i];
}
/* immediately reinit for backtracking resistance */
_rs_init(rsx->rs_buf, KEYSZ + IVSZ);
memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
}
static inline void
_rs_random_buf(void *_buf, size_t n)
{
u_char *buf = (u_char *)_buf;
u_char *keystream;
size_t m;
_rs_stir_if_needed(n);
while (n > 0) {
if (rs->rs_have > 0) {
m = min(n, rs->rs_have);
keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
- rs->rs_have;
memcpy(buf, keystream, m);
memset(keystream, 0, m);
buf += m;
n -= m;
rs->rs_have -= m;
}
if (rs->rs_have == 0)
_rs_rekey(NULL, 0);
}
}
static inline void
_rs_random_u32(uint32_t *val)
{
u_char *keystream;
_rs_stir_if_needed(sizeof(*val));
if (rs->rs_have < sizeof(*val))
_rs_rekey(NULL, 0);
keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
memcpy(val, keystream, sizeof(*val));
memset(keystream, 0, sizeof(*val));
rs->rs_have -= sizeof(*val);
}
uint32_t
arc4random(void)
{
uint32_t val;
_ARC4_LOCK();
_rs_random_u32(&val);
_ARC4_UNLOCK();
return val;
}
void
arc4random_buf(void *buf, size_t n)
{
_ARC4_LOCK();
_rs_random_buf(buf, n);
_ARC4_UNLOCK();
}
/* /*
* Calculate a uniformly distributed random number less than upper_bound * Calculate a uniformly distributed random number less than upper_bound

View File

@ -52,7 +52,7 @@ static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k"; static const char tau[16] = "expand 16-byte k";
static void static void
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits) chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
{ {
const char *constants; const char *constants;

View File

@ -3,11 +3,11 @@
* Public domain. * Public domain.
* Written by Matthew Dempsky. * Written by Matthew Dempsky.
*/ */
#include "config.h"
#include <string.h> #include <string.h>
__attribute__((weak)) void __attribute__((weak)) void
__explicit_bzero_hook(void *buf, size_t len) __explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len))
{ {
} }

View File

@ -232,11 +232,11 @@ static int
getentropy_sysctl(void *buf, size_t len) getentropy_sysctl(void *buf, size_t len)
{ {
static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID }; static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
size_t i, chunk; size_t i;
int save_errno = errno; int save_errno = errno;
for (i = 0; i < len; ) { for (i = 0; i < len; ) {
chunk = min(len - i, 16); size_t chunk = min(len - i, 16);
/* SYS__sysctl because some systems already removed sysctl() */ /* SYS__sysctl because some systems already removed sysctl() */
struct __sysctl_args args = { struct __sysctl_args args = {
@ -288,7 +288,7 @@ static int
getentropy_fallback(void *buf, size_t len) getentropy_fallback(void *buf, size_t len)
{ {
uint8_t results[SHA512_DIGEST_LENGTH]; uint8_t results[SHA512_DIGEST_LENGTH];
int save_errno = errno, e, m, pgs = getpagesize(), faster = 0, repeat; int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
static int cnt; static int cnt;
struct timespec ts; struct timespec ts;
struct timeval tv; struct timeval tv;
@ -298,7 +298,7 @@ getentropy_fallback(void *buf, size_t len)
SHA512_CTX ctx; SHA512_CTX ctx;
static pid_t lastpid; static pid_t lastpid;
pid_t pid; pid_t pid;
size_t i, ii; size_t i, ii, m;
char *p; char *p;
pid = getpid(); pid = getpid();
@ -327,7 +327,7 @@ getentropy_fallback(void *buf, size_t len)
HX((pid = getsid(pid)) == -1, pid); HX((pid = getsid(pid)) == -1, pid);
HX((pid = getppid()) == -1, pid); HX((pid = getppid()) == -1, pid);
HX((pid = getpgid(0)) == -1, pid); HX((pid = getpgid(0)) == -1, pid);
HX((m = getpriority(0, 0)) == -1, m); HX((e = getpriority(0, 0)) == -1, e);
if (!faster) { if (!faster) {
ts.tv_sec = 0; ts.tv_sec = 0;

View File

@ -10,7 +10,7 @@
#define FLEX_SCANNER #define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 36 #define YY_FLEX_SUBMINOR_VERSION 37
#if YY_FLEX_SUBMINOR_VERSION > 0 #if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA #define FLEX_BETA
#endif #endif
@ -3550,7 +3550,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
YY_BUFFER_STATE b; YY_BUFFER_STATE b;
char *buf; char *buf;
yy_size_t n; yy_size_t n;
int i; yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */ /* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2; n = _yybytes_len + 2;