summaryrefslogtreecommitdiffstats
path: root/contrib/unbound/compat
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2015-07-06 13:23:27 +0000
committerdes <des@FreeBSD.org>2015-07-06 13:23:27 +0000
commita060063a487e71aee85b154308b20e3c3d050c54 (patch)
tree78e508412e7aed4056295e6af1335856834fc7e3 /contrib/unbound/compat
parentc49abb198d367256a94da48fed297b82b5a11ad9 (diff)
downloadFreeBSD-src-a060063a487e71aee85b154308b20e3c3d050c54.zip
FreeBSD-src-a060063a487e71aee85b154308b20e3c3d050c54.tar.gz
MFH (r276605, r282089): upgrade to latest Unbound
MFH (r276699, r276702, r277057): local control socket MFH (r276599, r276612, r282087, r282088): build fixes This brings in Unbound 1.5.3 from head. Local control sockets are now supported and will be used by default for new installations. Existing systems will continue to use TCP control sockets until the automated setup script is re-run ("service local_unbound setup") and the service restarted ("service local_unbound restart"). Approved by: re (kib) Relnotes: yes
Diffstat (limited to 'contrib/unbound/compat')
-rw-r--r--contrib/unbound/compat/arc4_lock.c67
-rw-r--r--contrib/unbound/compat/arc4random.c231
-rw-r--r--contrib/unbound/compat/arc4random_uniform.c57
-rw-r--r--contrib/unbound/compat/chacha_private.h222
-rw-r--r--contrib/unbound/compat/explicit_bzero.c22
-rw-r--r--contrib/unbound/compat/fake-rfc2553.c4
-rw-r--r--contrib/unbound/compat/getentropy_linux.c514
-rw-r--r--contrib/unbound/compat/getentropy_osx.c432
-rw-r--r--contrib/unbound/compat/getentropy_solaris.c435
-rw-r--r--contrib/unbound/compat/getentropy_win.c56
-rw-r--r--contrib/unbound/compat/inet_aton.c10
-rw-r--r--contrib/unbound/compat/memmove.c2
-rw-r--r--contrib/unbound/compat/sha512.c477
-rw-r--r--contrib/unbound/compat/strptime.c8
14 files changed, 2524 insertions, 13 deletions
diff --git a/contrib/unbound/compat/arc4_lock.c b/contrib/unbound/compat/arc4_lock.c
new file mode 100644
index 0000000..faa743d
--- /dev/null
+++ b/contrib/unbound/compat/arc4_lock.c
@@ -0,0 +1,67 @@
+/* arc4_lock.c - global lock for arc4random
+*
+ * Copyright (c) 2014, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#define LOCKRET(func) func
+#include "util/locks.h"
+
+void _ARC4_LOCK(void);
+void _ARC4_UNLOCK(void);
+
+#ifdef THREADS_DISABLED
+void _ARC4_LOCK(void)
+{
+}
+
+void _ARC4_UNLOCK(void)
+{
+}
+#else /* !THREADS_DISABLED */
+
+static lock_quick_t arc4lock;
+static int arc4lockinit = 0;
+
+void _ARC4_LOCK(void)
+{
+ if(!arc4lockinit) {
+ arc4lockinit = 1;
+ lock_quick_init(&arc4lock);
+ }
+ lock_quick_lock(&arc4lock);
+}
+
+void _ARC4_UNLOCK(void)
+{
+ lock_quick_unlock(&arc4lock);
+}
+#endif /* THREADS_DISABLED */
diff --git a/contrib/unbound/compat/arc4random.c b/contrib/unbound/compat/arc4random.c
new file mode 100644
index 0000000..27a626b
--- /dev/null
+++ b/contrib/unbound/compat/arc4random.c
@@ -0,0 +1,231 @@
+/* $OpenBSD: arc4random.c,v 1.41 2014/07/12 13:24:54 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * 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>
+#ifndef UB_ON_WINDOWS
+#include <sys/mman.h>
+#endif
+
+#define KEYSTREAM_ONLY
+#include "chacha_private.h"
+
+#define arc4_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) {
+#ifndef UB_ON_WINDOWS
+ 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
+#else /* WINDOWS */
+ rs = malloc(sizeof(*rs));
+ if(!rs)
+ abort();
+#endif
+ }
+ if (rsx == NULL) {
+#ifndef UB_ON_WINDOWS
+ if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ abort();
+#else /* WINDOWS */
+ rsx = malloc(sizeof(*rsx));
+ if(!rsx)
+ abort();
+#endif
+ }
+
+ 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) {
+#ifdef SIGKILL
+ raise(SIGKILL);
+#else
+ exit(9); /* windows */
+#endif
+ }
+
+ 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 = arc4_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 = arc4_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();
+}
diff --git a/contrib/unbound/compat/arc4random_uniform.c b/contrib/unbound/compat/arc4random_uniform.c
new file mode 100644
index 0000000..154260e
--- /dev/null
+++ b/contrib/unbound/compat/arc4random_uniform.c
@@ -0,0 +1,57 @@
+/* $OpenBSD: arc4random_uniform.c,v 1.1 2014/07/12 13:24:54 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <stdlib.h>
+
+/*
+ * 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;
+}
diff --git a/contrib/unbound/compat/chacha_private.h b/contrib/unbound/compat/chacha_private.h
new file mode 100644
index 0000000..192258c
--- /dev/null
+++ b/contrib/unbound/compat/chacha_private.h
@@ -0,0 +1,222 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+typedef struct
+{
+ u32 input[16]; /* could be compressed */
+} chacha_ctx;
+
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((u8)(v) & U8C(0xFF))
+#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
+
+#define ROTL32(v, n) \
+ (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define U8TO32_LITTLE(p) \
+ (((u32)((p)[0]) ) | \
+ ((u32)((p)[1]) << 8) | \
+ ((u32)((p)[2]) << 16) | \
+ ((u32)((p)[3]) << 24))
+
+#define U32TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ } while (0)
+
+#define ROTATE(v,c) (ROTL32(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+static void
+chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
+{
+ const char *constants;
+
+ x->input[4] = U8TO32_LITTLE(k + 0);
+ x->input[5] = U8TO32_LITTLE(k + 4);
+ x->input[6] = U8TO32_LITTLE(k + 8);
+ x->input[7] = U8TO32_LITTLE(k + 12);
+ if (kbits == 256) { /* recommended */
+ k += 16;
+ constants = sigma;
+ } else { /* kbits == 128 */
+ constants = tau;
+ }
+ x->input[8] = U8TO32_LITTLE(k + 0);
+ x->input[9] = U8TO32_LITTLE(k + 4);
+ x->input[10] = U8TO32_LITTLE(k + 8);
+ x->input[11] = U8TO32_LITTLE(k + 12);
+ x->input[0] = U8TO32_LITTLE(constants + 0);
+ x->input[1] = U8TO32_LITTLE(constants + 4);
+ x->input[2] = U8TO32_LITTLE(constants + 8);
+ x->input[3] = U8TO32_LITTLE(constants + 12);
+}
+
+static void
+chacha_ivsetup(chacha_ctx *x,const u8 *iv)
+{
+ x->input[12] = 0;
+ x->input[13] = 0;
+ x->input[14] = U8TO32_LITTLE(iv + 0);
+ x->input[15] = U8TO32_LITTLE(iv + 4);
+}
+
+static void
+chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
+{
+ u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
+ u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ u8 *ctarget = NULL;
+ u8 tmp[64];
+ u_int i;
+
+ if (!bytes) return;
+
+ j0 = x->input[0];
+ j1 = x->input[1];
+ j2 = x->input[2];
+ j3 = x->input[3];
+ j4 = x->input[4];
+ j5 = x->input[5];
+ j6 = x->input[6];
+ j7 = x->input[7];
+ j8 = x->input[8];
+ j9 = x->input[9];
+ j10 = x->input[10];
+ j11 = x->input[11];
+ j12 = x->input[12];
+ j13 = x->input[13];
+ j14 = x->input[14];
+ j15 = x->input[15];
+
+ for (;;) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) tmp[i] = m[i];
+ m = tmp;
+ ctarget = c;
+ c = tmp;
+ }
+ x0 = j0;
+ x1 = j1;
+ x2 = j2;
+ x3 = j3;
+ x4 = j4;
+ x5 = j5;
+ x6 = j6;
+ x7 = j7;
+ x8 = j8;
+ x9 = j9;
+ x10 = j10;
+ x11 = j11;
+ x12 = j12;
+ x13 = j13;
+ x14 = j14;
+ x15 = j15;
+ for (i = 20;i > 0;i -= 2) {
+ QUARTERROUND( x0, x4, x8,x12)
+ QUARTERROUND( x1, x5, x9,x13)
+ QUARTERROUND( x2, x6,x10,x14)
+ QUARTERROUND( x3, x7,x11,x15)
+ QUARTERROUND( x0, x5,x10,x15)
+ QUARTERROUND( x1, x6,x11,x12)
+ QUARTERROUND( x2, x7, x8,x13)
+ QUARTERROUND( x3, x4, x9,x14)
+ }
+ x0 = PLUS(x0,j0);
+ x1 = PLUS(x1,j1);
+ x2 = PLUS(x2,j2);
+ x3 = PLUS(x3,j3);
+ x4 = PLUS(x4,j4);
+ x5 = PLUS(x5,j5);
+ x6 = PLUS(x6,j6);
+ x7 = PLUS(x7,j7);
+ x8 = PLUS(x8,j8);
+ x9 = PLUS(x9,j9);
+ x10 = PLUS(x10,j10);
+ x11 = PLUS(x11,j11);
+ x12 = PLUS(x12,j12);
+ x13 = PLUS(x13,j13);
+ x14 = PLUS(x14,j14);
+ x15 = PLUS(x15,j15);
+
+#ifndef KEYSTREAM_ONLY
+ x0 = XOR(x0,U8TO32_LITTLE(m + 0));
+ x1 = XOR(x1,U8TO32_LITTLE(m + 4));
+ x2 = XOR(x2,U8TO32_LITTLE(m + 8));
+ x3 = XOR(x3,U8TO32_LITTLE(m + 12));
+ x4 = XOR(x4,U8TO32_LITTLE(m + 16));
+ x5 = XOR(x5,U8TO32_LITTLE(m + 20));
+ x6 = XOR(x6,U8TO32_LITTLE(m + 24));
+ x7 = XOR(x7,U8TO32_LITTLE(m + 28));
+ x8 = XOR(x8,U8TO32_LITTLE(m + 32));
+ x9 = XOR(x9,U8TO32_LITTLE(m + 36));
+ x10 = XOR(x10,U8TO32_LITTLE(m + 40));
+ x11 = XOR(x11,U8TO32_LITTLE(m + 44));
+ x12 = XOR(x12,U8TO32_LITTLE(m + 48));
+ x13 = XOR(x13,U8TO32_LITTLE(m + 52));
+ x14 = XOR(x14,U8TO32_LITTLE(m + 56));
+ x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+#endif
+
+ j12 = PLUSONE(j12);
+ if (!j12) {
+ j13 = PLUSONE(j13);
+ /* stopping at 2^70 bytes per nonce is user's responsibility */
+ }
+
+ U32TO8_LITTLE(c + 0,x0);
+ U32TO8_LITTLE(c + 4,x1);
+ U32TO8_LITTLE(c + 8,x2);
+ U32TO8_LITTLE(c + 12,x3);
+ U32TO8_LITTLE(c + 16,x4);
+ U32TO8_LITTLE(c + 20,x5);
+ U32TO8_LITTLE(c + 24,x6);
+ U32TO8_LITTLE(c + 28,x7);
+ U32TO8_LITTLE(c + 32,x8);
+ U32TO8_LITTLE(c + 36,x9);
+ U32TO8_LITTLE(c + 40,x10);
+ U32TO8_LITTLE(c + 44,x11);
+ U32TO8_LITTLE(c + 48,x12);
+ U32TO8_LITTLE(c + 52,x13);
+ U32TO8_LITTLE(c + 56,x14);
+ U32TO8_LITTLE(c + 60,x15);
+
+ if (bytes <= 64) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) ctarget[i] = c[i];
+ }
+ x->input[12] = j12;
+ x->input[13] = j13;
+ return;
+ }
+ bytes -= 64;
+ c += 64;
+#ifndef KEYSTREAM_ONLY
+ m += 64;
+#endif
+ }
+}
diff --git a/contrib/unbound/compat/explicit_bzero.c b/contrib/unbound/compat/explicit_bzero.c
new file mode 100644
index 0000000..a3ba279
--- /dev/null
+++ b/contrib/unbound/compat/explicit_bzero.c
@@ -0,0 +1,22 @@
+/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
+/*
+ * Public domain.
+ * Written by Matthew Dempsky.
+ */
+#include "config.h"
+#include <string.h>
+
+__attribute__((weak)) void
+__explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len))
+{
+}
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+#ifdef UB_ON_WINDOWS
+ SecureZeroMemory(buf, len);
+#endif
+ memset(buf, 0, len);
+ __explicit_bzero_hook(buf, len);
+}
diff --git a/contrib/unbound/compat/fake-rfc2553.c b/contrib/unbound/compat/fake-rfc2553.c
index 91ddf8a..0f0f34f 100644
--- a/contrib/unbound/compat/fake-rfc2553.c
+++ b/contrib/unbound/compat/fake-rfc2553.c
@@ -120,12 +120,10 @@ addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
{
struct addrinfo *ai;
- ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
+ ai = calloc(1, sizeof(*ai) + sizeof(struct sockaddr_in));
if (ai == NULL)
return (NULL);
- memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
-
ai->ai_addr = (struct sockaddr *)(ai + 1);
/* XXX -- ssh doesn't use sa_len */
ai->ai_addrlen = sizeof(struct sockaddr_in);
diff --git a/contrib/unbound/compat/getentropy_linux.c b/contrib/unbound/compat/getentropy_linux.c
new file mode 100644
index 0000000..d4adab2
--- /dev/null
+++ b/contrib/unbound/compat/getentropy_linux.c
@@ -0,0 +1,514 @@
+/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
+
+/*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+ * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "config.h"
+
+/*
+#define _POSIX_C_SOURCE 199309L
+#define _GNU_SOURCE 1
+*/
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#include <sys/statvfs.h>
+#include <sys/socket.h>
+#include <sys/mount.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <openssl/sha.h>
+
+#include <linux/types.h>
+#include <linux/random.h>
+#include <linux/sysctl.h>
+#ifdef HAVE_GETAUXVAL
+#include <sys/auxv.h>
+#endif
+#include <sys/vfs.h>
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+ do { \
+ if ((a)) \
+ HD(errno); \
+ else \
+ HD(b); \
+ } while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int getentropy(void *buf, size_t len);
+
+#ifdef CAN_REFERENCE_MAIN
+extern int main(int, char *argv[]);
+#endif
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len);
+#ifdef SYS__sysctl
+static int getentropy_sysctl(void *buf, size_t len);
+#endif
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+ int ret = -1;
+
+ if (len > 256) {
+ errno = EIO;
+ return -1;
+ }
+
+#ifdef SYS_getrandom
+ /* try to use getrandom syscall introduced with kernel 3.17 */
+ ret = syscall(SYS_getrandom, buf, len, 0);
+ if (ret != -1)
+ return (ret);
+#endif /* SYS_getrandom */
+
+ /*
+ * Try to get entropy with /dev/urandom
+ *
+ * This can fail if the process is inside a chroot or if file
+ * descriptors are exhausted.
+ */
+ ret = getentropy_urandom(buf, len);
+ if (ret != -1)
+ return (ret);
+
+#ifdef SYS__sysctl
+ /*
+ * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
+ * sysctl is a failsafe API, so it guarantees a result. This
+ * should work inside a chroot, or when file descriptors are
+ * exhuasted.
+ *
+ * However this can fail if the Linux kernel removes support
+ * for sysctl. Starting in 2007, there have been efforts to
+ * deprecate the sysctl API/ABI, and push callers towards use
+ * of the chroot-unavailable fd-using /proc mechanism --
+ * essentially the same problems as /dev/urandom.
+ *
+ * Numerous setbacks have been encountered in their deprecation
+ * schedule, so as of June 2014 the kernel ABI still exists on
+ * most Linux architectures. The sysctl() stub in libc is missing
+ * on some systems. There are also reports that some kernels
+ * spew messages to the console.
+ */
+ ret = getentropy_sysctl(buf, len);
+ if (ret != -1)
+ return (ret);
+#endif /* SYS__sysctl */
+
+ /*
+ * Entropy collection via /dev/urandom and sysctl have failed.
+ *
+ * No other API exists for collecting entropy. See the large
+ * comment block above.
+ *
+ * We have very few options:
+ * - Even syslog_r is unsafe to call at this low level, so
+ * there is no way to alert the user or program.
+ * - Cannot call abort() because some systems have unsafe
+ * corefiles.
+ * - Could raise(SIGKILL) resulting in silent program termination.
+ * - Return EIO, to hint that arc4random's stir function
+ * should raise(SIGKILL)
+ * - Do the best under the circumstances....
+ *
+ * This code path exists to bring light to the issue that Linux
+ * does not provide a failsafe API for entropy collection.
+ *
+ * We hope this demonstrates that Linux should either retain their
+ * sysctl ABI, or consider providing a new failsafe API which
+ * works in a chroot or when file descriptors are exhausted.
+ */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+ raise(SIGKILL);
+#endif
+ ret = getentropy_fallback(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ errno = EIO;
+ return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+ char any_set = 0;
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ any_set |= buf[i];
+ if (any_set == 0)
+ return -1;
+ return 0;
+}
+
+static int
+getentropy_urandom(void *buf, size_t len)
+{
+ struct stat st;
+ size_t i;
+ int fd, cnt, flags;
+ int save_errno = errno;
+
+start:
+
+ flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+ flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ fd = open("/dev/urandom", flags, 0);
+ if (fd == -1) {
+ if (errno == EINTR)
+ goto start;
+ goto nodevrandom;
+ }
+#ifndef O_CLOEXEC
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+ /* Lightly verify that the device node looks sane */
+ if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+ close(fd);
+ goto nodevrandom;
+ }
+ if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
+ close(fd);
+ goto nodevrandom;
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+ ssize_t ret = read(fd, (char*)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ close(fd);
+ goto nodevrandom;
+ }
+ i += ret;
+ }
+ close(fd);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+nodevrandom:
+ errno = EIO;
+ return -1;
+}
+
+#ifdef SYS__sysctl
+static int
+getentropy_sysctl(void *buf, size_t len)
+{
+ static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
+ size_t i;
+ int save_errno = errno;
+
+ for (i = 0; i < len; ) {
+ size_t chunk = min(len - i, 16);
+
+ /* SYS__sysctl because some systems already removed sysctl() */
+ struct __sysctl_args args = {
+ .name = mib,
+ .nlen = 3,
+ .oldval = buf + i,
+ .oldlenp = &chunk,
+ };
+ if (syscall(SYS__sysctl, &args) != 0)
+ goto sysctlfailed;
+ i += chunk;
+ }
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return (0); /* satisfied */
+ }
+sysctlfailed:
+ errno = EIO;
+ return -1;
+}
+#endif /* SYS__sysctl */
+
+static int cl[] = {
+ CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+ CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+ CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+ CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+ CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+ CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+ CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+ CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+ uint8_t results[SHA512_DIGEST_LENGTH];
+ int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+ static int cnt;
+ struct timespec ts;
+ struct timeval tv;
+ struct rusage ru;
+ sigset_t sigset;
+ struct stat st;
+ SHA512_CTX ctx;
+ static pid_t lastpid;
+ pid_t pid;
+ size_t i, ii, m;
+ char *p;
+
+ pid = getpid();
+ if (lastpid == pid) {
+ faster = 1;
+ repeat = 2;
+ } else {
+ faster = 0;
+ lastpid = pid;
+ repeat = REPEAT;
+ }
+ for (i = 0; i < len; ) {
+ int j;
+ SHA512_Init(&ctx);
+ for (j = 0; j < repeat; j++) {
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+ HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+ HX((pid = getpid()) == -1, pid);
+ HX((pid = getsid(pid)) == -1, pid);
+ HX((pid = getppid()) == -1, pid);
+ HX((pid = getpgid(0)) == -1, pid);
+ HX((e = getpriority(0, 0)) == -1, e);
+
+ if (!faster) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ (void) nanosleep(&ts, NULL);
+ }
+
+ HX(sigpending(&sigset) == -1, sigset);
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+#ifdef CAN_REFERENCE_MAIN
+ HF(main); /* an addr in program */
+#endif
+ HF(getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+ HD(p); /* an addr on stack */
+ p = (char *)&errno;
+ HD(p); /* the addr of errno */
+
+ if (i == 0) {
+ struct sockaddr_storage ss;
+ struct statvfs stvfs;
+ struct termios tios;
+ struct statfs stfs;
+ socklen_t ssl;
+ off_t off;
+
+ /*
+ * Prime-sized mappings encourage fragmentation;
+ * thus exposing some address entropy.
+ */
+ struct mm {
+ size_t npg;
+ void *p;
+ } mm[] = {
+ { 17, MAP_FAILED }, { 3, MAP_FAILED },
+ { 11, MAP_FAILED }, { 2, MAP_FAILED },
+ { 5, MAP_FAILED }, { 3, MAP_FAILED },
+ { 7, MAP_FAILED }, { 1, MAP_FAILED },
+ { 57, MAP_FAILED }, { 3, MAP_FAILED },
+ { 131, MAP_FAILED }, { 1, MAP_FAILED },
+ };
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ HX(mm[m].p = mmap(NULL,
+ mm[m].npg * pgs,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1,
+ (off_t)0), mm[m].p);
+ if (mm[m].p != MAP_FAILED) {
+ size_t mo;
+
+ /* Touch some memory... */
+ p = mm[m].p;
+ mo = cnt %
+ (mm[m].npg * pgs - 1);
+ p[mo] = 1;
+ cnt += (int)((long)(mm[m].p)
+ / pgs);
+ }
+
+ /* Check cnts and times... */
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+ ii++) {
+ HX((e = clock_gettime(cl[ii],
+ &ts)) == -1, ts);
+ if (e != -1)
+ cnt += (int)ts.tv_nsec;
+ }
+
+ HX((e = getrusage(RUSAGE_SELF,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ }
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ if (mm[m].p != MAP_FAILED)
+ munmap(mm[m].p, mm[m].npg * pgs);
+ mm[m].p = MAP_FAILED;
+ }
+
+ HX(stat(".", &st) == -1, st);
+ HX(statvfs(".", &stvfs) == -1, stvfs);
+ HX(statfs(".", &stfs) == -1, stfs);
+
+ HX(stat("/", &st) == -1, st);
+ HX(statvfs("/", &stvfs) == -1, stvfs);
+ HX(statfs("/", &stfs) == -1, stfs);
+
+ HX((e = fstat(0, &st)) == -1, st);
+ if (e == -1) {
+ if (S_ISREG(st.st_mode) ||
+ S_ISFIFO(st.st_mode) ||
+ S_ISSOCK(st.st_mode)) {
+ HX(fstatvfs(0, &stvfs) == -1,
+ stvfs);
+ HX(fstatfs(0, &stfs) == -1,
+ stfs);
+ HX((off = lseek(0, (off_t)0,
+ SEEK_CUR)) < 0, off);
+ }
+ if (S_ISCHR(st.st_mode)) {
+ HX(tcgetattr(0, &tios) == -1,
+ tios);
+ } else if (S_ISSOCK(st.st_mode)) {
+ memset(&ss, 0, sizeof ss);
+ ssl = sizeof(ss);
+ HX(getpeername(0,
+ (void *)&ss, &ssl) == -1,
+ ss);
+ }
+ }
+
+ HX((e = getrusage(RUSAGE_CHILDREN,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ } else {
+ /* Subsequent hashes absorb previous result */
+ HD(results);
+ }
+
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ HD(cnt);
+ }
+#ifdef HAVE_GETAUXVAL
+# ifdef AT_RANDOM
+ /* Not as random as you think but we take what we are given */
+ p = (char *) getauxval(AT_RANDOM);
+ if (p)
+ HR(p, 16);
+# endif
+# ifdef AT_SYSINFO_EHDR
+ p = (char *) getauxval(AT_SYSINFO_EHDR);
+ if (p)
+ HR(p, pgs);
+# endif
+# ifdef AT_BASE
+ p = (char *) getauxval(AT_BASE);
+ if (p)
+ HD(p);
+# endif
+#endif /* HAVE_GETAUXVAL */
+
+ SHA512_Final(results, &ctx);
+ memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+ memset(results, 0, sizeof results);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+ errno = EIO;
+ return -1;
+}
diff --git a/contrib/unbound/compat/getentropy_osx.c b/contrib/unbound/compat/getentropy_osx.c
new file mode 100644
index 0000000..d5a64ab
--- /dev/null
+++ b/contrib/unbound/compat/getentropy_osx.c
@@ -0,0 +1,432 @@
+/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+ * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+#include <sys/statvfs.h>
+#include <sys/socket.h>
+#include <sys/mount.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <mach/mach_time.h>
+#include <mach/mach_host.h>
+#include <mach/host_info.h>
+#include <sys/socketvar.h>
+#include <sys/vmmeter.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+#include <CommonCrypto/CommonDigest.h>
+#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
+#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
+#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy)))
+#define SHA512_CTX CC_SHA512_CTX
+#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+ do { \
+ if ((a)) \
+ HD(errno); \
+ else \
+ HD(b); \
+ } while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int getentropy(void *buf, size_t len);
+
+#ifdef CAN_REFERENCE_MAIN
+extern int main(int, char *argv[]);
+#endif
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len);
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+ int ret = -1;
+
+ if (len > 256) {
+ errno = EIO;
+ return -1;
+ }
+
+ /*
+ * Try to get entropy with /dev/urandom
+ *
+ * This can fail if the process is inside a chroot or if file
+ * descriptors are exhausted.
+ */
+ ret = getentropy_urandom(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ /*
+ * Entropy collection via /dev/urandom and sysctl have failed.
+ *
+ * No other API exists for collecting entropy, and we have
+ * no failsafe way to get it on OSX that is not sensitive
+ * to resource exhaustion.
+ *
+ * We have very few options:
+ * - Even syslog_r is unsafe to call at this low level, so
+ * there is no way to alert the user or program.
+ * - Cannot call abort() because some systems have unsafe
+ * corefiles.
+ * - Could raise(SIGKILL) resulting in silent program termination.
+ * - Return EIO, to hint that arc4random's stir function
+ * should raise(SIGKILL)
+ * - Do the best under the circumstances....
+ *
+ * This code path exists to bring light to the issue that OSX
+ * does not provide a failsafe API for entropy collection.
+ *
+ * We hope this demonstrates that OSX should consider
+ * providing a new failsafe API which works in a chroot or
+ * when file descriptors are exhausted.
+ */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+ raise(SIGKILL);
+#endif
+ ret = getentropy_fallback(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ errno = EIO;
+ return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+ char any_set = 0;
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ any_set |= buf[i];
+ if (any_set == 0)
+ return -1;
+ return 0;
+}
+
+static int
+getentropy_urandom(void *buf, size_t len)
+{
+ struct stat st;
+ size_t i;
+ int fd, flags;
+ int save_errno = errno;
+
+start:
+
+ flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+ flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ fd = open("/dev/urandom", flags, 0);
+ if (fd == -1) {
+ if (errno == EINTR)
+ goto start;
+ goto nodevrandom;
+ }
+#ifndef O_CLOEXEC
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+ /* Lightly verify that the device node looks sane */
+ if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
+ close(fd);
+ goto nodevrandom;
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+ ssize_t ret = read(fd, (char*)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ close(fd);
+ goto nodevrandom;
+ }
+ i += ret;
+ }
+ close(fd);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+nodevrandom:
+ errno = EIO;
+ return -1;
+}
+
+static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
+static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
+static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
+static int kmib[] = { CTL_KERN, KERN_USRSTACK };
+static int hwmib[] = { CTL_HW, HW_USERMEM };
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+ uint8_t results[SHA512_DIGEST_LENGTH];
+ int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+ static int cnt;
+ struct timespec ts;
+ struct timeval tv;
+ struct rusage ru;
+ sigset_t sigset;
+ struct stat st;
+ SHA512_CTX ctx;
+ static pid_t lastpid;
+ pid_t pid;
+ size_t i, ii, m;
+ char *p;
+ struct tcpstat tcpstat;
+ struct udpstat udpstat;
+ struct ipstat ipstat;
+ u_int64_t mach_time;
+ unsigned int idata;
+ void *addr;
+
+ pid = getpid();
+ if (lastpid == pid) {
+ faster = 1;
+ repeat = 2;
+ } else {
+ faster = 0;
+ lastpid = pid;
+ repeat = REPEAT;
+ }
+ for (i = 0; i < len; ) {
+ int j;
+ SHA512_Init(&ctx);
+ for (j = 0; j < repeat; j++) {
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ mach_time = mach_absolute_time();
+ HD(mach_time);
+
+ ii = sizeof(addr);
+ HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
+ &addr, &ii, NULL, 0) == -1, addr);
+
+ ii = sizeof(idata);
+ HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
+ &idata, &ii, NULL, 0) == -1, idata);
+
+ ii = sizeof(tcpstat);
+ HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
+ &tcpstat, &ii, NULL, 0) == -1, tcpstat);
+
+ ii = sizeof(udpstat);
+ HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
+ &udpstat, &ii, NULL, 0) == -1, udpstat);
+
+ ii = sizeof(ipstat);
+ HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
+ &ipstat, &ii, NULL, 0) == -1, ipstat);
+
+ HX((pid = getpid()) == -1, pid);
+ HX((pid = getsid(pid)) == -1, pid);
+ HX((pid = getppid()) == -1, pid);
+ HX((pid = getpgid(0)) == -1, pid);
+ HX((e = getpriority(0, 0)) == -1, e);
+
+ if (!faster) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ (void) nanosleep(&ts, NULL);
+ }
+
+ HX(sigpending(&sigset) == -1, sigset);
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+#ifdef CAN_REFERENCE_MAIN
+ HF(main); /* an addr in program */
+#endif
+ HF(getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+ HD(p); /* an addr on stack */
+ p = (char *)&errno;
+ HD(p); /* the addr of errno */
+
+ if (i == 0) {
+ struct sockaddr_storage ss;
+ struct statvfs stvfs;
+ struct termios tios;
+ struct statfs stfs;
+ socklen_t ssl;
+ off_t off;
+
+ /*
+ * Prime-sized mappings encourage fragmentation;
+ * thus exposing some address entropy.
+ */
+ struct mm {
+ size_t npg;
+ void *p;
+ } mm[] = {
+ { 17, MAP_FAILED }, { 3, MAP_FAILED },
+ { 11, MAP_FAILED }, { 2, MAP_FAILED },
+ { 5, MAP_FAILED }, { 3, MAP_FAILED },
+ { 7, MAP_FAILED }, { 1, MAP_FAILED },
+ { 57, MAP_FAILED }, { 3, MAP_FAILED },
+ { 131, MAP_FAILED }, { 1, MAP_FAILED },
+ };
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ HX(mm[m].p = mmap(NULL,
+ mm[m].npg * pgs,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1,
+ (off_t)0), mm[m].p);
+ if (mm[m].p != MAP_FAILED) {
+ size_t mo;
+
+ /* Touch some memory... */
+ p = mm[m].p;
+ mo = cnt %
+ (mm[m].npg * pgs - 1);
+ p[mo] = 1;
+ cnt += (int)((long)(mm[m].p)
+ / pgs);
+ }
+
+ /* Check cnts and times... */
+ mach_time = mach_absolute_time();
+ HD(mach_time);
+ cnt += (int)mach_time;
+
+ HX((e = getrusage(RUSAGE_SELF,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ }
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ if (mm[m].p != MAP_FAILED)
+ munmap(mm[m].p, mm[m].npg * pgs);
+ mm[m].p = MAP_FAILED;
+ }
+
+ HX(stat(".", &st) == -1, st);
+ HX(statvfs(".", &stvfs) == -1, stvfs);
+ HX(statfs(".", &stfs) == -1, stfs);
+
+ HX(stat("/", &st) == -1, st);
+ HX(statvfs("/", &stvfs) == -1, stvfs);
+ HX(statfs("/", &stfs) == -1, stfs);
+
+ HX((e = fstat(0, &st)) == -1, st);
+ if (e == -1) {
+ if (S_ISREG(st.st_mode) ||
+ S_ISFIFO(st.st_mode) ||
+ S_ISSOCK(st.st_mode)) {
+ HX(fstatvfs(0, &stvfs) == -1,
+ stvfs);
+ HX(fstatfs(0, &stfs) == -1,
+ stfs);
+ HX((off = lseek(0, (off_t)0,
+ SEEK_CUR)) < 0, off);
+ }
+ if (S_ISCHR(st.st_mode)) {
+ HX(tcgetattr(0, &tios) == -1,
+ tios);
+ } else if (S_ISSOCK(st.st_mode)) {
+ memset(&ss, 0, sizeof ss);
+ ssl = sizeof(ss);
+ HX(getpeername(0,
+ (void *)&ss, &ssl) == -1,
+ ss);
+ }
+ }
+
+ HX((e = getrusage(RUSAGE_CHILDREN,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ } else {
+ /* Subsequent hashes absorb previous result */
+ HD(results);
+ }
+
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ HD(cnt);
+ }
+
+ SHA512_Final(results, &ctx);
+ memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+ memset(results, 0, sizeof results);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+ errno = EIO;
+ return -1;
+}
diff --git a/contrib/unbound/compat/getentropy_solaris.c b/contrib/unbound/compat/getentropy_solaris.c
new file mode 100644
index 0000000..8389573
--- /dev/null
+++ b/contrib/unbound/compat/getentropy_solaris.c
@@ -0,0 +1,435 @@
+/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+ * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/statvfs.h>
+#include <sys/socket.h>
+#include <sys/mount.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/sha2.h>
+#define SHA512_Init SHA512Init
+#define SHA512_Update SHA512Update
+#define SHA512_Final SHA512Final
+
+#include <sys/vfs.h>
+#include <sys/statfs.h>
+#include <sys/loadavg.h>
+
+#define REPEAT 5
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define HX(a, b) \
+ do { \
+ if ((a)) \
+ HD(errno); \
+ else \
+ HD(b); \
+ } while (0)
+
+#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+
+int getentropy(void *buf, size_t len);
+
+#ifdef CAN_REFERENCE_MAIN
+extern int main(int, char *argv[]);
+#endif
+static int gotdata(char *buf, size_t len);
+static int getentropy_urandom(void *buf, size_t len, const char *path,
+ int devfscheck);
+static int getentropy_fallback(void *buf, size_t len);
+
+int
+getentropy(void *buf, size_t len)
+{
+ int ret = -1;
+
+ if (len > 256) {
+ errno = EIO;
+ return -1;
+ }
+
+ /*
+ * Try to get entropy with /dev/urandom
+ *
+ * Solaris provides /dev/urandom as a symbolic link to
+ * /devices/pseudo/random@0:urandom which is provided by
+ * a devfs filesystem. Best practice is to use O_NOFOLLOW,
+ * so we must try the unpublished name directly.
+ *
+ * This can fail if the process is inside a chroot which lacks
+ * the devfs mount, or if file descriptors are exhausted.
+ */
+ ret = getentropy_urandom(buf, len,
+ "/devices/pseudo/random@0:urandom", 1);
+ if (ret != -1)
+ return (ret);
+
+ /*
+ * Unfortunately, chroot spaces on Solaris are sometimes setup
+ * with direct device node of the well-known /dev/urandom name
+ * (perhaps to avoid dragging all of devfs into the space).
+ *
+ * This can fail if the process is inside a chroot or if file
+ * descriptors are exhausted.
+ */
+ ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
+ if (ret != -1)
+ return (ret);
+
+ /*
+ * Entropy collection via /dev/urandom has failed.
+ *
+ * No other API exists for collecting entropy, and we have
+ * no failsafe way to get it on Solaris that is not sensitive
+ * to resource exhaustion.
+ *
+ * We have very few options:
+ * - Even syslog_r is unsafe to call at this low level, so
+ * there is no way to alert the user or program.
+ * - Cannot call abort() because some systems have unsafe
+ * corefiles.
+ * - Could raise(SIGKILL) resulting in silent program termination.
+ * - Return EIO, to hint that arc4random's stir function
+ * should raise(SIGKILL)
+ * - Do the best under the circumstances....
+ *
+ * This code path exists to bring light to the issue that Solaris
+ * does not provide a failsafe API for entropy collection.
+ *
+ * We hope this demonstrates that Solaris should consider
+ * providing a new failsafe API which works in a chroot or
+ * when file descriptors are exhausted.
+ */
+#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
+#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
+ raise(SIGKILL);
+#endif
+ ret = getentropy_fallback(buf, len);
+ if (ret != -1)
+ return (ret);
+
+ errno = EIO;
+ return (ret);
+}
+
+/*
+ * Basic sanity checking; wish we could do better.
+ */
+static int
+gotdata(char *buf, size_t len)
+{
+ char any_set = 0;
+ size_t i;
+
+ for (i = 0; i < len; ++i)
+ any_set |= buf[i];
+ if (any_set == 0)
+ return -1;
+ return 0;
+}
+
+static int
+getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
+{
+ struct stat st;
+ size_t i;
+ int fd, flags;
+ int save_errno = errno;
+
+start:
+
+ flags = O_RDONLY;
+#ifdef O_NOFOLLOW
+ flags |= O_NOFOLLOW;
+#endif
+#ifdef O_CLOEXEC
+ flags |= O_CLOEXEC;
+#endif
+ fd = open(path, flags, 0);
+ if (fd == -1) {
+ if (errno == EINTR)
+ goto start;
+ goto nodevrandom;
+ }
+#ifndef O_CLOEXEC
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+#endif
+
+ /* Lightly verify that the device node looks sane */
+ if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode) ||
+ (devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) {
+ close(fd);
+ goto nodevrandom;
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+ ssize_t ret = read(fd, (char*)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ close(fd);
+ goto nodevrandom;
+ }
+ i += ret;
+ }
+ close(fd);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+nodevrandom:
+ errno = EIO;
+ return -1;
+}
+
+static const int cl[] = {
+ CLOCK_REALTIME,
+#ifdef CLOCK_MONOTONIC
+ CLOCK_MONOTONIC,
+#endif
+#ifdef CLOCK_MONOTONIC_RAW
+ CLOCK_MONOTONIC_RAW,
+#endif
+#ifdef CLOCK_TAI
+ CLOCK_TAI,
+#endif
+#ifdef CLOCK_VIRTUAL
+ CLOCK_VIRTUAL,
+#endif
+#ifdef CLOCK_UPTIME
+ CLOCK_UPTIME,
+#endif
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+ CLOCK_PROCESS_CPUTIME_ID,
+#endif
+#ifdef CLOCK_THREAD_CPUTIME_ID
+ CLOCK_THREAD_CPUTIME_ID,
+#endif
+};
+
+static int
+getentropy_fallback(void *buf, size_t len)
+{
+ uint8_t results[SHA512_DIGEST_LENGTH];
+ int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
+ static int cnt;
+ struct timespec ts;
+ struct timeval tv;
+ double loadavg[3];
+ struct rusage ru;
+ sigset_t sigset;
+ struct stat st;
+ SHA512_CTX ctx;
+ static pid_t lastpid;
+ pid_t pid;
+ size_t i, ii, m;
+ char *p;
+
+ pid = getpid();
+ if (lastpid == pid) {
+ faster = 1;
+ repeat = 2;
+ } else {
+ faster = 0;
+ lastpid = pid;
+ repeat = REPEAT;
+ }
+ for (i = 0; i < len; ) {
+ int j;
+ SHA512_Init(&ctx);
+ for (j = 0; j < repeat; j++) {
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+ HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+ HX((pid = getpid()) == -1, pid);
+ HX((pid = getsid(pid)) == -1, pid);
+ HX((pid = getppid()) == -1, pid);
+ HX((pid = getpgid(0)) == -1, pid);
+ HX((e = getpriority(0, 0)) == -1, e);
+ HX((getloadavg(loadavg, 3) == -1), loadavg);
+
+ if (!faster) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+ (void) nanosleep(&ts, NULL);
+ }
+
+ HX(sigpending(&sigset) == -1, sigset);
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+#ifdef CAN_REFERENCE_MAIN
+ HF(main); /* an addr in program */
+#endif
+ HF(getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+ HD(p); /* an addr on stack */
+ p = (char *)&errno;
+ HD(p); /* the addr of errno */
+
+ if (i == 0) {
+ struct sockaddr_storage ss;
+ struct statvfs stvfs;
+ struct termios tios;
+ socklen_t ssl;
+ off_t off;
+
+ /*
+ * Prime-sized mappings encourage fragmentation;
+ * thus exposing some address entropy.
+ */
+ struct mm {
+ size_t npg;
+ void *p;
+ } mm[] = {
+ { 17, MAP_FAILED }, { 3, MAP_FAILED },
+ { 11, MAP_FAILED }, { 2, MAP_FAILED },
+ { 5, MAP_FAILED }, { 3, MAP_FAILED },
+ { 7, MAP_FAILED }, { 1, MAP_FAILED },
+ { 57, MAP_FAILED }, { 3, MAP_FAILED },
+ { 131, MAP_FAILED }, { 1, MAP_FAILED },
+ };
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ HX(mm[m].p = mmap(NULL,
+ mm[m].npg * pgs,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1,
+ (off_t)0), mm[m].p);
+ if (mm[m].p != MAP_FAILED) {
+ size_t mo;
+
+ /* Touch some memory... */
+ p = mm[m].p;
+ mo = cnt %
+ (mm[m].npg * pgs - 1);
+ p[mo] = 1;
+ cnt += (int)((long)(mm[m].p)
+ / pgs);
+ }
+
+ /* Check cnts and times... */
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
+ ii++) {
+ HX((e = clock_gettime(cl[ii],
+ &ts)) == -1, ts);
+ if (e != -1)
+ cnt += (int)ts.tv_nsec;
+ }
+
+ HX((e = getrusage(RUSAGE_SELF,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ }
+
+ for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
+ if (mm[m].p != MAP_FAILED)
+ munmap(mm[m].p, mm[m].npg * pgs);
+ mm[m].p = MAP_FAILED;
+ }
+
+ HX(stat(".", &st) == -1, st);
+ HX(statvfs(".", &stvfs) == -1, stvfs);
+
+ HX(stat("/", &st) == -1, st);
+ HX(statvfs("/", &stvfs) == -1, stvfs);
+
+ HX((e = fstat(0, &st)) == -1, st);
+ if (e == -1) {
+ if (S_ISREG(st.st_mode) ||
+ S_ISFIFO(st.st_mode) ||
+ S_ISSOCK(st.st_mode)) {
+ HX(fstatvfs(0, &stvfs) == -1,
+ stvfs);
+ HX((off = lseek(0, (off_t)0,
+ SEEK_CUR)) < 0, off);
+ }
+ if (S_ISCHR(st.st_mode)) {
+ HX(tcgetattr(0, &tios) == -1,
+ tios);
+ } else if (S_ISSOCK(st.st_mode)) {
+ memset(&ss, 0, sizeof ss);
+ ssl = sizeof(ss);
+ HX(getpeername(0,
+ (void *)&ss, &ssl) == -1,
+ ss);
+ }
+ }
+
+ HX((e = getrusage(RUSAGE_CHILDREN,
+ &ru)) == -1, ru);
+ if (e != -1) {
+ cnt += (int)ru.ru_utime.tv_sec;
+ cnt += (int)ru.ru_utime.tv_usec;
+ }
+ } else {
+ /* Subsequent hashes absorb previous result */
+ HD(results);
+ }
+
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+ cnt += (int)tv.tv_sec;
+ cnt += (int)tv.tv_usec;
+ }
+
+ HD(cnt);
+ }
+ SHA512_Final(results, &ctx);
+ memcpy((char*)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+ memset(results, 0, sizeof results);
+ if (gotdata(buf, len) == 0) {
+ errno = save_errno;
+ return 0; /* satisfied */
+ }
+ errno = EIO;
+ return -1;
+}
diff --git a/contrib/unbound/compat/getentropy_win.c b/contrib/unbound/compat/getentropy_win.c
new file mode 100644
index 0000000..71fb955
--- /dev/null
+++ b/contrib/unbound/compat/getentropy_win.c
@@ -0,0 +1,56 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+ * Copyright (c) 2014, Bob Beck <beck@obtuse.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <windows.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <wincrypt.h>
+#include <process.h>
+
+int getentropy(void *buf, size_t len);
+
+/*
+ * On Windows, CryptGenRandom is supposed to be a well-seeded
+ * cryptographically strong random number generator.
+ */
+int
+getentropy(void *buf, size_t len)
+{
+ HCRYPTPROV provider;
+
+ if (len > 256) {
+ errno = EIO;
+ return -1;
+ }
+
+ if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT) == 0)
+ goto fail;
+ if (CryptGenRandom(provider, len, buf) == 0) {
+ CryptReleaseContext(provider, 0);
+ goto fail;
+ }
+ CryptReleaseContext(provider, 0);
+ return (0);
+
+fail:
+ errno = EIO;
+ return (-1);
+}
diff --git a/contrib/unbound/compat/inet_aton.c b/contrib/unbound/compat/inet_aton.c
index 33c323d..e93fe8d 100644
--- a/contrib/unbound/compat/inet_aton.c
+++ b/contrib/unbound/compat/inet_aton.c
@@ -103,7 +103,7 @@ inet_aton(const char *cp, struct in_addr *addr)
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
- if (!isdigit(c))
+ if (!isdigit((unsigned char)c))
return (0);
val = 0; base = 10;
if (c == '0') {
@@ -114,12 +114,12 @@ inet_aton(const char *cp, struct in_addr *addr)
base = 8;
}
for (;;) {
- if (isascii(c) && isdigit(c)) {
+ if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
val = (val * base) + (c - '0');
c = *++cp;
- } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ } else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
val = (val << 4) |
- (c + 10 - (islower(c) ? 'a' : 'A'));
+ (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
c = *++cp;
} else
break;
@@ -141,7 +141,7 @@ inet_aton(const char *cp, struct in_addr *addr)
/*
* Check for trailing characters.
*/
- if (c != '\0' && (!isascii(c) || !isspace(c)))
+ if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
return (0);
/*
* Concoct the address according to
diff --git a/contrib/unbound/compat/memmove.c b/contrib/unbound/compat/memmove.c
index 0035bbf..fe319bb 100644
--- a/contrib/unbound/compat/memmove.c
+++ b/contrib/unbound/compat/memmove.c
@@ -28,7 +28,7 @@ void *memmove(void *dest, const void *src, size_t n)
to[i] = from[i];
return dest;
}
- if (from > to && from-to < (int)n) {
+ if (from > to && from-to < (int)n) {
/* to overlaps with from */
/* <from......> */
/* <to........> */
diff --git a/contrib/unbound/compat/sha512.c b/contrib/unbound/compat/sha512.c
new file mode 100644
index 0000000..ac046ab
--- /dev/null
+++ b/contrib/unbound/compat/sha512.c
@@ -0,0 +1,477 @@
+/*
+ * FILE: sha2.c
+ * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Modified by Jelte Jansen to fit in ldns, and not clash with any
+ * system-defined SHA code.
+ * Changes:
+ * - Renamed (external) functions and constants to fit ldns style
+ * - Removed _End and _Data functions
+ * - Added ldns_shaX(data, len, digest) convenience functions
+ * - Removed prototypes of _Transform functions and made those static
+ * Modified by Wouter, and trimmed, to provide SHA512 for getentropy_fallback.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+#include "config.h"
+
+#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
+#include <assert.h> /* assert() */
+
+/* do we have sha512 header defs */
+#ifndef SHA512_DIGEST_LENGTH
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+typedef struct _SHA512_CTX {
+ uint64_t state[8];
+ uint64_t bitcount[2];
+ uint8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+#endif /* do we have sha512 header defs */
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, void*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+unsigned char *SHA512(void *data, unsigned int data_len, unsigned char *digest);
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER. If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ * #define LITTLE_ENDIAN 1234
+ * #define BIG_ENDIAN 4321
+ *
+ * And for little-endian machines, add:
+ *
+ * #define BYTE_ORDER LITTLE_ENDIAN
+ *
+ * Or for big-endian machines:
+ *
+ * #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+typedef uint8_t sha2_byte; /* Exactly 1 byte */
+typedef uint32_t sha2_word32; /* Exactly 4 bytes */
+#ifdef S_SPLINT_S
+typedef unsigned long long sha2_word64; /* lint 8 bytes */
+#else
+typedef uint64_t sha2_word64; /* Exactly 8 bytes */
+#endif
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+ sha2_word32 tmp = (w); \
+ tmp = (tmp >> 16) | (tmp << 16); \
+ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#ifndef S_SPLINT_S
+#define REVERSE64(w,x) { \
+ sha2_word64 tmp = (w); \
+ tmp = (tmp >> 32) | (tmp << 32); \
+ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+ ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#else /* splint */
+#define REVERSE64(w,x) /* splint */
+#endif /* splint */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) { \
+ (w)[0] += (sha2_word64)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
+}
+#ifdef S_SPLINT_S
+#undef ADDINC128
+#define ADDINC128(w,n) /* splint */
+#endif
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory. Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define SHA2_USE_MEMSET_MEMCPY 1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l) memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l) bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
+ * S is a ROTATION) because the SHA-256/384/512 description document
+ * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ * same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x) ((x) >> (b))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
+#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const sha2_word64 K512[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* initial hash value H for SHA-512 */
+static const sha2_word64 sha512_initial_hash_value[8] = {
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
+};
+
+typedef union _ldns_sha2_buffer_union {
+ uint8_t* theChars;
+ uint64_t* theLongs;
+} ldns_sha2_buffer_union;
+
+/*** SHA-512: *********************************************************/
+void SHA512_Init(SHA512_CTX* context) {
+ if (context == (SHA512_CTX*)0) {
+ return;
+ }
+ MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+static void SHA512_Transform(SHA512_CTX* context,
+ const sha2_word64* data) {
+ sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
+ int j;
+
+ /* initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert TO host byte order */
+ REVERSE64(*data++, W512[j]);
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* Apply the SHA-512 compression function to update a..h with copy */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W512[(j+1)&0x0f];
+ s0 = sigma0_512(s0);
+ s1 = W512[(j+14)&0x0f];
+ s1 = sigma1_512(s1);
+
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+void SHA512_Update(SHA512_CTX* context, void *datain, size_t len) {
+ size_t freespace, usedspace;
+ const sha2_byte* data = (const sha2_byte*)datain;
+
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+ ADDINC128(context->bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+ ADDINC128(context->bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA512_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA512_Transform(context, (sha2_word64*)data);
+ ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+ len -= SHA512_BLOCK_LENGTH;
+ data += SHA512_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->buffer, data, len);
+ ADDINC128(context->bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+static void SHA512_Last(SHA512_CTX* context) {
+ size_t usedspace;
+ ldns_sha2_buffer_union cast_var;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->bitcount[0],context->bitcount[0]);
+ REVERSE64(context->bitcount[1],context->bitcount[1]);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA512_BLOCK_LENGTH) {
+ MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+ }
+ } else {
+ /* Prepare for final transform: */
+ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ cast_var.theChars = context->buffer;
+ cast_var.theLongs[SHA512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
+ cast_var.theLongs[SHA512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
+
+ /* final transform: */
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+}
+
+void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+ sha2_word64 *d = (sha2_word64*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA512_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha2_byte*)0) {
+ SHA512_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < 8; j++) {
+ REVERSE64(context->state[j],context->state[j]);
+ *d++ = context->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Zero out state data */
+ MEMSET_BZERO(context, sizeof(SHA512_CTX));
+}
+
+unsigned char *
+SHA512(void *data, unsigned int data_len, unsigned char *digest)
+{
+ SHA512_CTX ctx;
+ SHA512_Init(&ctx);
+ SHA512_Update(&ctx, data, data_len);
+ SHA512_Final(digest, &ctx);
+ return digest;
+}
diff --git a/contrib/unbound/compat/strptime.c b/contrib/unbound/compat/strptime.c
index 9a0caa5..10ec315 100644
--- a/contrib/unbound/compat/strptime.c
+++ b/contrib/unbound/compat/strptime.c
@@ -89,7 +89,7 @@ str2int(const char **buf, int max)
{
int ret=0, count=0;
- while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
+ while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
ret = ret*10 + (*buf[0] - '0');
(*buf)++;
count++;
@@ -111,11 +111,11 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
while ((c = *format) != '\0') {
/* whitespace, literal or format */
- if (isspace(c)) { /* whitespace */
+ if (isspace((unsigned char)c)) { /* whitespace */
/** whitespace matches zero or more whitespace characters in the
* input string.
**/
- while (isspace(*s))
+ while (isspace((unsigned char)*s))
s++;
}
else if (c == '%') { /* format */
@@ -221,7 +221,7 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
break;
case 'n': /* arbitrary whitespace */
case 't':
- while (isspace(*s))
+ while (isspace((unsigned char)*s))
s++;
break;
case 'p': /* am pm */
OpenPOWER on IntegriCloud