diff options
Diffstat (limited to 'external/unbound/compat/arc4random.c')
-rw-r--r-- | external/unbound/compat/arc4random.c | 236 |
1 files changed, 0 insertions, 236 deletions
diff --git a/external/unbound/compat/arc4random.c b/external/unbound/compat/arc4random.c deleted file mode 100644 index a09665c5d..000000000 --- a/external/unbound/compat/arc4random.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $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> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif -#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__ */ -#ifndef MAP_ANON -#define MAP_ANON MAP_ANONYMOUS -#endif - -#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(); -} |