diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2020-01-09 14:24:09 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2020-01-09 14:24:09 +0000 |
commit | 2a3120725f4d4b08fb2361463775f11844321eb0 (patch) | |
tree | 1b6c8acf0ef749edc94a5aef1f3d5c446e25cd86 | |
parent | eb9c1a6d4fbdf515e788e2506c32a2993bbff6cd (diff) |
Replace entropy.c, random.c and an outdated arc4random copy with
calls to libc's arc4random. Minus about 3k lines.
prodding deraadt@
38 files changed, 123 insertions, 2923 deletions
diff --git a/usr.sbin/bind/bin/dig/dighost.c b/usr.sbin/bind/bin/dig/dighost.c index 9532869d9c4..4e2928dbda0 100644 --- a/usr.sbin/bind/bin/dig/dighost.c +++ b/usr.sbin/bind/bin/dig/dighost.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.27 2020/01/09 14:19:49 florian Exp $ */ +/* $Id: dighost.c,v 1.28 2020/01/09 14:24:07 florian Exp $ */ /*! \file * \note @@ -43,7 +43,7 @@ #include <dns/ds.h> #include <dns/master.h> #include <dns/nsec.h> -#include <isc/random.h> + #include <ctype.h> #endif #include <dns/fixedname.h> @@ -65,7 +65,7 @@ #include <isc/app.h> #include <isc/base64.h> -#include <isc/entropy.h> + #include <isc/file.h> #include <isc/hex.h> #include <isc/lang.h> @@ -74,7 +74,7 @@ #include <isc/netdb.h> #include <isc/parseint.h> -#include <isc/random.h> + #include <isc/result.h> #include <isc/safe.h> #include <isc/serial.h> @@ -165,7 +165,6 @@ unsigned int digestbits = 0; isc_buffer_t *namebuf = NULL; dns_tsigkey_t *tsigkey = NULL; isc_boolean_t validated = ISC_TRUE; -isc_entropy_t *entp = NULL; isc_mempool_t *commctx = NULL; isc_boolean_t debugging = ISC_FALSE; isc_boolean_t debugtiming = ISC_FALSE; @@ -1424,7 +1423,6 @@ void setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { dig_searchlist_t *domain = NULL; lwres_result_t lwresult; - isc_result_t result; debug("setup_system()"); @@ -1505,10 +1503,7 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { #endif #endif - result = isc_entropy_getdata(entp, cookie_secret, - sizeof(cookie_secret), NULL, 0); - if (result != ISC_R_SUCCESS) - fatal("unable to generate cookie secret"); + arc4random_buf(cookie_secret, sizeof(cookie_secret)); } /*% @@ -1574,10 +1569,9 @@ setup_libs(void) { result = isc_socketmgr_create(mctx, &socketmgr); check_result(result, "isc_socketmgr_create"); - result = isc_entropy_create(mctx, &entp); check_result(result, "isc_entropy_create"); - result = dst_lib_init(mctx, entp, 0); + result = dst_lib_init(mctx); check_result(result, "dst_lib_init"); is_dst_up = ISC_TRUE; @@ -2145,8 +2139,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) srv != NULL; srv = ISC_LIST_HEAD(lookup->my_server_list)) { INSIST(i > 0); - isc_random_get(&j); - j %= i; + j = arc4random_uniform(i); next = ISC_LIST_NEXT(srv, link); while (j-- > 0 && next != NULL) { srv = next; @@ -2434,7 +2427,7 @@ setup_lookup(dig_lookup_t *lookup) { dighost_trying(store, lookup); INSIST(dns_name_isabsolute(lookup->name)); - isc_random_get(&id); + id = arc4random(); lookup->sendmsg->id = (unsigned short)id & 0xFFFF; lookup->sendmsg->opcode = lookup->opcode; lookup->msgcounter = 0; @@ -4394,10 +4387,6 @@ destroy_libs(void) { dst_lib_destroy(); is_dst_up = ISC_FALSE; } - if (entp != NULL) { - debug("detach from entropy"); - isc_entropy_detach(&entp); - } UNLOCK_LOOKUP; DESTROYLOCK(&lookup_lock); diff --git a/usr.sbin/bind/lib/dns/acache.c b/usr.sbin/bind/lib/dns/acache.c index 3244385877a..8eb17cd154a 100644 --- a/usr.sbin/bind/lib/dns/acache.c +++ b/usr.sbin/bind/lib/dns/acache.c @@ -14,9 +14,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acache.c,v 1.3 2019/12/17 01:46:31 sthen Exp $ */ +/* $Id: acache.c,v 1.4 2020/01/09 14:24:07 florian Exp $ */ #include <config.h> +#include <stdlib.h> #include <isc/atomic.h> #include <isc/event.h> @@ -25,7 +26,7 @@ #include <isc/mem.h> #include <isc/mutex.h> #include <isc/platform.h> -#include <isc/random.h> + #include <isc/refcount.h> #include <isc/rwlock.h> #include <isc/serial.h> @@ -808,7 +809,7 @@ entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, if (passed > interval / 2) return (ISC_TRUE); - isc_random_get(&val); + val = arc4random(); if (passed > interval / 4) return (ISC_TF(val % 4 == 0)); return (ISC_TF(val % 8 == 0)); @@ -1396,7 +1397,6 @@ dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, { dns_acacheentry_t *newentry; isc_result_t result; - isc_uint32_t r; isc_stdtime_t tmptime; REQUIRE(DNS_ACACHE_VALID(acache)); @@ -1426,8 +1426,8 @@ dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, return (ISC_R_NOMEMORY); } - isc_random_get(&r); - newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT; + + newentry->locknum = arc4random_uniform(DEFAULT_ACACHE_ENTRY_LOCK_COUNT); result = isc_refcount_init(&newentry->references, 1); if (result != ISC_R_SUCCESS) { diff --git a/usr.sbin/bind/lib/dns/adb.c b/usr.sbin/bind/lib/dns/adb.c index 97db279e7ff..ebfa7e1bde8 100644 --- a/usr.sbin/bind/lib/dns/adb.c +++ b/usr.sbin/bind/lib/dns/adb.c @@ -26,11 +26,12 @@ #include <config.h> #include <limits.h> +#include <stdlib.h> #include <isc/mutexblock.h> #include <isc/netaddr.h> -#include <isc/random.h> + #include <isc/stats.h> #include <isc/string.h> /* Required for HP/UX (and others?) */ #include <isc/task.h> @@ -1843,7 +1844,7 @@ new_adbentry(dns_adb_t *adb) { e->to512 = 0; e->sit = NULL; e->sitlen = 0; - isc_random_get(&r); + r = arc4random(); e->srtt = (r & 0x1f) + 1; e->lastage = 0; e->expires = 0; diff --git a/usr.sbin/bind/lib/dns/client.c b/usr.sbin/bind/lib/dns/client.c index b784eb0887b..d2532b32ca1 100644 --- a/usr.sbin/bind/lib/dns/client.c +++ b/usr.sbin/bind/lib/dns/client.c @@ -480,7 +480,7 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, if (result != ISC_R_SUCCESS) goto cleanup; - result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); + result = dns_dispatchmgr_create(mctx, &dispatchmgr); if (result != ISC_R_SUCCESS) goto cleanup; client->dispatchmgr = dispatchmgr; diff --git a/usr.sbin/bind/lib/dns/dispatch.c b/usr.sbin/bind/lib/dns/dispatch.c index b1b1df4e164..26527fcc5dd 100644 --- a/usr.sbin/bind/lib/dns/dispatch.c +++ b/usr.sbin/bind/lib/dns/dispatch.c @@ -23,12 +23,12 @@ #include <unistd.h> #include <stdlib.h> -#include <isc/entropy.h> + #include <isc/mem.h> #include <isc/mutex.h> #include <isc/portset.h> -#include <isc/random.h> + #include <isc/socket.h> #include <isc/stats.h> #include <isc/string.h> @@ -54,16 +54,6 @@ typedef ISC_LIST(dispsocket_t) dispsocketlist_t; typedef struct dispportentry dispportentry_t; typedef ISC_LIST(dispportentry_t) dispportlist_t; -/* ARC4 Random generator state */ -typedef struct arc4ctx { - isc_uint8_t i; - isc_uint8_t j; - isc_uint8_t s[256]; - int count; - isc_entropy_t *entropy; /*%< entropy source for ARC4 */ - isc_mutex_t *lock; -} arc4ctx_t; - typedef struct dns_qid { unsigned int magic; unsigned int qid_nbuckets; /*%< hash table size */ @@ -80,17 +70,12 @@ struct dns_dispatchmgr { dns_acl_t *blackhole; dns_portlist_t *portlist; isc_stats_t *stats; - isc_entropy_t *entropy; /*%< entropy source */ /* Locked by "lock". */ isc_mutex_t lock; unsigned int state; ISC_LIST(dns_dispatch_t) list; - /* Locked by arc4_lock. */ - isc_mutex_t arc4_lock; - arc4ctx_t arc4ctx; /*%< ARC4 context for QID */ - /* locked by buffer lock */ dns_qid_t *qid; isc_mutex_t buffer_lock; @@ -254,7 +239,6 @@ struct dns_dispatch { unsigned int tcpbuffers; /*%< allocated buffers */ dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ dns_qid_t *qid; - arc4ctx_t arc4ctx; /*%< for QID/UDP port num */ dispportlist_t *port_table; /*%< hold ports 'owned' by us */ isc_mempool_t *portpool; /*%< port table entries */ }; @@ -430,169 +414,6 @@ request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, } } -/*% - * ARC4 random number generator derived from OpenBSD. - * Only dispatch_random() and dispatch_uniformrandom() are expected - * to be called from general dispatch routines; the rest of them are subroutines - * for these two. - * - * The original copyright follows: - * Copyright (c) 1996, David Mazieres <dm@uun.org> - * 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. - */ -static void -dispatch_initrandom(arc4ctx_t *actx, isc_entropy_t *entropy, - isc_mutex_t *lock) -{ - int n; - for (n = 0; n < 256; n++) - actx->s[n] = n; - actx->i = 0; - actx->j = 0; - actx->count = 0; - actx->entropy = entropy; /* don't have to attach */ - actx->lock = lock; -} - -static void -dispatch_arc4addrandom(arc4ctx_t *actx, unsigned char *dat, int datlen) { - int n; - isc_uint8_t si; - - actx->i--; - for (n = 0; n < 256; n++) { - actx->i = (actx->i + 1); - si = actx->s[actx->i]; - actx->j = (actx->j + si + dat[n % datlen]); - actx->s[actx->i] = actx->s[actx->j]; - actx->s[actx->j] = si; - } - actx->j = actx->i; -} - -static inline isc_uint8_t -dispatch_arc4get8(arc4ctx_t *actx) { - isc_uint8_t si, sj; - - actx->i = (actx->i + 1); - si = actx->s[actx->i]; - actx->j = (actx->j + si); - sj = actx->s[actx->j]; - actx->s[actx->i] = sj; - actx->s[actx->j] = si; - - return (actx->s[(si + sj) & 0xff]); -} - -static inline isc_uint16_t -dispatch_arc4get16(arc4ctx_t *actx) { - isc_uint16_t val; - - val = dispatch_arc4get8(actx) << 8; - val |= dispatch_arc4get8(actx); - - return (val); -} - -static void -dispatch_arc4stir(arc4ctx_t *actx) { - int i; - union { - unsigned char rnd[128]; - isc_uint32_t rnd32[32]; - } rnd; - isc_result_t result; - - if (actx->entropy != NULL) { - /* - * We accept any quality of random data to avoid blocking. - */ - result = isc_entropy_getdata(actx->entropy, rnd.rnd, - sizeof(rnd), NULL, 0); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } else { - for (i = 0; i < 32; i++) - isc_random_get(&rnd.rnd32[i]); - } - dispatch_arc4addrandom(actx, rnd.rnd, sizeof(rnd.rnd)); - - /* - * Discard early keystream, as per recommendations in: - * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps - */ - for (i = 0; i < 256; i++) - (void)dispatch_arc4get8(actx); - - /* - * Derived from OpenBSD's implementation. The rationale is not clear, - * but should be conservative enough in safety, and reasonably large - * for efficiency. - */ - actx->count = 1600000; -} - -static isc_uint16_t -dispatch_random(arc4ctx_t *actx) { - isc_uint16_t result; - - if (actx->lock != NULL) - LOCK(actx->lock); - - actx->count -= sizeof(isc_uint16_t); - if (actx->count <= 0) - dispatch_arc4stir(actx); - result = dispatch_arc4get16(actx); - - if (actx->lock != NULL) - UNLOCK(actx->lock); - - return (result); -} - -static isc_uint16_t -dispatch_uniformrandom(arc4ctx_t *actx, isc_uint16_t upper_bound) { - isc_uint16_t min, r; - - if (upper_bound < 2) - return (0); - - /* - * Ensure the range of random numbers [min, 0xffff] be a multiple of - * upper_bound and contain at least a half of the 16 bit range. - */ - - if (upper_bound > 0x8000) - min = 1 + ~upper_bound; /* 0x8000 - upper_bound */ - else - min = (isc_uint16_t)(0x10000 % (isc_uint32_t)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 = dispatch_random(actx); - if (r >= min) - break; - } - - return (r % upper_bound); -} - /* * Return a hash of the destination and message id. */ @@ -878,7 +699,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest, dispsock->disp = disp; dispsock->resp = NULL; dispsock->portentry = NULL; - isc_random_get(&r); + r = arc4random(); dispsock->task = NULL; isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task); ISC_LINK_INIT(dispsock, link); @@ -895,8 +716,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest, qid = DNS_QID(disp); for (i = 0; i < 64; i++) { - port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp), - nports)]; + port = ports[arc4random_uniform(nports)]; isc_sockaddr_setport(&localaddr, port); LOCK(&qid->lock); @@ -1812,8 +1632,6 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) { DESTROYLOCK(&mgr->lock); mgr->state = 0; - DESTROYLOCK(&mgr->arc4_lock); - isc_mempool_destroy(&mgr->depool); isc_mempool_destroy(&mgr->rpool); isc_mempool_destroy(&mgr->dpool); @@ -1828,8 +1646,6 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) { DESTROYLOCK(&mgr->rpool_lock); DESTROYLOCK(&mgr->depool_lock); - if (mgr->entropy != NULL) - isc_entropy_detach(&mgr->entropy); if (mgr->qid != NULL) qid_destroy(mctx, &mgr->qid); @@ -1923,8 +1739,7 @@ create_default_portset(isc_mem_t *mctx, isc_portset_t **portsetp) { */ isc_result_t -dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, - dns_dispatchmgr_t **mgrp) +dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp) { dns_dispatchmgr_t *mgr; isc_result_t result; @@ -1948,13 +1763,9 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, if (result != ISC_R_SUCCESS) goto deallocate; - result = isc_mutex_init(&mgr->arc4_lock); - if (result != ISC_R_SUCCESS) - goto kill_lock; - result = isc_mutex_init(&mgr->buffer_lock); if (result != ISC_R_SUCCESS) - goto kill_arc4_lock; + goto kill_lock; result = isc_mutex_init(&mgr->depool_lock); if (result != ISC_R_SUCCESS) @@ -2020,7 +1831,6 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, mgr->maxbuffers = 0; mgr->bpool = NULL; mgr->spool = NULL; - mgr->entropy = NULL; mgr->qid = NULL; mgr->state = 0; ISC_LIST_INIT(mgr->list); @@ -2046,11 +1856,6 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, if (result != ISC_R_SUCCESS) goto kill_dpool; - if (entropy != NULL) - isc_entropy_attach(entropy, &mgr->entropy); - - dispatch_initrandom(&mgr->arc4ctx, mgr->entropy, &mgr->arc4_lock); - *mgrp = mgr; return (ISC_R_SUCCESS); @@ -2072,8 +1877,6 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, DESTROYLOCK(&mgr->depool_lock); kill_buffer_lock: DESTROYLOCK(&mgr->buffer_lock); - kill_arc4_lock: - DESTROYLOCK(&mgr->arc4_lock); kill_lock: DESTROYLOCK(&mgr->lock); deallocate: @@ -2577,7 +2380,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, ISC_LIST_INIT(disp->activesockets); ISC_LIST_INIT(disp->inactivesockets); disp->nsockets = 0; - dispatch_initrandom(&disp->arc4ctx, mgr->entropy, NULL); disp->port_table = NULL; disp->portpool = NULL; disp->dscp = -1; @@ -2899,9 +2701,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, for (i = 0; i < 1024; i++) { in_port_t prt; - prt = ports[dispatch_uniformrandom( - DISP_ARC4CTX(disp), - nports)]; + prt = ports[arc4random_uniform(nports)]; isc_sockaddr_setport(&localaddr_bound, prt); result = open_socket(sockmgr, &localaddr_bound, 0, &sock, NULL); @@ -3291,7 +3091,7 @@ dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) id = *idp; else - id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp)); + id = arc4random(); ok = ISC_FALSE; i = 0; do { diff --git a/usr.sbin/bind/lib/dns/dst_api.c b/usr.sbin/bind/lib/dns/dst_api.c index a60d2037bbc..96425be9ac4 100644 --- a/usr.sbin/bind/lib/dns/dst_api.c +++ b/usr.sbin/bind/lib/dns/dst_api.c @@ -33,7 +33,7 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.13 2020/01/09 14:21:27 florian Exp $ + * $Id: dst_api.c,v 1.14 2020/01/09 14:24:07 florian Exp $ */ /*! \file */ @@ -45,7 +45,7 @@ #include <isc/buffer.h> #include <isc/dir.h> -#include <isc/entropy.h> + #include <isc/fsaccess.h> #include <isc/hmacsha.h> #include <isc/lex.h> @@ -54,7 +54,7 @@ #include <isc/platform.h> #include <isc/refcount.h> -#include <isc/random.h> + #include <isc/safe.h> #include <isc/string.h> #include <isc/time.h> @@ -80,8 +80,6 @@ #define DST_AS_STR(t) ((t).value.as_textregion.base) static dst_func_t *dst_t_func[DST_MAX_ALGS]; -static isc_entropy_t *dst_entropy_pool = NULL; -static unsigned int dst_entropy_flags = 0; static isc_boolean_t dst_initialized = ISC_FALSE; isc_mem_t *dst__memory_pool = NULL; @@ -151,13 +149,12 @@ default_memfree(void *arg, void *ptr) { } isc_result_t -dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { - return (dst_lib_init2(mctx, ectx, NULL, eflags)); +dst_lib_init(isc_mem_t *mctx) { + return (dst_lib_init2(mctx, NULL)); } isc_result_t -dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, - const char *engine, unsigned int eflags) { +dst_lib_init2(isc_mem_t *mctx, const char *engine) { isc_result_t result; REQUIRE(mctx != NULL); @@ -180,10 +177,6 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, return (result); isc_mem_setname(dst__memory_pool, "dst", NULL); isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE); - if (ectx != NULL) { - isc_entropy_attach(ectx, &dst_entropy_pool); - dst_entropy_flags = eflags; - } dst_result_register(); @@ -237,8 +230,6 @@ dst_lib_destroy(void) { dst__openssl_destroy(); if (dst__memory_pool != NULL) isc_mem_detach(&dst__memory_pool); - if (dst_entropy_pool != NULL) - isc_entropy_detach(&dst_entropy_pool); } isc_boolean_t @@ -1769,28 +1760,6 @@ addsuffix(char *filename, int len, const char *odirname, return (ISC_R_SUCCESS); } -isc_result_t -dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { - unsigned int flags = dst_entropy_flags; - - if (dst_entropy_pool == NULL) - return (ISC_R_FAILURE); - - if (len == 0) - return (ISC_R_SUCCESS); - - if (pseudo) - flags &= ~ISC_ENTROPY_GOODONLY; - else - flags |= ISC_ENTROPY_BLOCKING; - return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags)); -} - -unsigned int -dst__entropy_status(void) { - return (isc_entropy_status(dst_entropy_pool)); -} - isc_buffer_t * dst_key_tkeytoken(const dst_key_t *key) { REQUIRE(VALID_KEY(key)); diff --git a/usr.sbin/bind/lib/dns/dst_internal.h b/usr.sbin/bind/lib/dns/dst_internal.h index 0b5d78a42c6..279b2382636 100644 --- a/usr.sbin/bind/lib/dns/dst_internal.h +++ b/usr.sbin/bind/lib/dns/dst_internal.h @@ -31,7 +31,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.6 2020/01/09 14:21:27 florian Exp $ */ +/* $Id: dst_internal.h,v 1.7 2020/01/09 14:24:07 florian Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -236,17 +236,6 @@ void * dst__mem_alloc(size_t size); void dst__mem_free(void *ptr); void * dst__mem_realloc(void *ptr, size_t size); -/*% - * Entropy retriever using the DST entropy pool. - */ -isc_result_t dst__entropy_getdata(void *buf, unsigned int len, - isc_boolean_t pseudo); - -/* - * Entropy status hook. - */ -unsigned int dst__entropy_status(void); - ISC_LANG_ENDDECLS #endif /* DST_DST_INTERNAL_H */ diff --git a/usr.sbin/bind/lib/dns/hmac_link.c b/usr.sbin/bind/lib/dns/hmac_link.c index 9eca228487d..62d1789985e 100644 --- a/usr.sbin/bind/lib/dns/hmac_link.c +++ b/usr.sbin/bind/lib/dns/hmac_link.c @@ -33,7 +33,7 @@ /* * Principal Author: Brian Wellington - * $Id: hmac_link.c,v 1.4 2020/01/09 13:52:23 florian Exp $ + * $Id: hmac_link.c,v 1.5 2020/01/09 14:24:07 florian Exp $ */ #include <config.h> @@ -159,6 +159,7 @@ hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { unsigned int bytes; unsigned char data[ISC_SHA1_BLOCK_LENGTH]; + UNUSED(pseudorandom_ok); UNUSED(callback); bytes = (key->key_size + 7) / 8; @@ -168,10 +169,7 @@ hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { } memset(data, 0, ISC_SHA1_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); - - if (ret != ISC_R_SUCCESS) - return (ret); + arc4random_buf(data, bytes); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); @@ -452,6 +450,7 @@ hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, unsigned int bytes; unsigned char data[ISC_SHA224_BLOCK_LENGTH]; + UNUSED(pseudorandom_ok); UNUSED(callback); bytes = (key->key_size + 7) / 8; @@ -461,10 +460,7 @@ hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, } memset(data, 0, ISC_SHA224_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); - - if (ret != ISC_R_SUCCESS) - return (ret); + arc4random_buf(data, bytes); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); @@ -739,6 +735,7 @@ hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, unsigned int bytes; unsigned char data[ISC_SHA256_BLOCK_LENGTH]; + UNUSED(pseudorandom_ok); UNUSED(callback); bytes = (key->key_size + 7) / 8; @@ -748,10 +745,7 @@ hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, } memset(data, 0, ISC_SHA256_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); - - if (ret != ISC_R_SUCCESS) - return (ret); + arc4random_buf(data, bytes); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); @@ -1026,6 +1020,7 @@ hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, unsigned int bytes; unsigned char data[ISC_SHA384_BLOCK_LENGTH]; + UNUSED(pseudorandom_ok); UNUSED(callback); bytes = (key->key_size + 7) / 8; @@ -1035,10 +1030,7 @@ hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, } memset(data, 0, ISC_SHA384_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); - - if (ret != ISC_R_SUCCESS) - return (ret); + arc4random_buf(data, bytes); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); @@ -1313,6 +1305,7 @@ hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, unsigned int bytes; unsigned char data[ISC_SHA512_BLOCK_LENGTH]; + UNUSED(pseudorandom_ok); UNUSED(callback); bytes = (key->key_size + 7) / 8; @@ -1322,10 +1315,7 @@ hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, } memset(data, 0, ISC_SHA512_BLOCK_LENGTH); - ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); - - if (ret != ISC_R_SUCCESS) - return (ret); + arc4random_buf(data, bytes); isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); diff --git a/usr.sbin/bind/lib/dns/include/dns/dispatch.h b/usr.sbin/bind/lib/dns/include/dns/dispatch.h index bdc8a55a5d4..074b21d5250 100644 --- a/usr.sbin/bind/lib/dns/include/dns/dispatch.h +++ b/usr.sbin/bind/lib/dns/include/dns/dispatch.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.h,v 1.9 2019/12/17 01:46:32 sthen Exp $ */ +/* $Id: dispatch.h,v 1.10 2020/01/09 14:24:07 florian Exp $ */ #ifndef DNS_DISPATCH_H #define DNS_DISPATCH_H 1 @@ -151,8 +151,7 @@ struct dns_dispatchset { #define DNS_DISPATCHOPT_FIXEDID 0x00000001U isc_result_t -dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, - dns_dispatchmgr_t **mgrp); +dns_dispatchmgr_create(isc_mem_t *mctx, dns_dispatchmgr_t **mgrp); /*%< * Creates a new dispatchmgr object. * @@ -161,10 +160,6 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, * *\li mgrp != NULL && *mgrp == NULL * - *\li "entropy" may be NULL, in which case an insecure random generator - * will be used. If it is non-NULL, it must be a valid entropy - * source. - * * Returns: *\li ISC_R_SUCCESS -- all ok * diff --git a/usr.sbin/bind/lib/dns/include/dns/tkey.h b/usr.sbin/bind/lib/dns/include/dns/tkey.h index 64ccde8bf37..191ee5fcc48 100644 --- a/usr.sbin/bind/lib/dns/include/dns/tkey.h +++ b/usr.sbin/bind/lib/dns/include/dns/tkey.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tkey.h,v 1.4 2020/01/09 13:56:37 florian Exp $ */ +/* $Id: tkey.h,v 1.5 2020/01/09 14:24:07 florian Exp $ */ #ifndef DNS_TKEY_H #define DNS_TKEY_H 1 @@ -39,12 +39,10 @@ struct dns_tkeyctx { dst_key_t *dhkey; dns_name_t *domain; isc_mem_t *mctx; - isc_entropy_t *ectx; }; isc_result_t -dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, - dns_tkeyctx_t **tctxp); +dns_tkeyctx_create(isc_mem_t *mctx, dns_tkeyctx_t **tctxp); /*%< * Create an empty TKEY context. * diff --git a/usr.sbin/bind/lib/dns/include/dst/dst.h b/usr.sbin/bind/lib/dns/include/dst/dst.h index 3c13b6f83fc..386648d14ad 100644 --- a/usr.sbin/bind/lib/dns/include/dst/dst.h +++ b/usr.sbin/bind/lib/dns/include/dst/dst.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst.h,v 1.4 2020/01/09 13:56:37 florian Exp $ */ +/* $Id: dst.h,v 1.5 2020/01/09 14:24:08 florian Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 @@ -132,17 +132,15 @@ typedef struct dst_context dst_context_t; ***/ isc_result_t -dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags); +dst_lib_init(isc_mem_t *mctx); isc_result_t -dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, - const char *engine, unsigned int eflags); +dst_lib_init2(isc_mem_t *mctx, const char *engine); /*%< * Initializes the DST subsystem. * * Requires: * \li "mctx" is a valid memory context - * \li "ectx" is a valid entropy context * * Returns: * \li ISC_R_SUCCESS diff --git a/usr.sbin/bind/lib/dns/lib.c b/usr.sbin/bind/lib/dns/lib.c index 63c65f48b66..d0069366a96 100644 --- a/usr.sbin/bind/lib/dns/lib.c +++ b/usr.sbin/bind/lib/dns/lib.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lib.c,v 1.4 2020/01/09 14:18:29 florian Exp $ */ +/* $Id: lib.c,v 1.5 2020/01/09 14:24:07 florian Exp $ */ /*! \file */ @@ -92,11 +92,11 @@ initialize(void) { result = dns_ecdb_register(dns_g_mctx, &dbimp); if (result != ISC_R_SUCCESS) goto cleanup_mctx; - result = isc_hash_create(dns_g_mctx, NULL, DNS_NAME_MAXWIRE); + result = isc_hash_create(dns_g_mctx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) goto cleanup_db; - result = dst_lib_init(dns_g_mctx, NULL, 0); + result = dst_lib_init(dns_g_mctx); if (result != ISC_R_SUCCESS) goto cleanup_hash; diff --git a/usr.sbin/bind/lib/dns/name.c b/usr.sbin/bind/lib/dns/name.c index dc283fcf820..ac7d1cec1a8 100644 --- a/usr.sbin/bind/lib/dns/name.c +++ b/usr.sbin/bind/lib/dns/name.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.16 2020/01/09 14:18:29 florian Exp $ */ +/* $Id: name.c,v 1.17 2020/01/09 14:24:07 florian Exp $ */ /*! \file */ @@ -28,7 +28,7 @@ #include <isc/mem.h> #include <isc/once.h> -#include <isc/random.h> + #include <isc/string.h> #include <isc/thread.h> #include <isc/util.h> diff --git a/usr.sbin/bind/lib/dns/openssl_link.c b/usr.sbin/bind/lib/dns/openssl_link.c index ecbe2dd738d..75c25920fa4 100644 --- a/usr.sbin/bind/lib/dns/openssl_link.c +++ b/usr.sbin/bind/lib/dns/openssl_link.c @@ -36,8 +36,8 @@ */ #include <config.h> +#include <stdlib.h> -#include <isc/entropy.h> #include <isc/mem.h> #include <isc/mutex.h> #include <isc/mutexblock.h> @@ -52,59 +52,11 @@ #include "dst_internal.h" #include "dst_openssl.h" -static RAND_METHOD *rm = NULL; - #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) static isc_mutex_t *locks = NULL; static int nlocks; #endif -static int -entropy_get(unsigned char *buf, int num) { - isc_result_t result; - if (num < 0) - return (-1); - result = dst__entropy_getdata(buf, (unsigned int) num, ISC_FALSE); - return (result == ISC_R_SUCCESS ? 1 : -1); -} - -static int -entropy_status(void) { - return (dst__entropy_status() > 32); -} - -static int -entropy_getpseudo(unsigned char *buf, int num) { - isc_result_t result; - if (num < 0) - return (-1); - result = dst__entropy_getdata(buf, (unsigned int) num, ISC_TRUE); - return (result == ISC_R_SUCCESS ? 1 : -1); -} - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static void -entropy_add(const void *buf, int num, double entropy) { - /* - * Do nothing. The only call to this provides no useful data anyway. - */ - UNUSED(buf); - UNUSED(num); - UNUSED(entropy); -} -#else -static int -entropy_add(const void *buf, int num, double entropy) { - /* - * Do nothing. The only call to this provides no useful data anyway. - */ - UNUSED(buf); - UNUSED(num); - UNUSED(entropy); - return (1); -} -#endif - #if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) static void lock_callback(int mode, int type, const char *file, int line) { @@ -198,25 +150,9 @@ dst__openssl_init(const char *engine) { ERR_load_crypto_strings(); #endif - rm = mem_alloc(sizeof(RAND_METHOD) FILELINE); - if (rm == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_mutexinit; - } - rm->seed = NULL; - rm->bytes = entropy_get; - rm->cleanup = NULL; - rm->add = entropy_add; - rm->pseudorand = entropy_getpseudo; - rm->status = entropy_status; - - RAND_set_rand_method(rm); return (ISC_R_SUCCESS); - cleanup_mutexinit: #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - CRYPTO_set_locking_callback(NULL); - DESTROYMUTEXBLOCK(locks, nlocks); cleanup_mutexalloc: mem_free(locks FILELINE); locks = NULL; @@ -228,21 +164,10 @@ void dst__openssl_destroy(void) { #if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L) OPENSSL_cleanup(); - if (rm != NULL) { - mem_free(rm FILELINE); - rm = NULL; - } #else /* * Sequence taken from apps_shutdown() in <apps/apps.h>. */ - if (rm != NULL) { -#if OPENSSL_VERSION_NUMBER >= 0x00907000L - RAND_cleanup(); -#endif - mem_free(rm FILELINE); - rm = NULL; - } #if (OPENSSL_VERSION_NUMBER >= 0x00907000L) CONF_modules_free(); #endif diff --git a/usr.sbin/bind/lib/dns/opensslecdsa_link.c b/usr.sbin/bind/lib/dns/opensslecdsa_link.c index 176a446fb3c..5d4efed5db5 100644 --- a/usr.sbin/bind/lib/dns/opensslecdsa_link.c +++ b/usr.sbin/bind/lib/dns/opensslecdsa_link.c @@ -22,7 +22,7 @@ #error "ECDSA without EVP for SHA2?" #endif -#include <isc/entropy.h> + #include <isc/mem.h> #include <isc/safe.h> #include <isc/sha2.h> diff --git a/usr.sbin/bind/lib/dns/openssleddsa_link.c b/usr.sbin/bind/lib/dns/openssleddsa_link.c index e867eb69a97..9bde5951a1a 100644 --- a/usr.sbin/bind/lib/dns/openssleddsa_link.c +++ b/usr.sbin/bind/lib/dns/openssleddsa_link.c @@ -19,7 +19,7 @@ #if defined(OPENSSL) && \ (defined(HAVE_OPENSSL_ED25519) || defined(HAVE_OPENSSL_ED448)) -#include <isc/entropy.h> + #include <isc/mem.h> #include <isc/safe.h> #include <isc/sha2.h> diff --git a/usr.sbin/bind/lib/dns/opensslgost_link.c b/usr.sbin/bind/lib/dns/opensslgost_link.c index 22ebe44bea0..27ede9d9c13 100644 --- a/usr.sbin/bind/lib/dns/opensslgost_link.c +++ b/usr.sbin/bind/lib/dns/opensslgost_link.c @@ -18,7 +18,7 @@ #if defined(OPENSSL) && defined(HAVE_OPENSSL_GOST) -#include <isc/entropy.h> + #include <isc/mem.h> #include <isc/safe.h> #include <isc/string.h> diff --git a/usr.sbin/bind/lib/dns/opensslrsa_link.c b/usr.sbin/bind/lib/dns/opensslrsa_link.c index 12672541de4..b4f7e8d7f75 100644 --- a/usr.sbin/bind/lib/dns/opensslrsa_link.c +++ b/usr.sbin/bind/lib/dns/opensslrsa_link.c @@ -28,7 +28,7 @@ #endif -#include <isc/entropy.h> + #include <isc/md5.h> #include <isc/mem.h> #include <isc/safe.h> diff --git a/usr.sbin/bind/lib/dns/rbtdb.c b/usr.sbin/bind/lib/dns/rbtdb.c index ee2a05d0e53..9b331ecf99b 100644 --- a/usr.sbin/bind/lib/dns/rbtdb.c +++ b/usr.sbin/bind/lib/dns/rbtdb.c @@ -21,6 +21,7 @@ */ #include <config.h> +#include <stdlib.h> /* #define inline */ @@ -38,7 +39,7 @@ #include <isc/once.h> #include <isc/platform.h> -#include <isc/random.h> + #include <isc/refcount.h> #include <isc/rwlock.h> #include <isc/serial.h> @@ -5532,7 +5533,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { if (isc_mem_isovermem(rbtdb->common.mctx)) { isc_uint32_t val; - isc_random_get(&val); + val = arc4random(); /* * XXXDCL Could stand to have a better policy, like LRU. */ diff --git a/usr.sbin/bind/lib/dns/rdataset.c b/usr.sbin/bind/lib/dns/rdataset.c index d319587bc03..4f5950409cd 100644 --- a/usr.sbin/bind/lib/dns/rdataset.c +++ b/usr.sbin/bind/lib/dns/rdataset.c @@ -22,7 +22,7 @@ #include <isc/buffer.h> #include <isc/mem.h> -#include <isc/random.h> + #include <isc/serial.h> #include <isc/util.h> @@ -414,10 +414,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, * 'Random' order. */ for (i = 0; i < count; i++) { - isc_uint32_t val; - - isc_random_get(&val); - choice = i + (val % (count - i)); + choice = i + arc4random_uniform(count - i); rdata = in[i]; in[i] = in[choice]; in[choice] = rdata; @@ -437,7 +434,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, val = rdataset->count; if (val == ISC_UINT32_MAX) - isc_random_get(&val); + val = arc4random(); j = val % count; for (i = 0; i < count; i++) { if (order != NULL) diff --git a/usr.sbin/bind/lib/dns/resolver.c b/usr.sbin/bind/lib/dns/resolver.c index e3e11c2ff1e..c66547caf13 100644 --- a/usr.sbin/bind/lib/dns/resolver.c +++ b/usr.sbin/bind/lib/dns/resolver.c @@ -18,13 +18,14 @@ #include <config.h> #include <ctype.h> +#include <stdlib.h> #include <isc/counter.h> #include <isc/log.h> #include <isc/platform.h> #include <isc/string.h> -#include <isc/random.h> + #include <isc/socket.h> #include <isc/stats.h> #include <isc/task.h> @@ -973,7 +974,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, * slow. We don't know. Increase the RTT. */ INSIST(no_response); - isc_random_get(&value); + value = arc4random(); if (query->addrinfo->srtt > 800000) mask = 0x3fff; else if (query->addrinfo->srtt > 400000) diff --git a/usr.sbin/bind/lib/dns/tkey.c b/usr.sbin/bind/lib/dns/tkey.c index 815569ba3f0..a8626b68aee 100644 --- a/usr.sbin/bind/lib/dns/tkey.c +++ b/usr.sbin/bind/lib/dns/tkey.c @@ -16,9 +16,10 @@ /*! \file */ #include <config.h> +#include <stdlib.h> #include <isc/buffer.h> -#include <isc/entropy.h> + #include <isc/md5.h> #include <isc/mem.h> @@ -68,12 +69,11 @@ tkey_log(const char *fmt, ...) { } isc_result_t -dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) +dns_tkeyctx_create(isc_mem_t *mctx, dns_tkeyctx_t **tctxp) { dns_tkeyctx_t *tctx; REQUIRE(mctx != NULL); - REQUIRE(ectx != NULL); REQUIRE(tctxp != NULL && *tctxp == NULL); tctx = isc_mem_get(mctx, sizeof(dns_tkeyctx_t)); @@ -81,8 +81,6 @@ dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) return (ISC_R_NOMEMORY); tctx->mctx = NULL; isc_mem_attach(mctx, &tctx->mctx); - tctx->ectx = NULL; - isc_entropy_attach(ectx, &tctx->ectx); tctx->dhkey = NULL; tctx->domain = NULL; @@ -107,7 +105,6 @@ dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) { dns_name_free(tctx->domain, mctx); isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t)); } - isc_entropy_detach(&tctx->ectx); isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t)); isc_mem_detach(&mctx); *tctxp = NULL; @@ -306,13 +303,7 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, if (randomdata == NULL) goto failure; - result = dst__entropy_getdata(randomdata, TKEY_RANDOM_AMOUNT, - ISC_FALSE); - if (result != ISC_R_SUCCESS) { - tkey_log("process_dhtkey: failed to obtain entropy: %s", - isc_result_totext(result)); - goto failure; - } + arc4random_buf(randomdata, TKEY_RANDOM_AMOUNT); r.base = randomdata; r.length = TKEY_RANDOM_AMOUNT; @@ -516,12 +507,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, isc_buffer_t b; unsigned int i, j; - result = isc_entropy_getdata(tctx->ectx, - randomdata, - sizeof(randomdata), - NULL, 0); - if (result != ISC_R_SUCCESS) - goto failure; + arc4random_buf(randomdata, sizeof(randomdata)); for (i = 0, j = 0; i < sizeof(randomdata); i++) { unsigned char val = randomdata[i]; diff --git a/usr.sbin/bind/lib/dns/xfrin.c b/usr.sbin/bind/lib/dns/xfrin.c index 409e8463c01..0ae6f2e8ae5 100644 --- a/usr.sbin/bind/lib/dns/xfrin.c +++ b/usr.sbin/bind/lib/dns/xfrin.c @@ -14,15 +14,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.13 2020/01/09 13:47:13 florian Exp $ */ +/* $Id: xfrin.c,v 1.14 2020/01/09 14:24:07 florian Exp $ */ /*! \file */ #include <config.h> +#include <stdlib.h> #include <isc/mem.h> -#include <isc/random.h> + #include <isc/string.h> /* Required for HP/UX (and others?) */ #include <isc/task.h> #include <isc/timer.h> @@ -848,7 +849,7 @@ xfrin_create(isc_mem_t *mctx, dns_name_init(&xfr->name, NULL); xfr->rdclass = rdclass; - isc_random_get(&tmp); + tmp = arc4random(); xfr->checkid = ISC_TRUE; xfr->id = (isc_uint16_t)(tmp & 0xffff); xfr->reqtype = reqtype; diff --git a/usr.sbin/bind/lib/dns/zone.c b/usr.sbin/bind/lib/dns/zone.c index 1c376d24a31..0b50069695f 100644 --- a/usr.sbin/bind/lib/dns/zone.c +++ b/usr.sbin/bind/lib/dns/zone.c @@ -18,13 +18,14 @@ #include <config.h> #include <errno.h> +#include <stdlib.h> #include <isc/file.h> #include <isc/hex.h> #include <isc/mutex.h> #include <isc/pool.h> -#include <isc/random.h> + #include <isc/ratelimiter.h> #include <isc/refcount.h> #include <isc/rwlock.h> @@ -815,7 +816,7 @@ static const char *dbargv_default[] = { "rbt" }; do { \ isc_interval_t _i; \ isc_uint32_t _j; \ - _j = isc_random_jitter((b), (b)/4); \ + _j = (b) - arc4random_uniform((b)/4); \ isc_interval_set(&_i, _j, 0); \ if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ dns_zone_log(zone, ISC_LOG_WARNING, \ @@ -3518,8 +3519,7 @@ set_resigntime(dns_zone_t *zone) { resign = rdataset.resign - zone->sigresigninginterval; dns_rdataset_disassociate(&rdataset); - isc_random_get(&nanosecs); - nanosecs %= 1000000000; + nanosecs = arc4random_uniform(1000000000); isc_time_set(&zone->resigntime, resign, nanosecs); cleanup: dns_db_detach(&db); @@ -4616,8 +4616,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, DNS_ZONE_TIME_ADD(&now, zone->retry, &zone->expiretime); - delay = isc_random_jitter(zone->retry, - (zone->retry * 3) / 4); + delay = zone->retry - + arc4random_uniform((zone->retry * 3) / 4); DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); if (isc_time_compare(&zone->refreshtime, &zone->expiretime) >= 0) @@ -6400,11 +6400,10 @@ zone_resigninc(dns_zone_t *zone) { * we still want some clustering to occur. */ if (sigvalidityinterval >= 3600U) { - isc_random_get(&jitter); if (sigvalidityinterval > 7200U) { - jitter %= 3600; + jitter = arc4random_uniform(3600); } else { - jitter %= 1200; + jitter = arc4random_uniform(1200); } expire = soaexpire - jitter - 1; } else { @@ -7384,11 +7383,10 @@ zone_nsec3chain(dns_zone_t *zone) { * we still want some clustering to occur. */ if (sigvalidityinterval >= 3600U) { - isc_random_get(&jitter); if (sigvalidityinterval > 7200U) { - jitter %= 3600; + jitter = arc4random_uniform(3600); } else { - jitter %= 1200; + jitter = arc4random_uniform(1200); } expire = soaexpire - jitter - 1; } else { @@ -8317,11 +8315,10 @@ zone_sign(dns_zone_t *zone) { * we still want some clustering to occur. */ if (sigvalidityinterval >= 3600U) { - isc_random_get(&jitter); if (sigvalidityinterval > 7200U) { - jitter %= 3600; + jitter = arc4random_uniform(3600); } else { - jitter %= 1200; + jitter = arc4random_uniform(1200); } expire = soaexpire - jitter - 1; } else { @@ -10086,7 +10083,7 @@ dns_zone_refresh(dns_zone_t *zone) { * Setting this to the retry time will do that. XXXMLG * If we are successful it will be reset using zone->refresh. */ - isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), + isc_interval_set(&i, zone->retry - arc4random_uniform(zone->retry / 4), 0); result = isc_time_nowplusinterval(&zone->refreshtime, &i); if (result != ISC_R_SUCCESS) diff --git a/usr.sbin/bind/lib/isc/Makefile.in b/usr.sbin/bind/lib/isc/Makefile.in index e51678f8d60..77a8b6e561d 100644 --- a/usr.sbin/bind/lib/isc/Makefile.in +++ b/usr.sbin/bind/lib/isc/Makefile.in @@ -32,7 +32,7 @@ CWARNINGS = # Alphabetically UNIXOBJS = @ISC_ISCIPV6_O@ @ISC_ISCPK11_API_O@ \ - unix/app.@O@ unix/dir.@O@ unix/entropy.@O@ unix/errno.@O@ \ + unix/app.@O@ unix/dir.@O@ unix/errno.@O@ \ unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \ unix/interfaceiter.@O@ unix/keyboard.@O@ unix/net.@O@ \ unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \ @@ -54,7 +54,7 @@ OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ md5.@O@ mem.@O@ mutexblock.@O@ \ netaddr.@O@ netscope.@O@ pool.@O@ ondestroy.@O@ \ - parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ + parseint.@O@ portset.@O@ quota.@O@ radix.@O@ \ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ rwlock.@O@ \ safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \ @@ -71,7 +71,7 @@ SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \ lex.c lfsr.c lib.c log.c \ md5.c mem.c mutexblock.c \ netaddr.c netscope.c pool.c ondestroy.c \ - parseint.c portset.c quota.c radix.c random.c \ + parseint.c portset.c quota.c radix.c \ ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \ symtab.c task.c taskpool.c timer.c \ diff --git a/usr.sbin/bind/lib/isc/entropy.c b/usr.sbin/bind/lib/isc/entropy.c deleted file mode 100644 index 0e0f7be204d..00000000000 --- a/usr.sbin/bind/lib/isc/entropy.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC 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. - */ - -/* $Id: entropy.c,v 1.8 2020/01/09 13:52:23 florian Exp $ */ - -/*! \file - * \brief - * This is the system independent part of the entropy module. It is - * compiled via inclusion from the relevant OS source file, ie, - * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c. - * - * \author Much of this code is modeled after the NetBSD /dev/random implementation, - * written by Michael Graff <explorer@netbsd.org>. - */ - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> - -#include <isc/buffer.h> -#include <isc/entropy.h> -#include <isc/keyboard.h> -#include <isc/list.h> -#include <isc/magic.h> -#include <isc/mem.h> -#include <isc/msgs.h> -#include <isc/mutex.h> -#include <isc/platform.h> - -#include <isc/region.h> -#include <isc/safe.h> -#include <isc/sha1.h> -#include <isc/string.h> -#include <isc/time.h> -#include <isc/util.h> - -#define ENTROPY_MAGIC ISC_MAGIC('E', 'n', 't', 'e') -#define SOURCE_MAGIC ISC_MAGIC('E', 'n', 't', 's') - -#define VALID_ENTROPY(e) ISC_MAGIC_VALID(e, ENTROPY_MAGIC) -#define VALID_SOURCE(s) ISC_MAGIC_VALID(s, SOURCE_MAGIC) - -/*** - *** "constants." Do not change these unless you _really_ know what - *** you are doing. - ***/ - -/*% - * Size of entropy pool in 32-bit words. This _MUST_ be a power of 2. - */ -#define RND_POOLWORDS 128 -/*% Pool in bytes. */ -#define RND_POOLBYTES (RND_POOLWORDS * 4) -/*% Pool in bits. */ -#define RND_POOLBITS (RND_POOLWORDS * 32) - -/*% - * Number of bytes returned per hash. This must be true: - * threshold * 2 <= digest_size_in_bytes - */ -#define RND_ENTROPY_THRESHOLD 10 -#define THRESHOLD_BITS (RND_ENTROPY_THRESHOLD * 8) - -/*% - * Size of the input event queue in samples. - */ -#define RND_EVENTQSIZE 32 - -/*% - * The number of times we'll "reseed" for pseudorandom seeds. This is an - * extremely weak pseudorandom seed. If the caller is using lots of - * pseudorandom data and they cannot provide a stronger random source, - * there is little we can do other than hope they're smart enough to - * call _adddata() with something better than we can come up with. - */ -#define RND_INITIALIZE 128 - -/*% Entropy Pool */ -typedef struct { - isc_uint32_t cursor; /*%< current add point in the pool */ - isc_uint32_t entropy; /*%< current entropy estimate in bits */ - isc_uint32_t pseudo; /*%< bits extracted in pseudorandom */ - isc_uint32_t rotate; /*%< how many bits to rotate by */ - isc_uint32_t pool[RND_POOLWORDS]; /*%< random pool data */ -} isc_entropypool_t; - -struct isc_entropy { - unsigned int magic; - isc_mem_t *mctx; - isc_mutex_t lock; - unsigned int refcnt; - isc_uint32_t initialized; - isc_uint32_t initcount; - isc_entropypool_t pool; - unsigned int nsources; - isc_entropysource_t *nextsource; - ISC_LIST(isc_entropysource_t) sources; -}; - -/*% Sample Queue */ -typedef struct { - isc_uint32_t last_time; /*%< last time recorded */ - isc_uint32_t last_delta; /*%< last delta value */ - isc_uint32_t last_delta2; /*%< last delta2 value */ - isc_uint32_t nsamples; /*%< number of samples filled in */ - isc_uint32_t *samples; /*%< the samples */ - isc_uint32_t *extra; /*%< extra samples added in */ -} sample_queue_t; - -typedef struct { - sample_queue_t samplequeue; -} isc_entropysamplesource_t; - -typedef struct { - isc_boolean_t start_called; - isc_entropystart_t startfunc; - isc_entropyget_t getfunc; - isc_entropystop_t stopfunc; - void *arg; - sample_queue_t samplequeue; -} isc_cbsource_t; - -typedef struct { - FILESOURCE_HANDLE_TYPE handle; -} isc_entropyfilesource_t; - -struct isc_entropysource { - unsigned int magic; - unsigned int type; - isc_entropy_t *ent; - isc_uint32_t total; /*%< entropy from this source */ - ISC_LINK(isc_entropysource_t) link; - char name[32]; - isc_boolean_t bad; - isc_boolean_t warn_keyboard; - isc_keyboard_t kbd; - union { - isc_entropysamplesource_t sample; - isc_entropyfilesource_t file; - isc_cbsource_t callback; - isc_entropyusocketsource_t usocket; - } sources; -}; - -#define ENTROPY_SOURCETYPE_SAMPLE 1 /*%< Type is a sample source */ -#define ENTROPY_SOURCETYPE_FILE 2 /*%< Type is a file source */ -#define ENTROPY_SOURCETYPE_CALLBACK 3 /*%< Type is a callback source */ -#define ENTROPY_SOURCETYPE_USOCKET 4 /*%< Type is a Unix socket source */ - -/*@{*/ -/*% - * The random pool "taps" - */ -#define TAP1 99 -#define TAP2 59 -#define TAP3 31 -#define TAP4 9 -#define TAP5 7 -/*@}*/ - -/*@{*/ -/*% - * Declarations for function provided by the system dependent sources that - * include this file. - */ -static void -fillpool(isc_entropy_t *, unsigned int, isc_boolean_t); - -static int -wait_for_sources(isc_entropy_t *); - -static void -destroyfilesource(isc_entropyfilesource_t *source); - -static void -destroyusocketsource(isc_entropyusocketsource_t *source); - -/*@}*/ - -static void -samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) { - REQUIRE(sq->samples != NULL); - REQUIRE(sq->extra != NULL); - - isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4); - isc_mem_put(ent->mctx, sq->extra, RND_EVENTQSIZE * 4); - sq->samples = NULL; - sq->extra = NULL; -} - -static isc_result_t -samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) { - sq->samples = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4); - if (sq->samples == NULL) - return (ISC_R_NOMEMORY); - - sq->extra = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4); - if (sq->extra == NULL) { - isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4); - sq->samples = NULL; - return (ISC_R_NOMEMORY); - } - - sq->nsamples = 0; - - return (ISC_R_SUCCESS); -} - -/*% - * Add in entropy, even when the value we're adding in could be - * very large. - */ -static inline void -add_entropy(isc_entropy_t *ent, isc_uint32_t entropy) { - /* clamp input. Yes, this must be done. */ - entropy = ISC_MIN(entropy, RND_POOLBITS); - /* Add in the entropy we already have. */ - entropy += ent->pool.entropy; - /* Clamp. */ - ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS); -} - -/*% - * Decrement the amount of entropy the pool has. - */ -static inline void -subtract_entropy(isc_entropy_t *ent, isc_uint32_t entropy) { - entropy = ISC_MIN(entropy, ent->pool.entropy); - ent->pool.entropy -= entropy; -} - -/*! - * Add in entropy, even when the value we're adding in could be - * very large. - */ -static inline void -add_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) { - /* clamp input. Yes, this must be done. */ - pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8); - /* Add in the pseudo we already have. */ - pseudo += ent->pool.pseudo; - /* Clamp. */ - ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8); -} - -/*! - * Decrement the amount of pseudo the pool has. - */ -static inline void -subtract_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) { - pseudo = ISC_MIN(pseudo, ent->pool.pseudo); - ent->pool.pseudo -= pseudo; -} - -/*! - * Add one word to the pool, rotating the input as needed. - */ -static inline void -entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) { - /* - * Steal some values out of the pool, and xor them into the - * word we were given. - * - * Mix the new value into the pool using xor. This will - * prevent the actual values from being known to the caller - * since the previous values are assumed to be unknown as well. - */ - val ^= rp->pool[(rp->cursor + TAP1) & (RND_POOLWORDS - 1)]; - val ^= rp->pool[(rp->cursor + TAP2) & (RND_POOLWORDS - 1)]; - val ^= rp->pool[(rp->cursor + TAP3) & (RND_POOLWORDS - 1)]; - val ^= rp->pool[(rp->cursor + TAP4) & (RND_POOLWORDS - 1)]; - val ^= rp->pool[(rp->cursor + TAP5) & (RND_POOLWORDS - 1)]; - if (rp->rotate == 0) - rp->pool[rp->cursor++] ^= val; - else - rp->pool[rp->cursor++] ^= - ((val << rp->rotate) | (val >> (32 - rp->rotate))); - - /* - * If we have looped around the pool, increment the rotate - * variable so the next value will get xored in rotated to - * a different position. - * Increment by a value that is relatively prime to the word size - * to try to spread the bits throughout the pool quickly when the - * pool is empty. - */ - if (rp->cursor == RND_POOLWORDS) { - rp->cursor = 0; - rp->rotate = (rp->rotate + 7) & 31; - } -} - -/*! - * Add a buffer's worth of data to the pool. - * - * Requires that the lock is held on the entropy pool. - */ -static void -entropypool_adddata(isc_entropy_t *ent, void *p, unsigned int len, - isc_uint32_t entropy) -{ - isc_uint32_t val; - unsigned long addr; - isc_uint8_t *buf; - - /* Silly MSVC in 64 bit mode complains here... */ -#ifdef _WIN64 - addr = (unsigned long)((unsigned long long)p); -#else - addr = (unsigned long)p; -#endif - buf = p; - - if ((addr & 0x03U) != 0U) { - val = 0; - switch (len) { - case 3: - val = *buf++; - len--; - /* FALLTHROUGH */ - case 2: - val = val << 8 | *buf++; - len--; - /* FALLTHROUGH */ - case 1: - val = val << 8 | *buf++; - len--; - } - - entropypool_add_word(&ent->pool, val); - } - - for (; len > 3; len -= 4) { - val = *((isc_uint32_t *)buf); - - entropypool_add_word(&ent->pool, val); - buf += 4; - } - - if (len != 0) { - val = 0; - switch (len) { - case 3: - val = *buf++; - /* FALLTHROUGH */ - case 2: - val = val << 8 | *buf++; - /* FALLTHROUGH */ - case 1: - val = val << 8 | *buf++; - } - - entropypool_add_word(&ent->pool, val); - } - - add_entropy(ent, entropy); - subtract_pseudo(ent, entropy); -} - -static inline void -reseed(isc_entropy_t *ent) { - isc_time_t t; - pid_t pid; - - if (ent->initcount == 0) { - pid = getpid(); - entropypool_adddata(ent, &pid, sizeof(pid), 0); - pid = getppid(); - entropypool_adddata(ent, &pid, sizeof(pid), 0); - } - - /*! - * After we've reseeded 100 times, only add new timing info every - * 50 requests. This will keep us from using lots and lots of - * CPU just to return bad pseudorandom data anyway. - */ - if (ent->initcount > 100) - if ((ent->initcount % 50) != 0) - return; - - TIME_NOW(&t); - entropypool_adddata(ent, &t, sizeof(t), 0); - ent->initcount++; -} - -static inline unsigned int -estimate_entropy(sample_queue_t *sq, isc_uint32_t t) { - isc_int32_t delta; - isc_int32_t delta2; - isc_int32_t delta3; - - /*! - * If the time counter has overflowed, calculate the real difference. - * If it has not, it is simpler. - */ - if (t < sq->last_time) - delta = UINT_MAX - sq->last_time + t; - else - delta = sq->last_time - t; - - if (delta < 0) - delta = -delta; - - /* - * Calculate the second and third order differentials - */ - delta2 = sq->last_delta - delta; - if (delta2 < 0) - delta2 = -delta2; - - delta3 = sq->last_delta2 - delta2; - if (delta3 < 0) - delta3 = -delta3; - - sq->last_time = t; - sq->last_delta = delta; - sq->last_delta2 = delta2; - - /* - * If any delta is 0, we got no entropy. If all are non-zero, we - * might have something. - */ - if (delta == 0 || delta2 == 0 || delta3 == 0) - return 0; - - /* - * We could find the smallest delta and claim we got log2(delta) - * bits, but for now return that we found 1 bit. - */ - return 1; -} - -static unsigned int -crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) { - unsigned int ns; - unsigned int added; - - if (sq->nsamples < 6) - return (0); - - added = 0; - sq->last_time = sq->samples[0]; - sq->last_delta = 0; - sq->last_delta2 = 0; - - /* - * Prime the values by adding in the first 4 samples in. This - * should completely initialize the delta calculations. - */ - for (ns = 0; ns < 4; ns++) - (void)estimate_entropy(sq, sq->samples[ns]); - - for (ns = 4; ns < sq->nsamples; ns++) - added += estimate_entropy(sq, sq->samples[ns]); - - entropypool_adddata(ent, sq->samples, sq->nsamples * 4, added); - entropypool_adddata(ent, sq->extra, sq->nsamples * 4, 0); - - /* - * Move the last 4 samples into the first 4 positions, and start - * adding new samples from that point. - */ - for (ns = 0; ns < 4; ns++) { - sq->samples[ns] = sq->samples[sq->nsamples - 4 + ns]; - sq->extra[ns] = sq->extra[sq->nsamples - 4 + ns]; - } - - sq->nsamples = 4; - - return (added); -} - -static unsigned int -get_from_callback(isc_entropysource_t *source, unsigned int desired, - isc_boolean_t blocking) -{ - isc_entropy_t *ent = source->ent; - isc_cbsource_t *cbs = &source->sources.callback; - unsigned int added; - unsigned int got; - isc_result_t result; - - if (desired == 0) - return (0); - - if (source->bad) - return (0); - - if (!cbs->start_called && cbs->startfunc != NULL) { - result = cbs->startfunc(source, cbs->arg, blocking); - if (result != ISC_R_SUCCESS) - return (0); - cbs->start_called = ISC_TRUE; - } - - added = 0; - result = ISC_R_SUCCESS; - while (desired > 0 && result == ISC_R_SUCCESS) { - result = cbs->getfunc(source, cbs->arg, blocking); - if (result == ISC_R_QUEUEFULL) { - got = crunchsamples(ent, &cbs->samplequeue); - added += got; - desired -= ISC_MIN(got, desired); - result = ISC_R_SUCCESS; - } else if (result != ISC_R_SUCCESS && - result != ISC_R_NOTBLOCKING) - source->bad = ISC_TRUE; - - } - - return (added); -} - -/* - * Extract some number of bytes from the random pool, decreasing the - * estimate of randomness as each byte is extracted. - * - * Do this by stiring the pool and returning a part of hash as randomness. - * Note that no secrets are given away here since parts of the hash are - * xored together before returned. - * - * Honor the request from the caller to only return good data, any data, - * etc. - */ -isc_result_t -isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, - unsigned int *returned, unsigned int flags) -{ - unsigned int i; - isc_sha1_t hash; - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; - isc_uint32_t remain, deltae, count, total; - isc_uint8_t *buf; - isc_boolean_t goodonly, partial, blocking; - - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(data != NULL); - REQUIRE(length > 0); - - goodonly = ISC_TF((flags & ISC_ENTROPY_GOODONLY) != 0); - partial = ISC_TF((flags & ISC_ENTROPY_PARTIAL) != 0); - blocking = ISC_TF((flags & ISC_ENTROPY_BLOCKING) != 0); - - REQUIRE(!partial || returned != NULL); - - LOCK(&ent->lock); - - remain = length; - buf = data; - total = 0; - while (remain != 0) { - count = ISC_MIN(remain, RND_ENTROPY_THRESHOLD); - - /* - * If we are extracting good data only, make certain we - * have enough data in our pool for this pass. If we don't, - * get some, and fail if we can't, and partial returns - * are not ok. - */ - if (goodonly) { - unsigned int fillcount; - - fillcount = ISC_MAX(remain * 8, count * 8); - - /* - * If, however, we have at least THRESHOLD_BITS - * of entropy in the pool, don't block here. It is - * better to drain the pool once in a while and - * then refill it than it is to constantly keep the - * pool full. - */ - if (ent->pool.entropy >= THRESHOLD_BITS) - fillpool(ent, fillcount, ISC_FALSE); - else - fillpool(ent, fillcount, blocking); - - /* - * Verify that we got enough entropy to do one - * extraction. If we didn't, bail. - */ - if (ent->pool.entropy < THRESHOLD_BITS) { - if (!partial) - goto zeroize; - else - goto partial_output; - } - } else { - /* - * If we've extracted half our pool size in bits - * since the last refresh, try to refresh here. - */ - if (ent->initialized < THRESHOLD_BITS) - fillpool(ent, THRESHOLD_BITS, blocking); - else - fillpool(ent, 0, ISC_FALSE); - - /* - * If we've not initialized with enough good random - * data, seed with our crappy code. - */ - if (ent->initialized < THRESHOLD_BITS) - reseed(ent); - } - - isc_sha1_init(&hash); - isc_sha1_update(&hash, (void *)(ent->pool.pool), - RND_POOLBYTES); - isc_sha1_final(&hash, digest); - - /* - * Stir the extracted data (all of it) back into the pool. - */ - entropypool_adddata(ent, digest, ISC_SHA1_DIGESTLENGTH, 0); - - for (i = 0; i < count; i++) - buf[i] = digest[i] ^ digest[i + RND_ENTROPY_THRESHOLD]; - - buf += count; - remain -= count; - - deltae = count * 8; - deltae = ISC_MIN(deltae, ent->pool.entropy); - total += deltae; - subtract_entropy(ent, deltae); - add_pseudo(ent, count * 8); - } - - partial_output: - isc_safe_memwipe(digest, sizeof(digest)); - - if (returned != NULL) - *returned = (length - remain); - - UNLOCK(&ent->lock); - - return (ISC_R_SUCCESS); - - zeroize: - /* put the entropy we almost extracted back */ - add_entropy(ent, total); - isc_safe_memwipe(data, length); - isc_safe_memwipe(digest, sizeof(digest)); - if (returned != NULL) - *returned = 0; - - UNLOCK(&ent->lock); - - return (ISC_R_NOENTROPY); -} - -static void -isc_entropypool_init(isc_entropypool_t *pool) { - pool->cursor = RND_POOLWORDS - 1; - pool->entropy = 0; - pool->pseudo = 0; - pool->rotate = 0; - memset(pool->pool, 0, RND_POOLBYTES); -} - -static void -isc_entropypool_invalidate(isc_entropypool_t *pool) { - pool->cursor = 0; - pool->entropy = 0; - pool->pseudo = 0; - pool->rotate = 0; - memset(pool->pool, 0, RND_POOLBYTES); -} - -isc_result_t -isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) { - isc_result_t result; - isc_entropy_t *ent; - - REQUIRE(mctx != NULL); - REQUIRE(entp != NULL && *entp == NULL); - - ent = isc_mem_get(mctx, sizeof(isc_entropy_t)); - if (ent == NULL) - return (ISC_R_NOMEMORY); - - /* - * We need a lock. - */ - result = isc_mutex_init(&ent->lock); - if (result != ISC_R_SUCCESS) - goto errout; - - /* - * From here down, no failures will/can occur. - */ - ISC_LIST_INIT(ent->sources); - ent->nextsource = NULL; - ent->nsources = 0; - ent->mctx = NULL; - isc_mem_attach(mctx, &ent->mctx); - ent->refcnt = 1; - ent->initialized = 0; - ent->initcount = 0; - ent->magic = ENTROPY_MAGIC; - - isc_entropypool_init(&ent->pool); - - *entp = ent; - return (ISC_R_SUCCESS); - - errout: - isc_mem_put(mctx, ent, sizeof(isc_entropy_t)); - - return (result); -} - -/*! - * Requires "ent" be locked. - */ -static void -destroysource(isc_entropysource_t **sourcep) { - isc_entropysource_t *source; - isc_entropy_t *ent; - isc_cbsource_t *cbs; - - source = *sourcep; - *sourcep = NULL; - ent = source->ent; - - ISC_LIST_UNLINK(ent->sources, source, link); - ent->nextsource = NULL; - REQUIRE(ent->nsources > 0); - ent->nsources--; - - switch (source->type) { - case ENTROPY_SOURCETYPE_FILE: - if (! source->bad) - destroyfilesource(&source->sources.file); - break; - case ENTROPY_SOURCETYPE_USOCKET: - if (! source->bad) - destroyusocketsource(&source->sources.usocket); - break; - case ENTROPY_SOURCETYPE_SAMPLE: - samplequeue_release(ent, &source->sources.sample.samplequeue); - break; - case ENTROPY_SOURCETYPE_CALLBACK: - cbs = &source->sources.callback; - if (cbs->start_called && cbs->stopfunc != NULL) { - cbs->stopfunc(source, cbs->arg); - cbs->start_called = ISC_FALSE; - } - samplequeue_release(ent, &cbs->samplequeue); - break; - } - - isc_safe_memwipe(source, sizeof(*source)); - isc_mem_put(ent->mctx, source, sizeof(*source)); -} - -static inline isc_boolean_t -destroy_check(isc_entropy_t *ent) { - isc_entropysource_t *source; - - if (ent->refcnt > 0) - return (ISC_FALSE); - - source = ISC_LIST_HEAD(ent->sources); - while (source != NULL) { - switch (source->type) { - case ENTROPY_SOURCETYPE_FILE: - case ENTROPY_SOURCETYPE_USOCKET: - break; - default: - return (ISC_FALSE); - } - source = ISC_LIST_NEXT(source, link); - } - - return (ISC_TRUE); -} - -static void -destroy(isc_entropy_t **entp) { - isc_entropy_t *ent; - isc_entropysource_t *source; - isc_mem_t *mctx; - - REQUIRE(entp != NULL && *entp != NULL); - ent = *entp; - *entp = NULL; - - LOCK(&ent->lock); - - REQUIRE(ent->refcnt == 0); - - /* - * Here, detach non-sample sources. - */ - source = ISC_LIST_HEAD(ent->sources); - while (source != NULL) { - switch(source->type) { - case ENTROPY_SOURCETYPE_FILE: - case ENTROPY_SOURCETYPE_USOCKET: - destroysource(&source); - break; - } - source = ISC_LIST_HEAD(ent->sources); - } - - /* - * If there are other types of sources, we've found a bug. - */ - REQUIRE(ISC_LIST_EMPTY(ent->sources)); - - mctx = ent->mctx; - - isc_entropypool_invalidate(&ent->pool); - - UNLOCK(&ent->lock); - - DESTROYLOCK(&ent->lock); - - isc_safe_memwipe(ent, sizeof(*ent)); - isc_mem_put(mctx, ent, sizeof(*ent)); - isc_mem_detach(&mctx); -} - -void -isc_entropy_destroysource(isc_entropysource_t **sourcep) { - isc_entropysource_t *source; - isc_entropy_t *ent; - isc_boolean_t killit; - - REQUIRE(sourcep != NULL); - REQUIRE(VALID_SOURCE(*sourcep)); - - source = *sourcep; - *sourcep = NULL; - - ent = source->ent; - REQUIRE(VALID_ENTROPY(ent)); - - LOCK(&ent->lock); - - destroysource(&source); - - killit = destroy_check(ent); - - UNLOCK(&ent->lock); - - if (killit) - destroy(&ent); -} - -isc_result_t -isc_entropy_createcallbacksource(isc_entropy_t *ent, - isc_entropystart_t start, - isc_entropyget_t get, - isc_entropystop_t stop, - void *arg, - isc_entropysource_t **sourcep) -{ - isc_result_t result; - isc_entropysource_t *source; - isc_cbsource_t *cbs; - - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(get != NULL); - REQUIRE(sourcep != NULL && *sourcep == NULL); - - LOCK(&ent->lock); - - source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); - if (source == NULL) { - result = ISC_R_NOMEMORY; - goto errout; - } - source->bad = ISC_FALSE; - - cbs = &source->sources.callback; - - result = samplesource_allocate(ent, &cbs->samplequeue); - if (result != ISC_R_SUCCESS) - goto errout; - - cbs->start_called = ISC_FALSE; - cbs->startfunc = start; - cbs->getfunc = get; - cbs->stopfunc = stop; - cbs->arg = arg; - - /* - * From here down, no failures can occur. - */ - source->magic = SOURCE_MAGIC; - source->type = ENTROPY_SOURCETYPE_CALLBACK; - source->ent = ent; - source->total = 0; - memset(source->name, 0, sizeof(source->name)); - ISC_LINK_INIT(source, link); - - /* - * Hook it into the entropy system. - */ - ISC_LIST_APPEND(ent->sources, source, link); - ent->nsources++; - - *sourcep = source; - - UNLOCK(&ent->lock); - return (ISC_R_SUCCESS); - - errout: - if (source != NULL) - isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); - - UNLOCK(&ent->lock); - - return (result); -} - -void -isc_entropy_stopcallbacksources(isc_entropy_t *ent) { - isc_entropysource_t *source; - isc_cbsource_t *cbs; - - REQUIRE(VALID_ENTROPY(ent)); - - LOCK(&ent->lock); - - source = ISC_LIST_HEAD(ent->sources); - while (source != NULL) { - if (source->type == ENTROPY_SOURCETYPE_CALLBACK) { - cbs = &source->sources.callback; - if (cbs->start_called && cbs->stopfunc != NULL) { - cbs->stopfunc(source, cbs->arg); - cbs->start_called = ISC_FALSE; - } - } - - source = ISC_LIST_NEXT(source, link); - } - - UNLOCK(&ent->lock); -} - -isc_result_t -isc_entropy_createsamplesource(isc_entropy_t *ent, - isc_entropysource_t **sourcep) -{ - isc_result_t result; - isc_entropysource_t *source; - sample_queue_t *sq; - - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(sourcep != NULL && *sourcep == NULL); - - LOCK(&ent->lock); - - source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); - if (source == NULL) { - result = ISC_R_NOMEMORY; - goto errout; - } - - sq = &source->sources.sample.samplequeue; - result = samplesource_allocate(ent, sq); - if (result != ISC_R_SUCCESS) - goto errout; - - /* - * From here down, no failures can occur. - */ - source->magic = SOURCE_MAGIC; - source->type = ENTROPY_SOURCETYPE_SAMPLE; - source->ent = ent; - source->total = 0; - memset(source->name, 0, sizeof(source->name)); - ISC_LINK_INIT(source, link); - - /* - * Hook it into the entropy system. - */ - ISC_LIST_APPEND(ent->sources, source, link); - ent->nsources++; - - *sourcep = source; - - UNLOCK(&ent->lock); - return (ISC_R_SUCCESS); - - errout: - if (source != NULL) - isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); - - UNLOCK(&ent->lock); - - return (result); -} - -/*! - * Add a sample, and return ISC_R_SUCCESS if the queue has become full, - * ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the - * queue was full when this function was called. - */ -static isc_result_t -addsample(sample_queue_t *sq, isc_uint32_t sample, isc_uint32_t extra) { - if (sq->nsamples >= RND_EVENTQSIZE) - return (ISC_R_NOMORE); - - sq->samples[sq->nsamples] = sample; - sq->extra[sq->nsamples] = extra; - sq->nsamples++; - - if (sq->nsamples >= RND_EVENTQSIZE) - return (ISC_R_QUEUEFULL); - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample, - isc_uint32_t extra) -{ - isc_entropy_t *ent; - sample_queue_t *sq; - unsigned int entropy; - isc_result_t result; - - REQUIRE(VALID_SOURCE(source)); - - ent = source->ent; - - LOCK(&ent->lock); - - sq = &source->sources.sample.samplequeue; - result = addsample(sq, sample, extra); - if (result == ISC_R_QUEUEFULL) { - entropy = crunchsamples(ent, sq); - add_entropy(ent, entropy); - } - - UNLOCK(&ent->lock); - - return (result); -} - -isc_result_t -isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample, - isc_uint32_t extra) -{ - sample_queue_t *sq; - isc_result_t result; - - REQUIRE(VALID_SOURCE(source)); - REQUIRE(source->type == ENTROPY_SOURCETYPE_CALLBACK); - - sq = &source->sources.callback.samplequeue; - result = addsample(sq, sample, extra); - - return (result); -} - -void -isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length, - isc_uint32_t entropy) -{ - REQUIRE(VALID_ENTROPY(ent)); - - LOCK(&ent->lock); - - entropypool_adddata(ent, data, length, entropy); - - if (ent->initialized < THRESHOLD_BITS) - ent->initialized = THRESHOLD_BITS; - - UNLOCK(&ent->lock); -} - -static void -dumpstats(isc_entropy_t *ent, FILE *out) { - fprintf(out, - isc_msgcat_get(isc_msgcat, ISC_MSGSET_ENTROPY, - ISC_MSG_ENTROPYSTATS, - "Entropy pool %p: refcnt %u cursor %u," - " rotate %u entropy %u pseudo %u nsources %u" - " nextsource %p initialized %u initcount %u\n"), - ent, ent->refcnt, - ent->pool.cursor, ent->pool.rotate, - ent->pool.entropy, ent->pool.pseudo, - ent->nsources, ent->nextsource, ent->initialized, - ent->initcount); -} - -/* - * This function ignores locking. Use at your own risk. - */ -void -isc_entropy_stats(isc_entropy_t *ent, FILE *out) { - REQUIRE(VALID_ENTROPY(ent)); - - LOCK(&ent->lock); - dumpstats(ent, out); - UNLOCK(&ent->lock); -} - -unsigned int -isc_entropy_status(isc_entropy_t *ent) { - unsigned int estimate; - - LOCK(&ent->lock); - estimate = ent->pool.entropy; - UNLOCK(&ent->lock); - - return estimate; -} - -void -isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) { - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(entp != NULL && *entp == NULL); - - LOCK(&ent->lock); - - ent->refcnt++; - *entp = ent; - - UNLOCK(&ent->lock); -} - -void -isc_entropy_detach(isc_entropy_t **entp) { - isc_entropy_t *ent; - isc_boolean_t killit; - - REQUIRE(entp != NULL && VALID_ENTROPY(*entp)); - ent = *entp; - *entp = NULL; - - LOCK(&ent->lock); - - REQUIRE(ent->refcnt > 0); - ent->refcnt--; - - killit = destroy_check(ent); - - UNLOCK(&ent->lock); - - if (killit) - destroy(&ent); -} - -static isc_result_t -kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { - /* - * The intent of "first" is to provide a warning message only once - * during the run of a program that might try to gather keyboard - * entropy multiple times. - */ - static isc_boolean_t first = ISC_TRUE; - - UNUSED(arg); - - if (! blocking) - return (ISC_R_NOENTROPY); - - if (first) { - if (source->warn_keyboard) - fprintf(stderr, "You must use the keyboard to create " - "entropy, since your system is lacking\n" - "/dev/random (or equivalent)\n\n"); - first = ISC_FALSE; - } - fprintf(stderr, "start typing:\n"); - - return (isc_keyboard_open(&source->kbd)); -} - -static void -kbdstop(isc_entropysource_t *source, void *arg) { - - UNUSED(arg); - - if (! isc_keyboard_canceled(&source->kbd)) - fprintf(stderr, "stop typing.\r\n"); - - (void)isc_keyboard_close(&source->kbd, 3); -} - -static isc_result_t -kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) { - isc_result_t result; - isc_time_t t; - isc_uint32_t sample; - isc_uint32_t extra; - unsigned char c; - - UNUSED(arg); - - if (!blocking) - return (ISC_R_NOTBLOCKING); - - result = isc_keyboard_getchar(&source->kbd, &c); - if (result != ISC_R_SUCCESS) - return (result); - - TIME_NOW(&t); - - sample = isc_time_nanoseconds(&t); - extra = c; - - result = isc_entropy_addcallbacksample(source, sample, extra); - if (result != ISC_R_SUCCESS) { - fprintf(stderr, "\r\n"); - return (result); - } - - fprintf(stderr, "."); - fflush(stderr); - - return (result); -} - -isc_result_t -isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, - const char *randomfile, int use_keyboard) -{ - isc_result_t result; - isc_result_t final_result = ISC_R_NOENTROPY; - isc_boolean_t userfile = ISC_TRUE; - - REQUIRE(VALID_ENTROPY(ectx)); - REQUIRE(source != NULL && *source == NULL); - REQUIRE(use_keyboard == ISC_ENTROPY_KEYBOARDYES || - use_keyboard == ISC_ENTROPY_KEYBOARDNO || - use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE); - -#ifdef PATH_RANDOMDEV - if (randomfile == NULL) { - randomfile = PATH_RANDOMDEV; - userfile = ISC_FALSE; - } -#endif - - if (randomfile != NULL && use_keyboard != ISC_ENTROPY_KEYBOARDYES) { - result = isc_entropy_createfilesource(ectx, randomfile); - if (result == ISC_R_SUCCESS && - use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE) - use_keyboard = ISC_ENTROPY_KEYBOARDNO; - if (result != ISC_R_SUCCESS && userfile) - return (result); - - final_result = result; - } - - if (use_keyboard != ISC_ENTROPY_KEYBOARDNO) { - result = isc_entropy_createcallbacksource(ectx, kbdstart, - kbdget, kbdstop, - NULL, source); - if (result == ISC_R_SUCCESS) - (*source)->warn_keyboard = - ISC_TF(use_keyboard == - ISC_ENTROPY_KEYBOARDMAYBE); - - if (final_result != ISC_R_SUCCESS) - final_result = result; - } - - /* - * final_result is ISC_R_SUCCESS if at least one source of entropy - * could be started, otherwise it is the error from the most recently - * failed operation (or ISC_R_NOENTROPY if PATH_RANDOMDEV is not - * defined and use_keyboard is ISC_ENTROPY_KEYBOARDNO). - */ - return (final_result); -} diff --git a/usr.sbin/bind/lib/isc/hash.c b/usr.sbin/bind/lib/isc/hash.c index c09f21c3af2..0e9d2ffb1e1 100644 --- a/usr.sbin/bind/lib/isc/hash.c +++ b/usr.sbin/bind/lib/isc/hash.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: hash.c,v 1.6 2019/12/17 01:46:34 sthen Exp $ */ +/* $Id: hash.c,v 1.7 2020/01/09 14:24:08 florian Exp $ */ /*! \file * Some portion of this code was derived from universal hash function @@ -56,14 +56,14 @@ if advised of the possibility of such damage. */ #include <config.h> +#include <stdlib.h> -#include <isc/entropy.h> #include <isc/hash.h> #include <isc/mem.h> #include <isc/magic.h> #include <isc/mutex.h> #include <isc/once.h> -#include <isc/random.h> + #include <isc/refcount.h> #include <isc/string.h> #include <isc/util.h> @@ -92,7 +92,6 @@ struct isc_hash { isc_mutex_t lock; isc_boolean_t initialized; isc_refcount_t refcnt; - isc_entropy_t *entropy; /*%< entropy source */ size_t limit; /*%< upper limit of key length */ size_t vectorlen; /*%< size of the vector below */ hash_random_t *rndvector; /*%< random vector for universal hashing */ @@ -138,8 +137,7 @@ static unsigned char maptolower[] = { }; isc_result_t -isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, - size_t limit, isc_hash_t **hctxp) +isc_hash_ctxcreate(isc_mem_t *mctx, size_t limit, isc_hash_t **hctxp) { isc_result_t result; isc_hash_t *hctx; @@ -188,14 +186,10 @@ isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, result = isc_refcount_init(&hctx->refcnt, 1); if (result != ISC_R_SUCCESS) goto cleanup_lock; - hctx->entropy = NULL; hctx->limit = limit; hctx->vectorlen = vlen; hctx->rndvector = rv; - if (entropy != NULL) - isc_entropy_attach(entropy, &hctx->entropy); - *hctxp = hctx; return (ISC_R_SUCCESS); @@ -215,7 +209,7 @@ initialize_lock(void) { } isc_result_t -isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) { +isc_hash_create(isc_mem_t *mctx, size_t limit) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(mctx != NULL); @@ -226,7 +220,7 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) { LOCK(&createlock); if (hash == NULL) - result = isc_hash_ctxcreate(mctx, entropy, limit, &hash); + result = isc_hash_ctxcreate(mctx, limit, &hash); UNLOCK(&createlock); @@ -240,33 +234,7 @@ isc_hash_ctxinit(isc_hash_t *hctx) { if (hctx->initialized == ISC_TRUE) goto out; - if (hctx->entropy != NULL) { - isc_result_t result; - - result = isc_entropy_getdata(hctx->entropy, - hctx->rndvector, - (unsigned int)hctx->vectorlen, - NULL, 0); - INSIST(result == ISC_R_SUCCESS); - } else { - isc_uint32_t pr; - size_t i, copylen; - unsigned char *p; - - p = (unsigned char *)hctx->rndvector; - for (i = 0; i < hctx->vectorlen; i += copylen, p += copylen) { - isc_random_get(&pr); - if (i + sizeof(pr) <= hctx->vectorlen) - copylen = sizeof(pr); - else - copylen = hctx->vectorlen - i; - - memmove(p, &pr, copylen); - } - INSIST(p == (unsigned char *)hctx->rndvector + - hctx->vectorlen); - } - + arc4random_buf(hctx->rndvector, hctx->vectorlen); hctx->initialized = ISC_TRUE; out: @@ -303,8 +271,6 @@ destroy(isc_hash_t **hctxp) { isc_refcount_destroy(&hctx->refcnt); mctx = hctx->mctx; - if (hctx->entropy != NULL) - isc_entropy_detach(&hctx->entropy); if (hctx->rndvector != NULL) isc_mem_put(mctx, hctx->rndvector, hctx->vectorlen); @@ -414,7 +380,7 @@ fnv_initialize(void) { * again, it should not change fnv_offset_basis. */ while (fnv_offset_basis == 0) { - isc_random_get(&fnv_offset_basis); + fnv_offset_basis = arc4random(); } } diff --git a/usr.sbin/bind/lib/isc/include/isc/Makefile.in b/usr.sbin/bind/lib/isc/include/isc/Makefile.in index 5d69055e660..d36c4064102 100644 --- a/usr.sbin/bind/lib/isc/include/isc/Makefile.in +++ b/usr.sbin/bind/lib/isc/include/isc/Makefile.in @@ -25,7 +25,7 @@ VERSION=@BIND9_VERSION@ # HEADERS = aes.h app.h assertions.h base32.h base64.h \ bind9.h boolean.h buffer.h bufferlist.h \ - commandline.h counter.h crc64.h entropy.h errno.h error.h \ + commandline.h counter.h crc64.h errno.h error.h \ event.h eventclass.h file.h formatcheck.h fsaccess.h \ hash.h heap.h hex.h hmacmd5.h hmacsha.h httpd.h \ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h json.h \ @@ -33,7 +33,7 @@ HEADERS = aes.h app.h assertions.h base32.h base64.h \ magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \ netaddr.h netscope.h ondestroy.h os.h parseint.h \ pool.h portset.h print.h queue.h quota.h \ - radix.h random.h ratelimiter.h refcount.h regex.h \ + radix.h ratelimiter.h refcount.h regex.h \ region.h resource.h result.h resultclass.h rwlock.h \ safe.h serial.h sha1.h sha2.h sockaddr.h socket.h \ stats.h stdio.h stdlib.h string.h symtab.h task.h \ diff --git a/usr.sbin/bind/lib/isc/include/isc/entropy.h b/usr.sbin/bind/lib/isc/include/isc/entropy.h deleted file mode 100644 index 301ac946ab8..00000000000 --- a/usr.sbin/bind/lib/isc/include/isc/entropy.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC 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. - */ - -/* $Id: entropy.h,v 1.3 2019/12/17 01:46:35 sthen Exp $ */ - -#ifndef ISC_ENTROPY_H -#define ISC_ENTROPY_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file isc/entropy.h - * \brief The entropy API - * - * \li MP: - * The entropy object is locked internally. All callbacks into - * application-provided functions (for setup, gathering, and - * shutdown of sources) are guaranteed to be called with the - * entropy API lock held. This means these functions are - * not permitted to call back into the entropy API. - * - * \li Reliability: - * No anticipated impact. - * - * \li Resources: - * A buffer, used as an entropy pool. - * - * \li Security: - * While this code is believed to implement good entropy gathering - * and distribution, it has not been reviewed by a cryptographic - * expert. - * Since the added entropy is only as good as the sources used, - * this module could hand out bad data and never know it. - * - * \li Standards: - * None. - */ - -/*** - *** Imports - ***/ - -#include <stdio.h> - -#include <isc/lang.h> -#include <isc/types.h> - -/*@{*/ -/*% Entropy callback function. */ -typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source, - void *arg, isc_boolean_t blocking); -typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source, - void *arg, isc_boolean_t blocking); -typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg); -/*@}*/ - -/*** - *** Flags. - ***/ - -/*! - * \brief - * Extract only "good" data; return failure if there is not enough - * data available and there are no sources which we can poll to get - * data, or those sources are empty. - * - * - */ -#define ISC_ENTROPY_GOODONLY 0x00000001U -/*! - * \brief - * Extract as much good data as possible, but if there isn't enough - * at hand, return what is available. This flag only makes sense - * when used with _GOODONLY. - */ -#define ISC_ENTROPY_PARTIAL 0x00000002U -/*! - * \brief - * Block the task until data is available. This is contrary to the - * ISC task system, where tasks should never block. However, if - * this is a special purpose application where blocking a task is - * acceptable (say, an offline zone signer) this flag may be set. - * This flag only makes sense when used with _GOODONLY, and will - * block regardless of the setting for _PARTIAL. - */ -#define ISC_ENTROPY_BLOCKING 0x00000004U - -/*! - * \brief - * Estimate the amount of entropy contained in the sample pool. - * If this is not set, the source will be gathered and periodically - * mixed into the entropy pool, but no increment in contained entropy - * will be assumed. This flag only makes sense on sample sources. - */ -#define ISC_ENTROPYSOURCE_ESTIMATE 0x00000001U - -/* - * For use with isc_entropy_usebestsource(). - */ -/*! - * \brief - * Use the keyboard as the only entropy source. - */ -#define ISC_ENTROPY_KEYBOARDYES 1 -/*! - * \brief - * Never use the keyboard as an entropy source. - */ -#define ISC_ENTROPY_KEYBOARDNO 2 -/*! - * \brief - * Use the keyboard as an entropy source only if opening the - * random device fails. - */ -#define ISC_ENTROPY_KEYBOARDMAYBE 3 - -ISC_LANG_BEGINDECLS - -/*** - *** Functions - ***/ - -isc_result_t -isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp); -/*!< - * \brief Create a new entropy object. - */ - -void -isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp); -/*!< - * Attaches to an entropy object. - */ - -void -isc_entropy_detach(isc_entropy_t **entp); -/*!< - * \brief Detaches from an entropy object. - */ - -isc_result_t -isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname); -/*!< - * \brief Create a new entropy source from a file. - * - * The file is assumed to contain good randomness, and will be mixed directly - * into the pool with every byte adding 8 bits of entropy. - * - * The file will be put into non-blocking mode, so it may be a device file, - * such as /dev/random. /dev/urandom should not be used here if it can - * be avoided, since it will always provide data even if it isn't good. - * We will make as much pseudorandom data as we need internally if our - * caller asks for it. - * - * If we hit end-of-file, we will stop reading from this source. Callers - * who require strong random data will get failure when our pool drains. - * The file will never be opened/read again once EOF is reached. - */ - -void -isc_entropy_destroysource(isc_entropysource_t **sourcep); -/*!< - * \brief Removes an entropy source from the entropy system. - */ - -isc_result_t -isc_entropy_createsamplesource(isc_entropy_t *ent, - isc_entropysource_t **sourcep); -/*!< - * \brief Create an entropy source that consists of samples. Each sample is - * added to the source via isc_entropy_addsamples(), below. - */ - -isc_result_t -isc_entropy_createcallbacksource(isc_entropy_t *ent, - isc_entropystart_t start, - isc_entropyget_t get, - isc_entropystop_t stop, - void *arg, - isc_entropysource_t **sourcep); -/*!< - * \brief Create an entropy source that is polled via a callback. - * - * This would - * be used when keyboard input is used, or a GUI input method. It can - * also be used to hook in any external entropy source. - * - * Samples are added via isc_entropy_addcallbacksample(), below. - * _addcallbacksample() is the only function which may be called from - * within an entropy API callback function. - */ - -void -isc_entropy_stopcallbacksources(isc_entropy_t *ent); -/*!< - * \brief Call the stop functions for callback sources that have had their - * start functions called. - */ - -/*@{*/ -isc_result_t -isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample, - isc_uint32_t extra); -isc_result_t -isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample, - isc_uint32_t extra); -/*!< - * \brief Add a sample to the sample source. - * - * The sample MUST be a timestamp - * that increases over time, with the exception of wrap-around for - * extremely high resolution timers which will quickly wrap-around - * a 32-bit integer. - * - * The "extra" parameter is used only to add a bit more unpredictable - * data. It is not used other than included in the hash of samples. - * - * When in an entropy API callback function, _addcallbacksource() must be - * used. At all other times, _addsample() must be used. - */ -/*@}*/ - -isc_result_t -isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, - unsigned int *returned, unsigned int flags); -/*!< - * \brief Extract data from the entropy pool. This may load the pool from various - * sources. - * - * Do this by stiring the pool and returning a part of hash as randomness. - * Note that no secrets are given away here since parts of the hash are - * xored together before returned. - * - * Honor the request from the caller to only return good data, any data, - * etc. - */ - -void -isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length, - isc_uint32_t entropy); -/*!< - * \brief Add "length" bytes in "data" to the entropy pool, incrementing the - * pool's entropy count by "entropy." - * - * These bytes will prime the pseudorandom portion even if no entropy is - * actually added. - */ - -void -isc_entropy_stats(isc_entropy_t *ent, FILE *out); -/*!< - * \brief Dump some (trivial) stats to the stdio stream "out". - */ - -unsigned int -isc_entropy_status(isc_entropy_t *end); -/* - * Returns the number of bits the pool currently contains. This is just - * an estimate. - */ - -isc_result_t -isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, - const char *randomfile, int use_keyboard); -/*!< - * \brief Use whatever source of entropy is best. - * - * Notes: - *\li If "randomfile" is not NULL, open it with - * isc_entropy_createfilesource(). - * - *\li If "randomfile" is NULL and the system's random device was detected - * when the program was configured and built, open that device with - * isc_entropy_createfilesource(). - * - *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDYES, then always open - * the keyboard as an entropy source (possibly in addition to - * "randomfile" or the random device). - * - *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only - * if opening the random file/device fails. A message will be - * printed describing the need for keyboard input. - * - *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDNO, the keyboard will - * never be opened. - * - * Returns: - *\li #ISC_R_SUCCESS if at least one source of entropy could be started. - * - *\li #ISC_R_NOENTROPY if use_keyboard is #ISC_ENTROPY_KEYBOARDNO and - * there is no random device pathname compiled into the program. - * - *\li A return code from isc_entropy_createfilesource() or - * isc_entropy_createcallbacksource(). - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_ENTROPY_H */ diff --git a/usr.sbin/bind/lib/isc/include/isc/hash.h b/usr.sbin/bind/lib/isc/include/isc/hash.h index 415dc8042bf..1d5348d32bc 100644 --- a/usr.sbin/bind/lib/isc/include/isc/hash.h +++ b/usr.sbin/bind/lib/isc/include/isc/hash.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: hash.h,v 1.5 2019/12/17 01:46:35 sthen Exp $ */ +/* $Id: hash.h,v 1.6 2020/01/09 14:24:08 florian Exp $ */ #ifndef ISC_HASH_H #define ISC_HASH_H 1 @@ -83,10 +83,9 @@ ISC_LANG_BEGINDECLS isc_result_t -isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit, - isc_hash_t **hctx); +isc_hash_ctxcreate(isc_mem_t *mctx, size_t limit, isc_hash_t **hctx); isc_result_t -isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit); +isc_hash_create(isc_mem_t *mctx, size_t limit); /*!< * \brief Create a new hash object. * @@ -95,10 +94,6 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit); * isc_hash_create() creates a module-internal object to support the * single-context mode. It should be called only once. * - * 'entropy' must be NULL or a valid entropy object. If 'entropy' is NULL, - * pseudo random values will be used to build the random vector, which may - * weaken security. - * * 'limit' specifies the maximum number of hash keys. If it is too large, * these functions may fail. */ diff --git a/usr.sbin/bind/lib/isc/include/isc/random.h b/usr.sbin/bind/lib/isc/include/isc/random.h deleted file mode 100644 index 1dfe59d9970..00000000000 --- a/usr.sbin/bind/lib/isc/include/isc/random.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC 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. - */ - -/* $Id: random.h,v 1.4 2019/12/17 01:46:35 sthen Exp $ */ - -#ifndef ISC_RANDOM_H -#define ISC_RANDOM_H 1 - -#include <isc/lang.h> -#include <isc/types.h> - -/*! \file isc/random.h - * \brief Implements a random state pool which will let the caller return a - * series of possibly non-reproducible random values. - * - * Note that the - * strength of these numbers is not all that high, and should not be - * used in cryptography functions. It is useful for jittering values - * a bit here and there, such as timeouts, etc. - */ - -ISC_LANG_BEGINDECLS - -void -isc_random_seed(isc_uint32_t seed); -/*%< - * Set the initial seed of the random state. - */ - -void -isc_random_get(isc_uint32_t *val); -/*%< - * Get a random value. - * - * Requires: - * val != NULL. - */ - -isc_uint32_t -isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter); -/*%< - * Get a random value between (max - jitter) and (max). - * This is useful for jittering timer values. - */ - -ISC_LANG_ENDDECLS - -#endif /* ISC_RANDOM_H */ diff --git a/usr.sbin/bind/lib/isc/include/isc/types.h b/usr.sbin/bind/lib/isc/include/isc/types.h index 54ddb07574c..c3550e27970 100644 --- a/usr.sbin/bind/lib/isc/include/isc/types.h +++ b/usr.sbin/bind/lib/isc/include/isc/types.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.7 2020/01/07 19:11:17 florian Exp $ */ +/* $Id: types.h,v 1.8 2020/01/09 14:24:08 florian Exp $ */ #ifndef ISC_TYPES_H #define ISC_TYPES_H 1 @@ -48,8 +48,6 @@ typedef struct isc_constregion isc_constregion_t; /*%< Const region */ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */ typedef struct isc_counter isc_counter_t; /*%< Counter */ typedef isc_int16_t isc_dscp_t; /*%< Diffserv code point */ -typedef struct isc_entropy isc_entropy_t; /*%< Entropy */ -typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */ typedef struct isc_event isc_event_t; /*%< Event */ typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */ typedef unsigned int isc_eventtype_t; /*%< Event Type */ diff --git a/usr.sbin/bind/lib/isc/pool.c b/usr.sbin/bind/lib/isc/pool.c index a8b1578318d..56fb49f093e 100644 --- a/usr.sbin/bind/lib/isc/pool.c +++ b/usr.sbin/bind/lib/isc/pool.c @@ -14,16 +14,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: pool.c,v 1.2 2019/12/17 01:46:34 sthen Exp $ */ +/* $Id: pool.c,v 1.3 2020/01/09 14:24:08 florian Exp $ */ /*! \file */ #include <config.h> - +#include <stdlib.h> #include <string.h> #include <isc/mem.h> -#include <isc/random.h> + #include <isc/pool.h> #include <isc/util.h> @@ -104,9 +104,7 @@ isc_pool_create(isc_mem_t *mctx, unsigned int count, void * isc_pool_get(isc_pool_t *pool) { - isc_uint32_t i; - isc_random_get(&i); - return (pool->pool[i % pool->count]); + return (pool->pool[arc4random_uniform(pool->count)]); } int diff --git a/usr.sbin/bind/lib/isc/random.c b/usr.sbin/bind/lib/isc/random.c deleted file mode 100644 index 888fa1da1da..00000000000 --- a/usr.sbin/bind/lib/isc/random.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC 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. - */ - -/* $Id: random.c,v 1.11 2019/12/17 01:46:34 sthen Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <stdlib.h> -#include <time.h> /* Required for time(). */ -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <isc/mutex.h> -#include <isc/once.h> -#include <isc/random.h> -#include <isc/string.h> -#include <isc/util.h> - -static isc_once_t once = ISC_ONCE_INIT; - -static void -initialize_rand(void) -{ -#ifndef HAVE_ARC4RANDOM - unsigned int pid = getpid(); - - /* - * The low bits of pid generally change faster. - * Xor them with the high bits of time which change slowly. - */ - pid = ((pid << 16) & 0xffff0000) | ((pid >> 16) & 0xffff); - - srand((unsigned)time(NULL) ^ pid); -#endif -} - -static void -initialize(void) -{ - RUNTIME_CHECK(isc_once_do(&once, initialize_rand) == ISC_R_SUCCESS); -} - -void -isc_random_seed(isc_uint32_t seed) -{ - initialize(); - -#ifndef HAVE_ARC4RANDOM - srand(seed); -#elif defined(HAVE_ARC4RANDOM_STIR) - /* Formally not necessary... */ - UNUSED(seed); - arc4random_stir(); -#elif defined(HAVE_ARC4RANDOM_ADDRANDOM) - arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); -#else - /* - * If arc4random() is available and no corresponding seeding - * function arc4random_addrandom() is available, no seeding is - * done on such platforms (e.g., OpenBSD 5.5). This is because - * the OS itself is supposed to seed the RNG and it is assumed - * that no explicit seeding is required. - */ - UNUSED(seed); -#endif -} - -void -isc_random_get(isc_uint32_t *val) -{ - REQUIRE(val != NULL); - - initialize(); - -#ifndef HAVE_ARC4RANDOM - /* - * rand()'s lower bits are not random. - * rand()'s upper bit is zero. - */ -#if RAND_MAX >= 0xfffff - /* We have at least 20 bits. Use lower 16 excluding lower most 4 */ - *val = ((((unsigned int)rand()) & 0xffff0) >> 4) | - ((((unsigned int)rand()) & 0xffff0) << 12); -#elif RAND_MAX >= 0x7fff - /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */ - *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) | - ((rand() << 18) & 0xffc00000); -#else -#error RAND_MAX is too small -#endif -#else - *val = arc4random(); -#endif -} - -isc_uint32_t -isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) { - isc_uint32_t rnd; - - REQUIRE(jitter < max || (jitter == 0 && max == 0)); - - if (jitter == 0) - return (max); - - isc_random_get(&rnd); - return (max - rnd % jitter); -} diff --git a/usr.sbin/bind/lib/isc/taskpool.c b/usr.sbin/bind/lib/isc/taskpool.c index 05a784dafdf..5f42e6b2b1c 100644 --- a/usr.sbin/bind/lib/isc/taskpool.c +++ b/usr.sbin/bind/lib/isc/taskpool.c @@ -14,14 +14,15 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: taskpool.c,v 1.3 2019/12/17 01:46:34 sthen Exp $ */ +/* $Id: taskpool.c,v 1.4 2020/01/09 14:24:08 florian Exp $ */ /*! \file */ #include <config.h> +#include <stdlib.h> #include <isc/mem.h> -#include <isc/random.h> + #include <isc/taskpool.h> #include <isc/util.h> @@ -101,9 +102,7 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx, void isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) { - isc_uint32_t i; - isc_random_get(&i); - isc_task_attach(pool->tasks[i % pool->ntasks], targetp); + isc_task_attach(pool->tasks[arc4random_uniform(pool->ntasks)], targetp); } int diff --git a/usr.sbin/bind/lib/isc/unix/Makefile.in b/usr.sbin/bind/lib/isc/unix/Makefile.in index 5194745155a..3384f95ea79 100644 --- a/usr.sbin/bind/lib/isc/unix/Makefile.in +++ b/usr.sbin/bind/lib/isc/unix/Makefile.in @@ -27,7 +27,7 @@ CWARNINGS = # Alphabetically OBJS = @ISC_IPV6_O@ @ISC_PK11_API_O@ \ - app.@O@ dir.@O@ entropy.@O@ errno.@O@ errno2result.@O@ \ + app.@O@ dir.@O@ errno.@O@ errno2result.@O@ \ file.@O@ fsaccess.@O@ interfaceiter.@O@ \ keyboard.@O@ net.@O@ \ os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \ @@ -35,7 +35,7 @@ OBJS = @ISC_IPV6_O@ @ISC_PK11_API_O@ \ # Alphabetically SRCS = @ISC_IPV6_C@ @ISC_PK11_API_C@ \ - app.c dir.c entropy.c errno.c errno2result.c file.c \ + app.c dir.c errno.c errno2result.c file.c \ fsaccess.c interfaceiter.c keyboard.c net.c \ os.c resource.c socket.c stdio.c stdtime.c \ strerror.c syslog.c time.c diff --git a/usr.sbin/bind/lib/isc/unix/entropy.c b/usr.sbin/bind/lib/isc/unix/entropy.c deleted file mode 100644 index 09f2e8ece72..00000000000 --- a/usr.sbin/bind/lib/isc/unix/entropy.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC 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. - */ - -/* $Id: entropy.c,v 1.11 2020/01/09 14:18:30 florian Exp $ */ - -/* \file unix/entropy.c - * \brief - * This is the system dependent part of the ISC entropy API. - */ - -#include <config.h> - -#include <sys/param.h> /* Openserver 5.0.6A and FD_SETSIZE */ -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#ifdef HAVE_NANOSLEEP -#include <time.h> -#endif -#include <unistd.h> - -#include <isc/platform.h> - -#include <isc/strerror.h> -#include <isc/string.h> - -#include <sys/select.h> - -#include "errno2result.h" - -/*% - * There is only one variable in the entropy data structures that is not - * system independent, but pulling the structure that uses it into this file - * ultimately means pulling several other independent structures here also to - * resolve their interdependencies. Thus only the problem variable's type - * is defined here. - */ -#define FILESOURCE_HANDLE_TYPE int - -typedef struct { - int handle; - enum { - isc_usocketsource_disconnected, - isc_usocketsource_connecting, - isc_usocketsource_connected, - isc_usocketsource_ndesired, - isc_usocketsource_wrote, - isc_usocketsource_reading - } status; - size_t sz_to_recv; -} isc_entropyusocketsource_t; - -#include "../entropy.c" - -static unsigned int -get_from_filesource(isc_entropysource_t *source, isc_uint32_t desired) { - isc_entropy_t *ent = source->ent; - unsigned char buf[128]; - int fd = source->sources.file.handle; - ssize_t n, ndesired; - unsigned int added; - - if (source->bad) - return (0); - - desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); - - added = 0; - while (desired > 0) { - ndesired = ISC_MIN(desired, sizeof(buf)); - n = read(fd, buf, ndesired); - if (n < 0) { - if (errno == EAGAIN || errno == EINTR) - goto out; - goto err; - } - if (n == 0) - goto err; - - entropypool_adddata(ent, buf, n, n * 8); - added += n * 8; - desired -= n; - } - goto out; - - err: - (void)close(fd); - source->sources.file.handle = -1; - source->bad = ISC_TRUE; - - out: - return (added); -} - -static unsigned int -get_from_usocketsource(isc_entropysource_t *source, isc_uint32_t desired) { - isc_entropy_t *ent = source->ent; - unsigned char buf[128]; - int fd = source->sources.usocket.handle; - ssize_t n = 0, ndesired; - unsigned int added; - size_t sz_to_recv = source->sources.usocket.sz_to_recv; - - if (source->bad) - return (0); - - desired = desired / 8 + (((desired & 0x07) > 0) ? 1 : 0); - - added = 0; - while (desired > 0) { - ndesired = ISC_MIN(desired, sizeof(buf)); - eagain_loop: - - switch ( source->sources.usocket.status ) { - case isc_usocketsource_ndesired: - buf[0] = ndesired; - if ((n = sendto(fd, buf, 1, 0, NULL, 0)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNRESET) - goto out; - goto err; - } - INSIST(n == 1); - source->sources.usocket.status = - isc_usocketsource_wrote; - goto eagain_loop; - - case isc_usocketsource_connecting: - case isc_usocketsource_connected: - buf[0] = 1; - buf[1] = ndesired; - if ((n = sendto(fd, buf, 2, 0, NULL, 0)) < 0) { - if (errno == EWOULDBLOCK || errno == EINTR || - errno == ECONNRESET) - goto out; - goto err; - } - if (n == 1) { - source->sources.usocket.status = - isc_usocketsource_ndesired; - goto eagain_loop; - } - INSIST(n == 2); - source->sources.usocket.status = - isc_usocketsource_wrote; - /* FALLTHROUGH */ - - case isc_usocketsource_wrote: - if (recvfrom(fd, buf, 1, 0, NULL, NULL) != 1) { - if (errno == EAGAIN) { - /* - * The problem of EAGAIN (try again - * later) is a major issue on HP-UX. - * Solaris actually tries the recvfrom - * call again, while HP-UX just dies. - * This code is an attempt to let the - * entropy pool fill back up (at least - * that's what I think the problem is.) - * We go to eagain_loop because if we - * just "break", then the "desired" - * amount gets borked. - */ -#ifdef HAVE_NANOSLEEP - struct timespec ts; - - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); -#else - usleep(1000); -#endif - goto eagain_loop; - } - if (errno == EWOULDBLOCK || errno == EINTR) - goto out; - goto err; - } - source->sources.usocket.status = - isc_usocketsource_reading; - sz_to_recv = buf[0]; - source->sources.usocket.sz_to_recv = sz_to_recv; - if (sz_to_recv > sizeof(buf)) - goto err; - /* FALLTHROUGH */ - - case isc_usocketsource_reading: - if (sz_to_recv != 0U) { - n = recv(fd, buf, sz_to_recv, 0); - if (n < 0) { - if (errno == EWOULDBLOCK || - errno == EINTR) - goto out; - goto err; - } - } else - n = 0; - break; - - default: - goto err; - } - - if ((size_t)n != sz_to_recv) - source->sources.usocket.sz_to_recv -= n; - else - source->sources.usocket.status = - isc_usocketsource_connected; - - if (n == 0) - goto out; - - entropypool_adddata(ent, buf, n, n * 8); - added += n * 8; - desired -= n; - } - goto out; - - err: - close(fd); - source->bad = ISC_TRUE; - source->sources.usocket.status = isc_usocketsource_disconnected; - source->sources.usocket.handle = -1; - - out: - return (added); -} - -/* - * Poll each source, trying to get data from it to stuff into the entropy - * pool. - */ -static void -fillpool(isc_entropy_t *ent, unsigned int desired, isc_boolean_t blocking) { - unsigned int added; - unsigned int remaining; - unsigned int needed; - unsigned int nsource; - isc_entropysource_t *source; - - REQUIRE(VALID_ENTROPY(ent)); - - needed = desired; - - /* - * This logic is a little strange, so an explanation is in order. - * - * If needed is 0, it means we are being asked to "fill to whatever - * we think is best." This means that if we have at least a - * partially full pool (say, > 1/4th of the pool) we probably don't - * need to add anything. - * - * Also, we will check to see if the "pseudo" count is too high. - * If it is, try to mix in better data. Too high is currently - * defined as 1/4th of the pool. - * - * Next, if we are asked to add a specific bit of entropy, make - * certain that we will do so. Clamp how much we try to add to - * (DIGEST_SIZE * 8 < needed < POOLBITS - entropy). - * - * Note that if we are in a blocking mode, we will only try to - * get as much data as we need, not as much as we might want - * to build up. - */ - if (needed == 0) { - REQUIRE(!blocking); - - if ((ent->pool.entropy >= RND_POOLBITS / 4) - && (ent->pool.pseudo <= RND_POOLBITS / 4)) - return; - - needed = THRESHOLD_BITS * 4; - } else { - needed = ISC_MAX(needed, THRESHOLD_BITS); - needed = ISC_MIN(needed, RND_POOLBITS); - } - - /* - * In any case, clamp how much we need to how much we can add. - */ - needed = ISC_MIN(needed, RND_POOLBITS - ent->pool.entropy); - - /* - * But wait! If we're not yet initialized, we need at least - * THRESHOLD_BITS - * of randomness. - */ - if (ent->initialized < THRESHOLD_BITS) - needed = ISC_MAX(needed, THRESHOLD_BITS - ent->initialized); - - /* - * Poll each file source to see if we can read anything useful from - * it. XXXMLG When where are multiple sources, we should keep a - * record of which one we last used so we can start from it (or the - * next one) to avoid letting some sources build up entropy while - * others are always drained. - */ - - added = 0; - remaining = needed; - if (ent->nextsource == NULL) { - ent->nextsource = ISC_LIST_HEAD(ent->sources); - if (ent->nextsource == NULL) - return; - } - source = ent->nextsource; - again_file: - for (nsource = 0; nsource < ent->nsources; nsource++) { - unsigned int got; - - if (remaining == 0) - break; - - got = 0; - - switch ( source->type ) { - case ENTROPY_SOURCETYPE_FILE: - got = get_from_filesource(source, remaining); - break; - - case ENTROPY_SOURCETYPE_USOCKET: - got = get_from_usocketsource(source, remaining); - break; - } - - added += got; - - remaining -= ISC_MIN(remaining, got); - - source = ISC_LIST_NEXT(source, link); - if (source == NULL) - source = ISC_LIST_HEAD(ent->sources); - } - ent->nextsource = source; - - if (blocking && remaining != 0) { - int fds; - - fds = wait_for_sources(ent); - if (fds > 0) - goto again_file; - } - - /* - * Here, if there are bits remaining to be had and we can block, - * check to see if we have a callback source. If so, call them. - */ - source = ISC_LIST_HEAD(ent->sources); - while ((remaining != 0) && (source != NULL)) { - unsigned int got; - - got = 0; - - if (source->type == ENTROPY_SOURCETYPE_CALLBACK) - got = get_from_callback(source, remaining, blocking); - - added += got; - remaining -= ISC_MIN(remaining, got); - - if (added >= needed) - break; - - source = ISC_LIST_NEXT(source, link); - } - - /* - * Mark as initialized if we've added enough data. - */ - if (ent->initialized < THRESHOLD_BITS) - ent->initialized += added; -} - -static int -wait_for_sources(isc_entropy_t *ent) { - isc_entropysource_t *source; - int maxfd, fd; - int cc; - fd_set reads; - fd_set writes; - - maxfd = -1; - FD_ZERO(&reads); - FD_ZERO(&writes); - - source = ISC_LIST_HEAD(ent->sources); - while (source != NULL) { - if (source->type == ENTROPY_SOURCETYPE_FILE) { - fd = source->sources.file.handle; - if (fd >= 0) { - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &reads); - } - } - if (source->type == ENTROPY_SOURCETYPE_USOCKET) { - fd = source->sources.usocket.handle; - if (fd >= 0) { - switch (source->sources.usocket.status) { - case isc_usocketsource_disconnected: - break; - case isc_usocketsource_connecting: - case isc_usocketsource_connected: - case isc_usocketsource_ndesired: - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &writes); - break; - case isc_usocketsource_wrote: - case isc_usocketsource_reading: - maxfd = ISC_MAX(maxfd, fd); - FD_SET(fd, &reads); - break; - } - } - } - source = ISC_LIST_NEXT(source, link); - } - - if (maxfd < 0) - return (-1); - - cc = select(maxfd + 1, &reads, &writes, NULL, NULL); - if (cc < 0) - return (-1); - - return (cc); -} - -static void -destroyfilesource(isc_entropyfilesource_t *source) { - (void)close(source->handle); -} - -static void -destroyusocketsource(isc_entropyusocketsource_t *source) { - close(source->handle); -} - -/* - * Make a fd non-blocking - */ -static isc_result_t -make_nonblock(int fd) { - int ret; - char strbuf[ISC_STRERRORSIZE]; -#ifdef USE_FIONBIO_IOCTL - int on = 1; -#else - int flags; -#endif - -#ifdef USE_FIONBIO_IOCTL - ret = ioctl(fd, FIONBIO, (char *)&on); -#else - flags = fcntl(fd, F_GETFL, 0); - flags |= PORT_NONBLOCK; - ret = fcntl(fd, F_SETFL, flags); -#endif - - if (ret == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, -#ifdef USE_FIONBIO_IOCTL - "ioctl(%d, FIONBIO, &on): %s", fd, -#else - "fcntl(%d, F_SETFL, %d): %s", fd, flags, -#endif - strbuf); - - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { - int fd; - struct stat _stat; - isc_boolean_t is_usocket = ISC_FALSE; - isc_boolean_t is_connected = ISC_FALSE; - isc_result_t ret; - isc_entropysource_t *source; - - REQUIRE(VALID_ENTROPY(ent)); - REQUIRE(fname != NULL); - - LOCK(&ent->lock); - - if (stat(fname, &_stat) < 0) { - ret = isc__errno2result(errno); - goto errout; - } - /* - * Solaris 2.5.1 does not have support for sockets (S_IFSOCK), - * but it does return type S_IFIFO (the OS believes that - * the socket is a fifo). This may be an issue if we tell - * the program to look at an actual FIFO as its source of - * entropy. - */ -#if defined(S_ISSOCK) - if (S_ISSOCK(_stat.st_mode)) - is_usocket = ISC_TRUE; -#endif -#if defined(S_ISFIFO) && defined(sun) - if (S_ISFIFO(_stat.st_mode)) - is_usocket = ISC_TRUE; -#endif - if (is_usocket) - fd = socket(PF_UNIX, SOCK_STREAM, 0); - else - fd = open(fname, O_RDONLY | PORT_NONBLOCK, 0); - - if (fd < 0) { - ret = isc__errno2result(errno); - goto errout; - } - - ret = make_nonblock(fd); - if (ret != ISC_R_SUCCESS) - goto closefd; - - if (is_usocket) { - struct sockaddr_un sname; - - memset(&sname, 0, sizeof(sname)); - sname.sun_family = AF_UNIX; - strlcpy(sname.sun_path, fname, sizeof(sname.sun_path)); -#if !defined(SUN_LEN) -#define SUN_LEN(su) \ - (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) -#endif - sname.sun_len = SUN_LEN(&sname); - - if (connect(fd, (struct sockaddr *) &sname, - sizeof(struct sockaddr_un)) < 0) { - if (errno != EINPROGRESS) { - ret = isc__errno2result(errno); - goto closefd; - } - } else - is_connected = ISC_TRUE; - } - - source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); - if (source == NULL) { - ret = ISC_R_NOMEMORY; - goto closefd; - } - - /* - * From here down, no failures can occur. - */ - source->magic = SOURCE_MAGIC; - source->ent = ent; - source->total = 0; - source->bad = ISC_FALSE; - memset(source->name, 0, sizeof(source->name)); - ISC_LINK_INIT(source, link); - if (is_usocket) { - source->sources.usocket.handle = fd; - if (is_connected) - source->sources.usocket.status = - isc_usocketsource_connected; - else - source->sources.usocket.status = - isc_usocketsource_connecting; - source->sources.usocket.sz_to_recv = 0; - source->type = ENTROPY_SOURCETYPE_USOCKET; - } else { - source->sources.file.handle = fd; - source->type = ENTROPY_SOURCETYPE_FILE; - } - - /* - * Hook it into the entropy system. - */ - ISC_LIST_APPEND(ent->sources, source, link); - ent->nsources++; - - UNLOCK(&ent->lock); - return (ISC_R_SUCCESS); - - closefd: - (void)close(fd); - - errout: - UNLOCK(&ent->lock); - - return (ret); -} diff --git a/usr.sbin/bind/lib/isc/unix/file.c b/usr.sbin/bind/lib/isc/unix/file.c index ad1e4b72a08..1f7888621b5 100644 --- a/usr.sbin/bind/lib/isc/unix/file.c +++ b/usr.sbin/bind/lib/isc/unix/file.c @@ -43,7 +43,7 @@ * SUCH DAMAGE. */ -/* $Id: file.c,v 1.8 2020/01/09 14:18:30 florian Exp $ */ +/* $Id: file.c,v 1.9 2020/01/09 14:24:08 florian Exp $ */ /*! \file */ @@ -68,7 +68,7 @@ #include <isc/file.h> #include <isc/log.h> #include <isc/mem.h> -#include <isc/random.h> + #include <isc/string.h> #include <isc/time.h> #include <isc/util.h> @@ -258,7 +258,6 @@ isc_result_t isc_file_renameunique(const char *file, char *templet) { char *x; char *cp; - isc_uint32_t which; REQUIRE(file != NULL); REQUIRE(templet != NULL); @@ -271,8 +270,7 @@ isc_file_renameunique(const char *file, char *templet) { x = cp--; while (cp >= templet && *cp == 'X') { - isc_random_get(&which); - *cp = alphnum[which % (sizeof(alphnum) - 1)]; + *cp = alphnum[arc4random_uniform(sizeof(alphnum) - 1)]; x = cp--; } while (link(file, templet) == -1) { @@ -316,7 +314,6 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { isc_result_t result = ISC_R_SUCCESS; char *x; char *cp; - isc_uint32_t which; REQUIRE(templet != NULL); REQUIRE(fp != NULL && *fp == NULL); @@ -329,8 +326,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) { x = cp--; while (cp >= templet && *cp == 'X') { - isc_random_get(&which); - *cp = alphnum[which % (sizeof(alphnum) - 1)]; + *cp = alphnum[arc4random_uniform(sizeof(alphnum) - 1)]; x = cp--; } |