#include <isc/log.h>
#include <isc/netaddr.h>
#include <isc/netdb.h>
+#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/random.h>
else if (keysecret[0] != 0)
setup_text_key();
- isc_random_buf(cookie_secret, sizeof(cookie_secret));
+ isc_nonce_buf(cookie_secret, sizeof(cookie_secret));
}
/*%
srv != NULL;
srv = ISC_LIST_HEAD(lookup->my_server_list)) {
INSIST(i > 0);
- j = isc_random();
- j %= i;
+ j = isc_random_uniform(i);
next = ISC_LIST_NEXT(srv, link);
while (j-- > 0 && next != NULL) {
srv = next;
isc_boolean_t
setup_lookup(dig_lookup_t *lookup) {
isc_result_t result;
- isc_uint32_t id;
unsigned int len;
dig_server_t *serv;
dig_query_t *query;
dighost_trying(store, lookup);
INSIST(dns_name_isabsolute(lookup->name));
- id = isc_random();
- lookup->sendmsg->id = (unsigned short)id & 0xFFFF;
+ lookup->sendmsg->id = (dns_messageid_t)isc_random16();
lookup->sendmsg->opcode = lookup->opcode;
lookup->msgcounter = 0;
/*
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/netaddr.h>
+#include <isc/nonce.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/stdtime.h>
*/
if (conn->nonce == 0) {
while (conn->nonce == 0) {
- isc_random_buf(&conn->nonce, sizeof(conn->nonce));
+ isc_nonce_buf(&conn->nonce, sizeof(conn->nonce));
}
eresult = ISC_R_SUCCESS;
} else
#include <isc/httpd.h>
#include <isc/lex.h>
#include <isc/meminfo.h>
+#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/platform.h>
#include <isc/portset.h>
#include <isc/print.h>
-#include <isc/random.h>
#include <isc/refcount.h>
#include <isc/resource.h>
#include <isc/sha2.h>
if (result != ISC_R_SUCCESS)
return (result);
- isc_random_buf(view->secret, sizeof(view->secret));
+ isc_nonce_buf(view->secret, sizeof(view->secret));
ISC_LIST_APPEND(*viewlist, view, link);
dns_view_attach(view, viewp);
}
}
} else {
- isc_random_buf(server->sctx->secret,
- sizeof(server->sctx->secret));
+ isc_nonce_buf(server->sctx->secret,
+ sizeof(server->sctx->secret));
}
/*
if (saltlen > 256U)
return (ISC_R_RANGE);
- isc_random_buf(salt, saltlen);
+ isc_nonce_buf(salt, saltlen);
r.base = salt;
r.length = (unsigned int) saltlen;
#include <isc/lex.h>
#include <isc/log.h>
#include <isc/mem.h>
+#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/platform.h>
fatal("out of memory");
}
- memmove(kserver, &master_servers[master_inuse], sizeof(isc_sockaddr_t));
+ memmove(kserver, &master_servers[master_inuse],
+ sizeof(isc_sockaddr_t));
servname = dns_fixedname_initname(&fname);
if (realm == NULL)
get_ticket_realm(gmctx);
- result = snprintf(servicename, sizeof(servicename), "DNS/%s%s", namestr, realm ? realm : "");
+ result = snprintf(servicename, sizeof(servicename), "DNS/%s%s",
+ namestr, realm ? realm : "");
RUNTIME_CHECK(result < sizeof(servicename));
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
keyname = dns_fixedname_initname(&fkname);
- val = isc_random();
+ isc_nonce_buf(&val, sizeof(val));
- result = snprintf(mykeystr, sizeof(mykeystr), "%u.sig-%s", val, namestr);
+ result = snprintf(mykeystr, sizeof(mykeystr), "%u.sig-%s", val,
+ namestr);
RUNTIME_CHECK(result <= sizeof(mykeystr));
isc_buffer_init(&buf, mykeystr, strlen(mykeystr));
if (argc < 1)
usage(1);
- serial = isc_random();
+ serial = isc_random32();
DO("create memory context", isc_mem_create(0, 0, &rndc_mctx));
DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr));
#include <isc/hash.h>
#include <isc/log.h>
#include <isc/mem.h>
+#include <isc/nonce.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/sockaddr.h>
CHECK("dst_key_fromnamedfile", result);
isc_buffer_init(&nonce, noncedata, sizeof(noncedata));
- isc_random_buf(noncedata, sizeof(noncedata));
+ isc_nonce_buf(noncedata, sizeof(noncedata));
isc_buffer_add(&nonce, sizeof(noncedata));
(void)isc_app_run();
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/net.h>
+#include <isc/nonce.h>
#include <isc/parseint.h>
#include <isc/print.h>
#include <isc/random.h>
RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
RUNCHECK(dst_lib_init(mctx, NULL));
- isc_random_buf(cookie_secret, sizeof(cookie_secret));
+ isc_nonce_buf(cookie_secret, sizeof(cookie_secret));
ISC_LIST_INIT(queries);
parse_args(ISC_FALSE, argc, argv);
e->to512 = 0;
e->cookie = NULL;
e->cookielen = 0;
- e->srtt = (isc_random() & 0x1f) + 1;
+ e->srtt = (isc_random_uniform(0x1f)) + 1;
e->lastage = 0;
e->expires = 0;
e->active = 0;
dispsock->resp = NULL;
dispsock->portentry = NULL;
dispsock->task = NULL;
- isc_task_attach(disp->task[isc_random() % disp->ntasks], &dispsock->task);
+ isc_task_attach(disp->task[isc_random_uniform(disp->ntasks)],
+ &dispsock->task);
ISC_LINK_INIT(dispsock, link);
ISC_LINK_INIT(dispsock, blink);
dispsock->magic = DISPSOCK_MAGIC;
if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) {
id = *idp;
} else {
- isc_random_buf(&id, sizeof(id));
+ id = (dns_messageid_t)isc_random16();
}
ok = ISC_FALSE;
i = 0;
#include <isc/hmacmd5.h>
#include <isc/hmacsha.h>
#include <isc/md5.h>
+#include <isc/nonce.h>
#include <isc/random.h>
#include <isc/sha1.h>
#include <isc/mem.h>
}
memset(data, 0, ISC_MD5_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
}
memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
}
memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
}
memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
}
memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
}
memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
- isc_random_buf(data, bytes);
+ isc_nonce_buf(data, bytes);
isc_buffer_init(&b, data, bytes);
isc_buffer_add(&b, bytes);
#include <string.h>
#include <isc/mem.h>
+#include <isc/nonce.h>
#include <isc/random.h>
#include <isc/safe.h>
#include <isc/sha1.h>
UNUSED(unused);
- isc_random_buf(rand_array, sizeof(rand_array));
+ isc_nonce_buf(rand_array, sizeof(rand_array));
dsa = DSA_new();
if (dsa == NULL)
isc_stdtime_get(&now);
if (isc_mem_isovermem(rbtdb->common.mctx)) {
- isc_uint32_t val = isc_random();
-
/*
+ * Force expire with 25% probability.
* XXXDCL Could stand to have a better policy, like LRU.
*/
- force_expire = ISC_TF(rbtnode->down == NULL && val % 4 == 0);
+ force_expire = ISC_TF(rbtnode->down == NULL &&
+ (isc_random32() % 4) == 0);
/*
* Note that 'log' can be true IFF overmem is also true.
* 'Random' order.
*/
for (i = 0; i < count; i++) {
- isc_uint32_t val = isc_random();
+ isc_uint32_t val = isc_random32();
- choice = i + (val % (count - i));
+ choice = i + val % (count - i);
rdata = in[i];
in[i] = in[choice];
in[choice] = rdata;
val = rdataset->count;
if (val == ISC_UINT32_MAX) {
- val = isc_random();
+ val = isc_random32();
}
j = val % count;
for (i = 0; i < count; i++) {
* slow. We don't know. Increase the RTT.
*/
INSIST(no_response);
- value = isc_random();
+ value = isc_random32();
if (query->addrinfo->srtt > 800000)
mask = 0x3fff;
else if (query->addrinfo->srtt > 400000)
close(fd);
/* Randomly fuzz a portion of the memory */
- p = base + (isc_random() % filesize);
+ p = base + (isc_random_uniform(filesize));
q = base + filesize;
- q -= (isc_random() % (q - p));
+ q -= (isc_random_uniform(q - p));
while (p++ < q) {
- *p = isc_random() & 0xff;
+ *p = isc_random8();
}
result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
dns_name_t *name;
for (j = 0; j < 32; j++) {
- isc_uint32_t v = isc_random();
- namebuf[j] = 'a' + (v % 26);
+ isc_uint32_t v = isc_random_uniform(26);
+ namebuf[j] = 'a' + v;
}
namebuf[32] = '.';
namebuf[33] = 0;
isc_result_t result;
for (j = 0; j < 32; j++) {
- isc_uint32_t v = isc_random();
- namebuf[j] = 'a' + (v % 26);
+ isc_uint32_t v = isc_random_uniform(26);
+ namebuf[j] = 'a' + v;
}
namebuf[32] = '.';
namebuf[33] = 0;
for (i = 0; i < 4096; i++) {
isc_uint32_t num_names;
- num_names = isc_random();
if (names_count < 1024) {
- num_names %= 1024 - names_count;
+ num_names = isc_random_uniform(1024 - names_count);
num_names++;
} else {
num_names = 0;
insert_nodes(mytree, names, &names_count, num_names);
check_tree(mytree, names, names_count, __LINE__);
- num_names = isc_random();
if (names_count > 0) {
- num_names %= names_count;
+ num_names = isc_random_uniform(names_count);
num_names++;
} else {
num_names = 0;
#include <isc/buffer.h>
#include <isc/md5.h>
#include <isc/mem.h>
+#include <isc/nonce.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/string.h>
if (randomdata == NULL)
goto failure;
- isc_random_buf(randomdata, TKEY_RANDOM_AMOUNT);
+ isc_nonce_buf(randomdata, TKEY_RANDOM_AMOUNT);
r.base = randomdata;
r.length = TKEY_RANDOM_AMOUNT;
isc_buffer_t b;
unsigned int i, j;
- isc_random_buf(randomdata, sizeof(randomdata));
+ isc_nonce_buf(randomdata, sizeof(randomdata));
for (i = 0, j = 0; i < sizeof(randomdata); i++) {
unsigned char val = randomdata[i];
dns_name_init(&xfr->name, NULL);
xfr->rdclass = rdclass;
xfr->checkid = ISC_TRUE;
- xfr->id = (isc_uint16_t)(isc_random() & 0xffff);
+ xfr->id = (dns_messageid_t)isc_random16();
xfr->reqtype = reqtype;
xfr->dscp = dscp;
resign = rdataset.resign - zone->sigresigninginterval;
dns_rdataset_disassociate(&rdataset);
- nanosecs = isc_random();
- nanosecs %= 1000000000;
+ nanosecs = isc_random_uniform(1000000000);
isc_time_set(&zone->resigntime, resign, nanosecs);
cleanup:
dns_db_detach(&db);
OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \
aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
bind9.@O@ buffer.@O@ bufferlist.@O@ \
- commandline.@O@ counter.@O@ crc64.@O@ error.@O@ event.@O@ \
- hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
+ commandline.@O@ counter.@O@ crc64.@O@ error.@O@ entropy.@O@ \
+ event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
hmacsha.@O@ httpd.@O@ iterated_hash.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
md5.@O@ mem.@O@ mutexblock.@O@ \
- netaddr.@O@ netscope.@O@ pool.@O@ \
+ netaddr.@O@ netscope.@O@ nonce.@O@ pool.@O@ \
parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \
rwlock.@O@ \
SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \
aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
buffer.c bufferlist.c commandline.c counter.c crc64.c \
- error.c event.c hash.c ht.c heap.c hex.c hmacmd5.c \
+ entropy.c error.c event.c hash.c ht.c heap.c hex.c hmacmd5.c \
hmacsha.c httpd.c iterated_hash.c \
lex.c lfsr.c lib.c log.c \
md5.c mem.c mutexblock.c \
- netaddr.c netscope.c pool.c \
+ netaddr.c netscope.c nonce.c pool.c \
parseint.c portset.c quota.c radix.c random.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 \
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <isc/util.h>
+
+#include "entropy_private.h"
+
+#if HAVE_OPENSSL
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+void
+isc_entropy_get(void *buf, size_t buflen) {
+ if (RAND_bytes(buf, buflen) < 1) {
+ FATAL_ERROR(__FILE__,
+ __LINE__,
+ "RAND_bytes(): %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ }
+}
+
+#elif HAVE_PKCS11
+#include <pk11/pk11.h>
+
+void
+isc_entropy_get(void *buf, size_t buflen) {
+ RUNTIME_CHECK(pk11_rand_bytes(buf, buflen) == ISC_R_SUCCESS);
+}
+
+#endif /* if HAVE_PKCS11 */
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <isc/lang.h>
+
+/*! \file isc/entropy.h
+ * \brief Implements wrapper around CSPRNG cryptographic library calls
+ * for getting cryptographically secure pseudo-random numbers.
+ *
+ * - If OpenSSL is used, it uses RAND_bytes()
+ * - If PKCS#11 is used, it uses pkcs_C_GenerateRandom()
+ *
+ */
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_entropy_get(void *buf, size_t buflen);
+/*!<
+ * \brief Get cryptographically-secure pseudo-random data.
+ */
+
+ISC_LANG_ENDDECLS
* again, it should not change fnv_offset_basis.
*/
while (fnv_offset_basis == 0) {
- fnv_offset_basis = isc_random();
+ fnv_offset_basis = isc_random32();
}
fnv_initialized = ISC_TRUE;
interfaceiter.h @ISC_IPV6_H@ iterated_hash.h \
json.h lang.h lex.h lfsr.h lib.h likely.h list.h log.h \
magic.h md5.h mem.h meminfo.h msgcat.h msgs.h mutexblock.h \
- netaddr.h netscope.h os.h parseint.h \
+ netaddr.h netscope.h nonce.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 \
region.h resource.h result.h resultclass.h rwlock.h \
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <isc/lang.h>
+
+/*! \file isc/nonce.h
+ * \brief Provides a function for generating an arbitrarily long nonce.
+ */
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_nonce_buf(void *buf, size_t buflen);
+/*!<
+ * Fill 'buf', up to 'buflen' bytes, with random data from the
+ * crypto provider's random function.
+ */
+
+ISC_LANG_ENDDECLS
#include <isc/lang.h>
/*! \file isc/random.h
- * \brief Implements wrapper around system provider pseudo-random data
- * generators.
- *
- * The system providers used:
- * - On Linux - getrandom() glibc call or syscall
- * - On BSDs - arc4random()
- *
- * If neither is available, the crypto library provider is used:
- * - If OpenSSL is used - RAND_bytes()
- * - If PKCS#11 is used - pkcs_C_GenerateRandom()
+ * \brief Implements wrapper around a non-cryptographically secure
+ * pseudo-random number generator.
*
*/
ISC_LANG_BEGINDECLS
+uint8_t
+isc_random8(void);
+/*!<
+ * \brief Returns a single 8-bit random value.
+ */
+
+uint16_t
+isc_random16(void);
+/*!<
+ * \brief Returns a single 16-bit random value.
+ */
+
uint32_t
-isc_random(void);
+isc_random32(void);
+/*!<
+ * \brief Returns a single 32-bit random value.
+ */
void
isc_random_buf(void *buf, size_t buflen);
/*!<
- * \brief Get random data.
+ * \brief Fills the region buf of length buflen with random data.
*/
uint32_t
isc_random_uniform(uint32_t upper_bound);
+/*!<
+ * \brief Will return a single 32-bit value, uniformly distributed but
+ * less than upper_bound. This is recommended over
+ * constructions like ``isc_random() % upper_bound'' as it
+ * avoids "modulo bias" when the upper bound is not a power of
+ * two. In the worst case, this function may require multiple
+ * iterations to ensure uniformity.
+ */
ISC_LANG_ENDDECLS
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <config.h>
+
+#include <isc/nonce.h>
+
+#include "entropy_private.h"
+
+inline void
+isc_nonce_buf(void *buf, size_t buflen) {
+ return (isc_entropy_get(buf, buflen));
+}
void *
isc_pool_get(isc_pool_t *pool) {
- isc_uint32_t i = isc_random();
- return (pool->pool[i % pool->count]);
+ return (pool->pool[isc_random_uniform(pool->count)]);
}
int
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
-#if HAVE_OPENSSL
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#endif /* ifdef HAVE_OPENSSL */
-
-#if HAVE_PKCS11
-#include <pk11/pk11.h>
-#endif /* if HAVE_PKCS11 */
-
-#if defined(__linux__)
-# include <errno.h>
-# ifdef HAVE_GETRANDOM
-# include <sys/random.h>
-# else /* HAVE_GETRANDOM */
-# include <sys/syscall.h>
-# endif /* HAVE_GETRANDOM */
-#endif /* defined(__linux__) */
-
#include <isc/random.h>
#include <isc/result.h>
#include <isc/types.h>
#include <isc/util.h>
-#if defined(_WIN32) || defined(_WIN64)
#include <isc/once.h>
-#endif
-
-#if defined(__linux__)
-# ifdef HAVE_GETRANDOM
-# define have_getrandom() 1
-# else /* ifdef HAVE_GETRANDOM */
-# undef getrandom
-# if defined(SYS_getrandom)
-# define getrandom(dst,s,flags) syscall(SYS_getrandom, \
- (void*)dst, \
- (size_t)s, \
- (unsigned int)flags)
-
-static unsigned
-have_getrandom(void) {
- uint16_t buf;
- ssize_t ret;
- ret = getrandom(&buf, sizeof(buf), 1 /*GRND_NONBLOCK*/);
- return (ret == sizeof(buf) ||
- (ret == -1 && errno == EAGAIN));
-}
-# else /* defined(SYS_getrandom) */
-# define have_getrandom() 0
-# define getrandom(dst,s,flags) -1
-# endif /* defined(SYS_getrandom) */
-# endif /* ifdef HAVE_GETRANDOM */
-
-static int
-getrandom_buf(void *buf, size_t buflen) {
- size_t left = buflen;
- ssize_t ret;
- uint8_t *p = buf;
-
- while (left > 0) {
- ret = getrandom(p, left, 0);
- if (ret == -1 && errno == EINTR) {
- continue;
- }
-
- RUNTIME_CHECK(ret >= 0);
-
- if (ret > 0) {
- left -= ret;
- p += ret;
- }
- }
+#include "entropy_private.h"
- return(0);
-}
-#endif /* __linux__ */
+/*
+ * The specific implementation for PRNG is included as a C file
+ * that has to provide a static variable named seed, and a function
+ * uint32_t next(void) that provides next random number.
+ *
+ * The implementation must be thread-safe.
+ */
-#if defined(_WIN32) || defined(_WIN64)
+/*
+ * Two contestants have been considered: the xoroshiro family of the
+ * functions by Villa&Blackman, and PCG by O'Neill. After
+ * consideration, the xoshiro128starstar function has been chosen as
+ * the uint32_t random number provider because it is very fast and has
+ * good enough properties for our usage pattern.
+ */
+#include "xoshiro128starstar.c"
static isc_once_t isc_random_once = ISC_ONCE_INIT;
-static HCRYPTPROV isc_random_hcryptprov;
+static void
+isc_random_initialize(void) {
+ isc_entropy_get(seed, sizeof(seed));
+}
-static void isc_random_initialize(void) {
- RUNTIME_CHECK(CryptAcquireContext(&isc_random_hcryptprov,
- NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
+uint8_t
+isc_random8(void) {
+ RUNTIME_CHECK(isc_once_do(&isc_random_once,
+ isc_random_initialize) == ISC_R_SUCCESS);
+ return (next() & 0xff);
}
-#endif /* defined(_WIN32) || defined(_WIN64) */
+uint16_t
+isc_random16(void) {
+ RUNTIME_CHECK(isc_once_do(&isc_random_once,
+ isc_random_initialize) == ISC_R_SUCCESS);
+ return (next() & 0xffff);
+}
uint32_t
-isc_random(void) {
-#if defined(HAVE_ARC4RANDOM)
- return(arc4random());
-#else /* HAVE_ARC4RANDOM */
- uint32_t ret;
- isc_random_buf(&ret, sizeof(ret));
- return (ret);
-#endif /* HAVE_ARC4RANDOM */
+isc_random32(void) {
+ RUNTIME_CHECK(isc_once_do(&isc_random_once,
+ isc_random_initialize) == ISC_R_SUCCESS);
+ return (next());
}
-/*
- * Fill the region buf of length buflen with random data.
- */
void
isc_random_buf(void *buf, size_t buflen) {
REQUIRE(buf);
REQUIRE(buflen > 0);
-#if defined(_WIN32) || defined(_WIN64)
RUNTIME_CHECK(isc_once_do(&isc_random_once,
isc_random_initialize) == ISC_R_SUCCESS);
- RUNTIME_CHECK(CryptGenRandom(isc_random_hcryptprov,
- (DWORD)buflen, buf));
- return;
-#elif defined(HAVE_ARC4RANDOM_BUF)
- arc4random_buf(buf, buflen);
- return;
-#else
-# if defined(__linux__)
- /*
- * We need to check the availability of the SYS_getrandom
- * syscall at runtime and fall back to crypto library provider
- * if not available
- */
- if (have_getrandom()) {
- getrandom_buf(buf, buflen);
- return;
- }
+ int i;
+ uint32_t r;
-# endif /* defined(__linux__) */
-
-/* Use crypto library as fallback when no other CSPRNG is available */
-# if HAVE_OPENSSL
- if (RAND_bytes(buf, buflen) < 1) {
- FATAL_ERROR(__FILE__, __LINE__, "RAND_bytes(): %s", ERR_error_string(ERR_get_error(), NULL));
+ for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) {
+ r = next();
+ memmove((uint8_t *)buf + i, &r, sizeof(r)); /* Buffers cannot
+ * really overlap
+ * here */
}
-# elif HAVE_PKCS11
- RUNTIME_CHECK(pk11_rand_bytes(buf, buflen) == ISC_R_SUCCESS);
-# endif /* if defined(HAVE_ARC4RANDOM_BUF) */
-
-#endif
+ r = next();
+ memmove((uint8_t *)buf + i, &r, buflen % sizeof(r)); /* Buffer cannot
+ * really overlap
+ * here */
+ return;
}
uint32_t
isc_random_uniform(uint32_t upper_bound) {
-#if defined(HAVE_ARC4RANDOM_UNIFORM)
- return(arc4random_uniform(upper_bound));
-#else /* if defined(HAVE_ARC4RANDOM_UNIFORM) */
/* Copy of arc4random_uniform from OpenBSD */
uint32_t r, min;
+ RUNTIME_CHECK(isc_once_do(&isc_random_once,
+ isc_random_initialize) == ISC_R_SUCCESS);
+
if (upper_bound < 2) {
return (0);
}
* to re-roll.
*/
for (;;) {
- r = isc_random();
+ r = next();
if (r >= min) {
break;
}
}
return (r % upper_bound);
-#endif /* if defined(HAVE_ARC4RANDOM_UNIFORM) */
}
void
isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
- isc_uint32_t i = isc_random();
- isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
+ isc_task_attach(pool->tasks[isc_random_uniform(pool->ntasks)], targetp);
}
int
#include <isc/random.h>
#include <isc/result.h>
#include <isc/mem.h>
+#include <isc/nonce.h>
#include <isc/print.h>
#include <isc/util.h>
static double igamc(double a, double x);
static double igam(double a, double x);
+typedef enum {
+ ISC_RANDOM8,
+ ISC_RANDOM16,
+ ISC_RANDOM32,
+ ISC_RANDOM_BYTES,
+ ISC_RANDOM_UNIFORM,
+ ISC_NONCE_BYTES
+} isc_random_func;
+
static double
igamc(double a, double x) {
double ans, ax, c, yc, r, t, y, z;
}
static void
-random_test(pvalue_func_t *func, isc_boolean_t word_sized) {
+random_test(pvalue_func_t *func, isc_random_func test_func) {
isc_mem_t *mctx = NULL;
isc_result_t result;
isc_uint32_t m;
for (j = 0; j < m; j++) {
isc_uint32_t i;
- isc_uint16_t values[REPS];
+ isc_uint32_t values[REPS];
+ isc_uint16_t *uniform_values;
double p_value;
- if (word_sized) {
- for (i = 0; i < REPS; i++) {
- isc_random_buf(&values[i], sizeof(values[i]));
+ switch (test_func) {
+ case ISC_RANDOM8:
+ for (i = 0; i < (sizeof(values) / sizeof(*values)); i++)
+ {
+ values[i] = isc_random8();
}
- } else {
+ break;
+ case ISC_RANDOM16:
+ for (i = 0; i < (sizeof(values) / sizeof(*values)); i++)
+ {
+ values[i] = isc_random16();
+ }
+ break;
+ case ISC_RANDOM32:
+ for (i = 0; i < (sizeof(values) / sizeof(*values)); i++)
+ {
+ values[i] = isc_random32();
+ }
+ break;
+ case ISC_RANDOM_BYTES:
isc_random_buf(values, sizeof(values));
+ break;
+ case ISC_RANDOM_UNIFORM:
+ uniform_values = (isc_uint16_t *)values;
+ for (i = 0;
+ i < (sizeof(values) / sizeof(*uniform_values));
+ i++)
+ {
+ uniform_values[i] =
+ isc_random_uniform(ISC_UINT16_MAX);
+ }
+ break;
+ case ISC_NONCE_BYTES:
+ isc_nonce_buf(values, sizeof(values));
+ break;
}
- p_value = (*func)(mctx, values, REPS);
+ p_value = (*func)(mctx, (uint16_t *)values, REPS * 2);
if (p_value >= 0.01) {
passed++;
}
UNUSED(mctx);
- numbits = length * 16;
+ numbits = length * sizeof(*values) * 8;
scount = 0;
for (i = 0; i < length; i++)
UNUSED(mctx);
- numbits = length * 16;
+ numbits = length * sizeof(*values) * 8;
bcount = 0;
- for (i = 0; i < REPS; i++)
+ for (i = 0; i < length; i++)
bcount += bitcounts_table[values[i]];
/* Debug message, not displayed when running via atf-run */
double chi_square;
double p_value;
- numbits = length * 16;
+ numbits = length * sizeof(*values) * 8;
mbits = 32000;
mwords = mbits / 16;
numblocks = numbits / mbits;
isc_mem_put(mctx, pi, numblocks * sizeof(double));
/* Debug message, not displayed when running via atf-run */
- printf("chi_square=%f\n", chi_square);
+printf("chi_square=%f\n", chi_square);
p_value = igamc(numblocks * 0.5, chi_square * 0.5);
return (p_value);
}
-ATF_TC(isc_random_monobit_16);
-ATF_TC_HEAD(isc_random_monobit_16, tc) {
+/* Tests for isc_random32() function */
+
+ATF_TC(isc_random32_monobit);
+ATF_TC_HEAD(isc_random32_monobit, tc) {
+ atf_tc_set_md_var(tc, "descr", "Monobit test for the RANDOM");
+}
+ATF_TC_BODY(isc_random32_monobit, tc) {
+ UNUSED(tc);
+
+ random_test(monobit, ISC_RANDOM32);
+}
+
+ATF_TC(isc_random32_runs);
+ATF_TC_HEAD(isc_random32_runs, tc) {
+ atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM");
+}
+ATF_TC_BODY(isc_random32_runs, tc) {
+ UNUSED(tc);
+
+ random_test(runs, ISC_RANDOM32);
+}
+
+ATF_TC(isc_random32_blockfrequency);
+ATF_TC_HEAD(isc_random32_blockfrequency, tc) {
+ atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM");
+}
+ATF_TC_BODY(isc_random32_blockfrequency, tc) {
+ UNUSED(tc);
+
+ random_test(blockfrequency, ISC_RANDOM32);
+}
+
+ATF_TC(isc_random32_binarymatrixrank);
+ATF_TC_HEAD(isc_random32_binarymatrixrank, tc) {
+ atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
+}
+ATF_TC_BODY(isc_random32_binarymatrixrank, tc) {
+ UNUSED(tc);
+
+ random_test(binarymatrixrank, ISC_RANDOM32);
+}
+
+/* Tests for isc_random_bytes() function */
+
+ATF_TC(isc_random_bytes_monobit);
+ATF_TC_HEAD(isc_random_bytes_monobit, tc) {
atf_tc_set_md_var(tc, "descr", "Monobit test for the RANDOM");
}
-ATF_TC_BODY(isc_random_monobit_16, tc) {
+ATF_TC_BODY(isc_random_bytes_monobit, tc) {
UNUSED(tc);
- random_test(monobit, ISC_TRUE);
+ random_test(monobit, ISC_RANDOM_BYTES);
}
-ATF_TC(isc_random_runs_16);
-ATF_TC_HEAD(isc_random_runs_16, tc) {
+ATF_TC(isc_random_bytes_runs);
+ATF_TC_HEAD(isc_random_bytes_runs, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM");
}
-ATF_TC_BODY(isc_random_runs_16, tc) {
+ATF_TC_BODY(isc_random_bytes_runs, tc) {
UNUSED(tc);
- random_test(runs, ISC_TRUE);
+ random_test(runs, ISC_RANDOM_BYTES);
}
-ATF_TC(isc_random_blockfrequency_16);
-ATF_TC_HEAD(isc_random_blockfrequency_16, tc) {
+ATF_TC(isc_random_bytes_blockfrequency);
+ATF_TC_HEAD(isc_random_bytes_blockfrequency, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM");
}
-ATF_TC_BODY(isc_random_blockfrequency_16, tc) {
+ATF_TC_BODY(isc_random_bytes_blockfrequency, tc) {
UNUSED(tc);
- random_test(blockfrequency, ISC_TRUE);
+ random_test(blockfrequency, ISC_RANDOM_BYTES);
}
-ATF_TC(isc_random_binarymatrixrank_16);
-ATF_TC_HEAD(isc_random_binarymatrixrank_16, tc) {
+ATF_TC(isc_random_bytes_binarymatrixrank);
+ATF_TC_HEAD(isc_random_bytes_binarymatrixrank, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
}
-/*
- * This is the binary matrix rank test taken from the NIST SP 800-22 RNG
- * test suite.
- */
-ATF_TC_BODY(isc_random_binarymatrixrank_16, tc) {
+ATF_TC_BODY(isc_random_bytes_binarymatrixrank, tc) {
UNUSED(tc);
- random_test(binarymatrixrank, ISC_TRUE);
+ random_test(binarymatrixrank, ISC_RANDOM_BYTES);
}
-ATF_TC(isc_random_monobit_bytes);
-ATF_TC_HEAD(isc_random_monobit_bytes, tc) {
+
+/* Tests for isc_random_uniform() function */
+
+ATF_TC(isc_random_uniform_monobit);
+ATF_TC_HEAD(isc_random_uniform_monobit, tc) {
atf_tc_set_md_var(tc, "descr", "Monobit test for the RANDOM");
}
-ATF_TC_BODY(isc_random_monobit_bytes, tc) {
+ATF_TC_BODY(isc_random_uniform_monobit, tc) {
UNUSED(tc);
- random_test(monobit, ISC_FALSE);
+ random_test(monobit, ISC_RANDOM_UNIFORM);
}
-ATF_TC(isc_random_runs_bytes);
-ATF_TC_HEAD(isc_random_runs_bytes, tc) {
+ATF_TC(isc_random_uniform_runs);
+ATF_TC_HEAD(isc_random_uniform_runs, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM");
}
-ATF_TC_BODY(isc_random_runs_bytes, tc) {
+ATF_TC_BODY(isc_random_uniform_runs, tc) {
UNUSED(tc);
- random_test(runs, ISC_FALSE);
+ random_test(runs, ISC_RANDOM_UNIFORM);
}
-ATF_TC(isc_random_blockfrequency_bytes);
-ATF_TC_HEAD(isc_random_blockfrequency_bytes, tc) {
+ATF_TC(isc_random_uniform_blockfrequency);
+ATF_TC_HEAD(isc_random_uniform_blockfrequency, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM");
}
-ATF_TC_BODY(isc_random_blockfrequency_bytes, tc) {
+ATF_TC_BODY(isc_random_uniform_blockfrequency, tc) {
UNUSED(tc);
- random_test(blockfrequency, ISC_FALSE);
+ random_test(blockfrequency, ISC_RANDOM_UNIFORM);
}
-ATF_TC(isc_random_binarymatrixrank_bytes);
-ATF_TC_HEAD(isc_random_binarymatrixrank_bytes, tc) {
+ATF_TC(isc_random_uniform_binarymatrixrank);
+ATF_TC_HEAD(isc_random_uniform_binarymatrixrank, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
}
-/*
- * This is the binary matrix rank test taken from the NIST SP 800-22 RNG
- * test suite.
- */
-ATF_TC_BODY(isc_random_binarymatrixrank_bytes, tc) {
+ATF_TC_BODY(isc_random_uniform_binarymatrixrank, tc) {
+ UNUSED(tc);
+
+ random_test(binarymatrixrank, ISC_RANDOM_UNIFORM);
+}
+
+
+/* Tests for isc_nonce_bytes() function */
+
+ATF_TC(isc_nonce_bytes_monobit);
+ATF_TC_HEAD(isc_nonce_bytes_monobit, tc) {
+ atf_tc_set_md_var(tc, "descr", "Monobit test for the RANDOM");
+}
+
+ATF_TC_BODY(isc_nonce_bytes_monobit, tc) {
+ UNUSED(tc);
+
+ random_test(monobit, ISC_NONCE_BYTES);
+}
+
+ATF_TC(isc_nonce_bytes_runs);
+ATF_TC_HEAD(isc_nonce_bytes_runs, tc) {
+ atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM");
+}
+
+ATF_TC_BODY(isc_nonce_bytes_runs, tc) {
+ UNUSED(tc);
+
+ random_test(runs, ISC_NONCE_BYTES);
+}
+
+ATF_TC(isc_nonce_bytes_blockfrequency);
+ATF_TC_HEAD(isc_nonce_bytes_blockfrequency, tc) {
+ atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM");
+}
+
+ATF_TC_BODY(isc_nonce_bytes_blockfrequency, tc) {
+ UNUSED(tc);
+
+ random_test(blockfrequency, ISC_NONCE_BYTES);
+}
+
+ATF_TC(isc_nonce_bytes_binarymatrixrank);
+ATF_TC_HEAD(isc_nonce_bytes_binarymatrixrank, tc) {
+ atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
+}
+
+ATF_TC_BODY(isc_nonce_bytes_binarymatrixrank, tc) {
UNUSED(tc);
- random_test(binarymatrixrank, ISC_FALSE);
+ random_test(binarymatrixrank, ISC_NONCE_BYTES);
}
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
- ATF_TP_ADD_TC(tp, isc_random_monobit_16);
- ATF_TP_ADD_TC(tp, isc_random_runs_16);
- ATF_TP_ADD_TC(tp, isc_random_blockfrequency_16);
- ATF_TP_ADD_TC(tp, isc_random_binarymatrixrank_16);
- ATF_TP_ADD_TC(tp, isc_random_monobit_bytes);
- ATF_TP_ADD_TC(tp, isc_random_runs_bytes);
- ATF_TP_ADD_TC(tp, isc_random_blockfrequency_bytes);
- ATF_TP_ADD_TC(tp, isc_random_binarymatrixrank_bytes);
+ ATF_TP_ADD_TC(tp, isc_random32_monobit);
+ ATF_TP_ADD_TC(tp, isc_random32_runs);
+ ATF_TP_ADD_TC(tp, isc_random32_blockfrequency);
+ ATF_TP_ADD_TC(tp, isc_random32_binarymatrixrank);
+ ATF_TP_ADD_TC(tp, isc_random_bytes_monobit);
+ ATF_TP_ADD_TC(tp, isc_random_bytes_runs);
+ ATF_TP_ADD_TC(tp, isc_random_bytes_blockfrequency);
+ ATF_TP_ADD_TC(tp, isc_random_bytes_binarymatrixrank);
+ ATF_TP_ADD_TC(tp, isc_random_uniform_monobit);
+ ATF_TP_ADD_TC(tp, isc_random_uniform_runs);
+ ATF_TP_ADD_TC(tp, isc_random_uniform_blockfrequency);
+ ATF_TP_ADD_TC(tp, isc_random_uniform_binarymatrixrank);
+ ATF_TP_ADD_TC(tp, isc_nonce_bytes_monobit);
+ ATF_TP_ADD_TC(tp, isc_nonce_bytes_runs);
+ ATF_TP_ADD_TC(tp, isc_nonce_bytes_blockfrequency);
+ ATF_TP_ADD_TC(tp, isc_nonce_bytes_binarymatrixrank);
return (atf_no_error());
}
x = cp--;
while (cp >= templet && *cp == 'X') {
- isc_uint32_t which = isc_random();
- *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ *cp = alphnum[isc_random_uniform(sizeof(alphnum) - 1)];
x = cp--;
}
while (link(file, templet) == -1) {
x = cp--;
while (cp >= templet && *cp == 'X') {
- isc_uint32_t which = isc_random();
- *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ *cp = alphnum[isc_random_uniform(sizeof(alphnum) - 1)];
x = cp--;
}
trv++;
/* extra X's get set to 0's */
while (*--trv == 'X') {
- isc_uint32_t which = isc_random();
- *trv = alphnum[which % (sizeof(alphnum) - 1)];
+ isc_uint32_t which = isc_random_uniform(sizeof(alphnum) - 1);
+ *trv = alphnum[which];
}
/*
* check the target directory; if you have six X's and it
--- /dev/null
+/*
+ * Portions Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*
+ * Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+ *
+ * To the extent possible under law, the author has dedicated all
+ * copyright and related and neighboring rights to this software to the
+ * public domain worldwide. This software is distributed without any
+ * warranty.
+ *
+ * See <http://creativecommons.org/publicdomain/zero/1.0/>.
+*/
+
+#include <stdint.h>
+
+/*
+ * This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator.
+ * It has excellent (sub-ns) speed, a state size (128 bits) that is large
+ * enough for mild parallelism, and it passes all tests we are aware of.
+ *
+ * For generating just single-precision (i.e., 32-bit) floating-point
+ * numbers, xoshiro128+ is even faster.
+ *
+ * The state must be seeded so that it is not everywhere zero.
+ */
+
+static inline uint32_t rotl(const uint32_t x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+static uint32_t seed[4];
+
+static inline uint32_t
+next(void) {
+ const uint32_t result_starstar = rotl(seed[0] * 5, 7) * 9;
+
+ const uint32_t t = seed[1] << 9;
+
+ seed[2] ^= seed[0];
+ seed[3] ^= seed[1];
+ seed[1] ^= seed[2];
+ seed[0] ^= seed[3];
+
+ seed[2] ^= t;
+
+ seed[3] = rotl(seed[3], 11);
+
+ return (result_starstar);
+}
#include <isc/hmacsha.h>
#include <isc/mutex.h>
#include <isc/once.h>
+#include <isc/nonce.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/queue.h>
isc_buffer_init(&buf, cookie, sizeof(cookie));
isc_stdtime_get(&now);
- isc_random_buf(&nonce, sizeof(nonce));
+ isc_nonce_buf(&nonce, sizeof(nonce));
compute_cookie(client, now, nonce, client->sctx->secret, &buf);
isc_buffer_t querybuf;
dns_compress_t cctx;
isc_result_t result;
- isc_uint32_t qid;
REQUIRE(client != NULL);
REQUIRE(qnamestr != NULL);
/*
* Set query ID to a random value.
*/
- qid = isc_random();
- message->id = (dns_messageid_t)(qid & 0xffff);
+ message->id = isc_random16();
/*
* Set query flags as requested by the caller.
./lib/isc/commandline.c C.PORTION 1999,2000,2001,2004,2005,2007,2008,2014,2015,2016,2018
./lib/isc/counter.c C 2014,2016,2018
./lib/isc/crc64.c C 2013,2016,2018
+./lib/isc/entropy.c C 2018
+./lib/isc/entropy.h C 2018
+./lib/isc/entropy_private.h C 2018
./lib/isc/error.c C 1998,1999,2000,2001,2004,2005,2007,2015,2016,2018
./lib/isc/event.c C 1998,1999,2000,2001,2004,2005,2007,2014,2016,2017,2018
./lib/isc/fsaccess.c C 2000,2001,2004,2005,2007,2016,2017,2018
./lib/isc/include/isc/mutexblock.h C 1999,2000,2001,2004,2005,2006,2007,2016,2018
./lib/isc/include/isc/netaddr.h C 1998,1999,2000,2001,2002,2004,2005,2006,2007,2009,2015,2016,2017,2018
./lib/isc/include/isc/netscope.h C 2002,2004,2005,2006,2007,2009,2016,2018
+./lib/isc/include/isc/nonce.h C 2018
./lib/isc/include/isc/os.h C 2000,2001,2004,2005,2006,2007,2016,2018
./lib/isc/include/isc/parseint.h C 2001,2002,2004,2005,2006,2007,2016,2018
./lib/isc/include/isc/platform.h.in C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,2014,2015,2016,2017,2018
./lib/isc/noatomic/include/Makefile.in MAKE 2007,2012,2016,2018
./lib/isc/noatomic/include/isc/Makefile.in MAKE 2007,2012,2015,2016,2018
./lib/isc/noatomic/include/isc/atomic.h C 2005,2007,2016,2018
+./lib/isc/nonce.c C 2018
./lib/isc/nothreads/Makefile.in MAKE 2000,2001,2004,2007,2009,2010,2012,2013,2016,2018
./lib/isc/nothreads/condition.c C 2000,2001,2004,2006,2007,2016,2018
./lib/isc/nothreads/include/Makefile.in MAKE 2000,2001,2004,2007,2012,2016,2018
./lib/isc/x86_64/include/Makefile.in MAKE 2007,2012,2016,2018
./lib/isc/x86_64/include/isc/Makefile.in MAKE 2007,2012,2015,2016,2018
./lib/isc/x86_64/include/isc/atomic.h C 2005,2007,2008,2015,2016,2017,2018
+./lib/isc/xoshiro128starstar.c C.PORTION 2018
./lib/isccc/Makefile.in MAKE 2001,2003,2004,2007,2009,2011,2012,2014,2015,2016,2017,2018
./lib/isccc/alist.c C.NOM 2001,2004,2005,2007,2015,2016,2018
./lib/isccc/api X 2001,2006,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018