2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Change isc_random() to be just PRNG, and add isc_nonce_buf() that uses CSPRNG

This commit reverts the previous change to use system provided
entropy, as (SYS_)getrandom is very slow on Linux because it is
a syscall.

The change introduced in this commit adds a new call isc_nonce_buf
that uses CSPRNG from cryptographic library provider to generate
secure data that can be and must be used for generating nonces.
Example usage would be DNS cookies.

The isc_random() API has been changed to use fast PRNG that is not
cryptographically secure, but runs entirely in user space.  Two
contestants have been considered xoroshiro family of the functions
by Villa&Blackman and PCG by O'Neill.  After a consideration the
xoshiro128starstar function has been used as uint32_t random number
provider because it is very fast and has good enough properties
for our usage pattern.

The other change introduced in the commit is the more extensive usage
of isc_random_uniform in places where the usage pattern was
isc_random() % n to prevent modulo bias.  For usage patterns where
only 16 or 8 bits are needed (DNS Message ID), the isc_random()
functions has been renamed to isc_random32(), and isc_random16() and
isc_random8() functions have been introduced by &-ing the
isc_random32() output with 0xffff and 0xff.  Please note that the
functions that uses stripped down bit count doesn't pass our
NIST SP 800-22 based random test.
This commit is contained in:
Ondřej Surý 2018-05-28 15:22:23 +02:00
parent 1a9a1b48d7
commit 99ba29bc52
37 changed files with 542 additions and 267 deletions

View File

@ -63,6 +63,7 @@
#include <isc/log.h> #include <isc/log.h>
#include <isc/netaddr.h> #include <isc/netaddr.h>
#include <isc/netdb.h> #include <isc/netdb.h>
#include <isc/nonce.h>
#include <isc/parseint.h> #include <isc/parseint.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/random.h> #include <isc/random.h>
@ -1315,7 +1316,7 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) {
else if (keysecret[0] != 0) else if (keysecret[0] != 0)
setup_text_key(); setup_text_key();
isc_random_buf(cookie_secret, sizeof(cookie_secret)); isc_nonce_buf(cookie_secret, sizeof(cookie_secret));
} }
/*% /*%
@ -1870,8 +1871,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section)
srv != NULL; srv != NULL;
srv = ISC_LIST_HEAD(lookup->my_server_list)) { srv = ISC_LIST_HEAD(lookup->my_server_list)) {
INSIST(i > 0); INSIST(i > 0);
j = isc_random(); j = isc_random_uniform(i);
j %= i;
next = ISC_LIST_NEXT(srv, link); next = ISC_LIST_NEXT(srv, link);
while (j-- > 0 && next != NULL) { while (j-- > 0 && next != NULL) {
srv = next; srv = next;
@ -2023,7 +2023,6 @@ compute_cookie(unsigned char *clientcookie, size_t len) {
isc_boolean_t isc_boolean_t
setup_lookup(dig_lookup_t *lookup) { setup_lookup(dig_lookup_t *lookup) {
isc_result_t result; isc_result_t result;
isc_uint32_t id;
unsigned int len; unsigned int len;
dig_server_t *serv; dig_server_t *serv;
dig_query_t *query; dig_query_t *query;
@ -2198,8 +2197,7 @@ setup_lookup(dig_lookup_t *lookup) {
dighost_trying(store, lookup); dighost_trying(store, lookup);
INSIST(dns_name_isabsolute(lookup->name)); INSIST(dns_name_isabsolute(lookup->name));
id = isc_random(); lookup->sendmsg->id = (dns_messageid_t)isc_random16();
lookup->sendmsg->id = (unsigned short)id & 0xFFFF;
lookup->sendmsg->opcode = lookup->opcode; lookup->sendmsg->opcode = lookup->opcode;
lookup->msgcounter = 0; lookup->msgcounter = 0;
/* /*

View File

@ -20,6 +20,7 @@
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/net.h> #include <isc/net.h>
#include <isc/netaddr.h> #include <isc/netaddr.h>
#include <isc/nonce.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/result.h> #include <isc/result.h>
#include <isc/stdtime.h> #include <isc/stdtime.h>
@ -457,7 +458,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) {
*/ */
if (conn->nonce == 0) { if (conn->nonce == 0) {
while (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; eresult = ISC_R_SUCCESS;
} else } else

View File

@ -32,11 +32,11 @@
#include <isc/httpd.h> #include <isc/httpd.h>
#include <isc/lex.h> #include <isc/lex.h>
#include <isc/meminfo.h> #include <isc/meminfo.h>
#include <isc/nonce.h>
#include <isc/parseint.h> #include <isc/parseint.h>
#include <isc/platform.h> #include <isc/platform.h>
#include <isc/portset.h> #include <isc/portset.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/random.h>
#include <isc/refcount.h> #include <isc/refcount.h>
#include <isc/resource.h> #include <isc/resource.h>
#include <isc/sha2.h> #include <isc/sha2.h>
@ -5670,7 +5670,7 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
isc_random_buf(view->secret, sizeof(view->secret)); isc_nonce_buf(view->secret, sizeof(view->secret));
ISC_LIST_APPEND(*viewlist, view, link); ISC_LIST_APPEND(*viewlist, view, link);
dns_view_attach(view, viewp); dns_view_attach(view, viewp);
@ -8845,8 +8845,8 @@ load_configuration(const char *filename, named_server_t *server,
} }
} }
} else { } else {
isc_random_buf(server->sctx->secret, isc_nonce_buf(server->sctx->secret,
sizeof(server->sctx->secret)); sizeof(server->sctx->secret));
} }
/* /*
@ -13513,7 +13513,7 @@ generate_salt(unsigned char *salt, size_t saltlen) {
if (saltlen > 256U) if (saltlen > 256U)
return (ISC_R_RANGE); return (ISC_R_RANGE);
isc_random_buf(salt, saltlen); isc_nonce_buf(salt, saltlen);
r.base = salt; r.base = salt;
r.length = (unsigned int) saltlen; r.length = (unsigned int) saltlen;

View File

@ -29,6 +29,7 @@
#include <isc/lex.h> #include <isc/lex.h>
#include <isc/log.h> #include <isc/log.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/parseint.h> #include <isc/parseint.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/platform.h> #include <isc/platform.h>
@ -2829,14 +2830,16 @@ start_gssrequest(dns_name_t *master) {
fatal("out of memory"); 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); servname = dns_fixedname_initname(&fname);
if (realm == NULL) if (realm == NULL)
get_ticket_realm(gmctx); 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)); RUNTIME_CHECK(result < sizeof(servicename));
isc_buffer_init(&buf, servicename, strlen(servicename)); isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename)); isc_buffer_add(&buf, strlen(servicename));
@ -2848,9 +2851,10 @@ start_gssrequest(dns_name_t *master) {
keyname = dns_fixedname_initname(&fkname); 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)); RUNTIME_CHECK(result <= sizeof(mykeystr));
isc_buffer_init(&buf, mykeystr, strlen(mykeystr)); isc_buffer_init(&buf, mykeystr, strlen(mykeystr));

View File

@ -930,7 +930,7 @@ main(int argc, char **argv) {
if (argc < 1) if (argc < 1)
usage(1); usage(1);
serial = isc_random(); serial = isc_random32();
DO("create memory context", isc_mem_create(0, 0, &rndc_mctx)); DO("create memory context", isc_mem_create(0, 0, &rndc_mctx));
DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr)); DO("create socket manager", isc_socketmgr_create(rndc_mctx, &socketmgr));

View File

@ -20,6 +20,7 @@
#include <isc/hash.h> #include <isc/hash.h>
#include <isc/log.h> #include <isc/log.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/sockaddr.h> #include <isc/sockaddr.h>
@ -295,7 +296,7 @@ main(int argc, char *argv[]) {
CHECK("dst_key_fromnamedfile", result); CHECK("dst_key_fromnamedfile", result);
isc_buffer_init(&nonce, noncedata, sizeof(noncedata)); 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)); isc_buffer_add(&nonce, sizeof(noncedata));
(void)isc_app_run(); (void)isc_app_run();

View File

@ -22,6 +22,7 @@
#include <isc/log.h> #include <isc/log.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/net.h> #include <isc/net.h>
#include <isc/nonce.h>
#include <isc/parseint.h> #include <isc/parseint.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/random.h> #include <isc/random.h>
@ -1917,7 +1918,7 @@ main(int argc, char *argv[]) {
RUNCHECK(isc_log_create(mctx, &lctx, &lcfg)); RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
RUNCHECK(dst_lib_init(mctx, NULL)); 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); ISC_LIST_INIT(queries);
parse_args(ISC_FALSE, argc, argv); parse_args(ISC_FALSE, argc, argv);

View File

@ -1834,7 +1834,7 @@ new_adbentry(dns_adb_t *adb) {
e->to512 = 0; e->to512 = 0;
e->cookie = NULL; e->cookie = NULL;
e->cookielen = 0; e->cookielen = 0;
e->srtt = (isc_random() & 0x1f) + 1; e->srtt = (isc_random_uniform(0x1f)) + 1;
e->lastage = 0; e->lastage = 0;
e->expires = 0; e->expires = 0;
e->active = 0; e->active = 0;

View File

@ -693,7 +693,8 @@ get_dispsocket(dns_dispatch_t *disp, const isc_sockaddr_t *dest,
dispsock->resp = NULL; dispsock->resp = NULL;
dispsock->portentry = NULL; dispsock->portentry = NULL;
dispsock->task = 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, link);
ISC_LINK_INIT(dispsock, blink); ISC_LINK_INIT(dispsock, blink);
dispsock->magic = DISPSOCK_MAGIC; dispsock->magic = DISPSOCK_MAGIC;
@ -3169,7 +3170,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) { if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) {
id = *idp; id = *idp;
} else { } else {
isc_random_buf(&id, sizeof(id)); id = (dns_messageid_t)isc_random16();
} }
ok = ISC_FALSE; ok = ISC_FALSE;
i = 0; i = 0;

View File

@ -29,6 +29,7 @@
#include <isc/hmacmd5.h> #include <isc/hmacmd5.h>
#include <isc/hmacsha.h> #include <isc/hmacsha.h>
#include <isc/md5.h> #include <isc/md5.h>
#include <isc/nonce.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/sha1.h> #include <isc/sha1.h>
#include <isc/mem.h> #include <isc/mem.h>
@ -161,7 +162,7 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_MD5_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);
@ -468,7 +469,7 @@ hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_SHA1_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);
@ -758,7 +759,7 @@ hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_SHA224_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);
@ -1042,7 +1043,7 @@ hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_SHA256_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);
@ -1326,7 +1327,7 @@ hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_SHA384_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);
@ -1610,7 +1611,7 @@ hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int))
} }
memset(data, 0, ISC_SHA512_BLOCK_LENGTH); 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_init(&b, data, bytes);
isc_buffer_add(&b, bytes); isc_buffer_add(&b, bytes);

View File

@ -34,6 +34,7 @@
#include <string.h> #include <string.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/safe.h> #include <isc/safe.h>
#include <isc/sha1.h> #include <isc/sha1.h>
@ -351,7 +352,7 @@ openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
UNUSED(unused); UNUSED(unused);
isc_random_buf(rand_array, sizeof(rand_array)); isc_nonce_buf(rand_array, sizeof(rand_array));
dsa = DSA_new(); dsa = DSA_new();
if (dsa == NULL) if (dsa == NULL)

View File

@ -5415,12 +5415,12 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
isc_stdtime_get(&now); isc_stdtime_get(&now);
if (isc_mem_isovermem(rbtdb->common.mctx)) { 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. * 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. * Note that 'log' can be true IFF overmem is also true.

View File

@ -410,9 +410,9 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
* 'Random' order. * 'Random' order.
*/ */
for (i = 0; i < count; i++) { 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]; rdata = in[i];
in[i] = in[choice]; in[i] = in[choice];
in[choice] = rdata; in[choice] = rdata;
@ -432,7 +432,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
val = rdataset->count; val = rdataset->count;
if (val == ISC_UINT32_MAX) { if (val == ISC_UINT32_MAX) {
val = isc_random(); val = isc_random32();
} }
j = val % count; j = val % count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {

View File

@ -1182,7 +1182,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
* slow. We don't know. Increase the RTT. * slow. We don't know. Increase the RTT.
*/ */
INSIST(no_response); INSIST(no_response);
value = isc_random(); value = isc_random32();
if (query->addrinfo->srtt > 800000) if (query->addrinfo->srtt > 800000)
mask = 0x3fff; mask = 0x3fff;
else if (query->addrinfo->srtt > 400000) else if (query->addrinfo->srtt > 400000)

View File

@ -387,11 +387,11 @@ ATF_TC_BODY(deserialize_corrupt, tc) {
close(fd); close(fd);
/* Randomly fuzz a portion of the memory */ /* Randomly fuzz a portion of the memory */
p = base + (isc_random() % filesize); p = base + (isc_random_uniform(filesize));
q = base + filesize; q = base + filesize;
q -= (isc_random() % (q - p)); q -= (isc_random_uniform(q - p));
while (p++ < q) { while (p++ < q) {
*p = isc_random() & 0xff; *p = isc_random8();
} }
result = dns_rbt_deserialize_tree(base, filesize, 0, mctx, result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,

View File

@ -368,8 +368,8 @@ ATF_TC_BODY(rbt_check_distance_random, tc) {
dns_name_t *name; dns_name_t *name;
for (j = 0; j < 32; j++) { for (j = 0; j < 32; j++) {
isc_uint32_t v = isc_random(); isc_uint32_t v = isc_random_uniform(26);
namebuf[j] = 'a' + (v % 26); namebuf[j] = 'a' + v;
} }
namebuf[32] = '.'; namebuf[32] = '.';
namebuf[33] = 0; namebuf[33] = 0;
@ -894,8 +894,8 @@ insert_nodes(dns_rbt_t *mytree, char **names,
isc_result_t result; isc_result_t result;
for (j = 0; j < 32; j++) { for (j = 0; j < 32; j++) {
isc_uint32_t v = isc_random(); isc_uint32_t v = isc_random_uniform(26);
namebuf[j] = 'a' + (v % 26); namebuf[j] = 'a' + v;
} }
namebuf[32] = '.'; namebuf[32] = '.';
namebuf[33] = 0; namebuf[33] = 0;
@ -1019,9 +1019,8 @@ ATF_TC_BODY(rbt_insert_and_remove, tc) {
for (i = 0; i < 4096; i++) { for (i = 0; i < 4096; i++) {
isc_uint32_t num_names; isc_uint32_t num_names;
num_names = isc_random();
if (names_count < 1024) { if (names_count < 1024) {
num_names %= 1024 - names_count; num_names = isc_random_uniform(1024 - names_count);
num_names++; num_names++;
} else { } else {
num_names = 0; num_names = 0;
@ -1030,9 +1029,8 @@ ATF_TC_BODY(rbt_insert_and_remove, tc) {
insert_nodes(mytree, names, &names_count, num_names); insert_nodes(mytree, names, &names_count, num_names);
check_tree(mytree, names, names_count, __LINE__); check_tree(mytree, names, names_count, __LINE__);
num_names = isc_random();
if (names_count > 0) { if (names_count > 0) {
num_names %= names_count; num_names = isc_random_uniform(names_count);
num_names++; num_names++;
} else { } else {
num_names = 0; num_names = 0;

View File

@ -15,6 +15,7 @@
#include <isc/buffer.h> #include <isc/buffer.h>
#include <isc/md5.h> #include <isc/md5.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/string.h> #include <isc/string.h>
@ -411,7 +412,7 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
if (randomdata == NULL) if (randomdata == NULL)
goto failure; goto failure;
isc_random_buf(randomdata, TKEY_RANDOM_AMOUNT); isc_nonce_buf(randomdata, TKEY_RANDOM_AMOUNT);
r.base = randomdata; r.base = randomdata;
r.length = TKEY_RANDOM_AMOUNT; r.length = TKEY_RANDOM_AMOUNT;
@ -766,7 +767,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
isc_buffer_t b; isc_buffer_t b;
unsigned int i, j; 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++) { for (i = 0, j = 0; i < sizeof(randomdata); i++) {
unsigned char val = randomdata[i]; unsigned char val = randomdata[i];

View File

@ -805,7 +805,7 @@ xfrin_create(isc_mem_t *mctx,
dns_name_init(&xfr->name, NULL); dns_name_init(&xfr->name, NULL);
xfr->rdclass = rdclass; xfr->rdclass = rdclass;
xfr->checkid = ISC_TRUE; xfr->checkid = ISC_TRUE;
xfr->id = (isc_uint16_t)(isc_random() & 0xffff); xfr->id = (dns_messageid_t)isc_random16();
xfr->reqtype = reqtype; xfr->reqtype = reqtype;
xfr->dscp = dscp; xfr->dscp = dscp;

View File

@ -3576,8 +3576,7 @@ set_resigntime(dns_zone_t *zone) {
resign = rdataset.resign - zone->sigresigninginterval; resign = rdataset.resign - zone->sigresigninginterval;
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
nanosecs = isc_random(); nanosecs = isc_random_uniform(1000000000);
nanosecs %= 1000000000;
isc_time_set(&zone->resigntime, resign, nanosecs); isc_time_set(&zone->resigntime, resign, nanosecs);
cleanup: cleanup:
dns_db_detach(&db); dns_db_detach(&db);

View File

@ -51,12 +51,12 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/errno.@O@ \
OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \ OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \
aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
bind9.@O@ buffer.@O@ bufferlist.@O@ \ bind9.@O@ buffer.@O@ bufferlist.@O@ \
commandline.@O@ counter.@O@ crc64.@O@ error.@O@ event.@O@ \ commandline.@O@ counter.@O@ crc64.@O@ error.@O@ entropy.@O@ \
hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \ event.@O@ hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
hmacsha.@O@ httpd.@O@ iterated_hash.@O@ \ hmacsha.@O@ httpd.@O@ iterated_hash.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
md5.@O@ mem.@O@ mutexblock.@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@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \
rwlock.@O@ \ rwlock.@O@ \
@ -70,11 +70,11 @@ SYMTBLOBJS = backtrace-emptytbl.@O@
SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \ SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \
aes.c assertions.c backtrace.c base32.c base64.c bind9.c \ aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
buffer.c bufferlist.c commandline.c counter.c crc64.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 \ hmacsha.c httpd.c iterated_hash.c \
lex.c lfsr.c lib.c log.c \ lex.c lfsr.c lib.c log.c \
md5.c mem.c mutexblock.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 \ parseint.c portset.c quota.c radix.c random.c \
ratelimiter.c refcount.c region.c regex.c result.c rwlock.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 \ safe.c serial.c sha1.c sha2.c sockaddr.c stats.c string.c \

40
lib/isc/entropy.c Normal file
View File

@ -0,0 +1,40 @@
/*
* 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 */

36
lib/isc/entropy_private.h Normal file
View File

@ -0,0 +1,36 @@
/*
* 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

View File

@ -70,7 +70,7 @@ fnv_initialize(void) {
* again, it should not change fnv_offset_basis. * again, it should not change fnv_offset_basis.
*/ */
while (fnv_offset_basis == 0) { while (fnv_offset_basis == 0) {
fnv_offset_basis = isc_random(); fnv_offset_basis = isc_random32();
} }
fnv_initialized = ISC_TRUE; fnv_initialized = ISC_TRUE;

View File

@ -27,7 +27,7 @@ HEADERS = aes.h app.h assertions.h backtrace.h base32.h base64.h \
interfaceiter.h @ISC_IPV6_H@ iterated_hash.h \ interfaceiter.h @ISC_IPV6_H@ iterated_hash.h \
json.h lang.h lex.h lfsr.h lib.h likely.h list.h log.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 \ 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 \ pool.h portset.h print.h queue.h quota.h \
radix.h random.h ratelimiter.h refcount.h regex.h \ radix.h random.h ratelimiter.h refcount.h regex.h \
region.h resource.h result.h resultclass.h rwlock.h \ region.h resource.h result.h resultclass.h rwlock.h \

View File

@ -0,0 +1,32 @@
/*
* 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

View File

@ -17,31 +17,46 @@
#include <isc/lang.h> #include <isc/lang.h>
/*! \file isc/random.h /*! \file isc/random.h
* \brief Implements wrapper around system provider pseudo-random data * \brief Implements wrapper around a non-cryptographically secure
* generators. * pseudo-random number generator.
*
* 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()
* *
*/ */
ISC_LANG_BEGINDECLS 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 uint32_t
isc_random(void); isc_random32(void);
/*!<
* \brief Returns a single 32-bit random value.
*/
void void
isc_random_buf(void *buf, size_t buflen); 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 uint32_t
isc_random_uniform(uint32_t upper_bound); 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 ISC_LANG_ENDDECLS

21
lib/isc/nonce.c Normal file
View File

@ -0,0 +1,21 @@
/*
* 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));
}

View File

@ -98,8 +98,7 @@ isc_pool_create(isc_mem_t *mctx, unsigned int count,
void * void *
isc_pool_get(isc_pool_t *pool) { isc_pool_get(isc_pool_t *pool) {
isc_uint32_t i = isc_random(); return (pool->pool[isc_random_uniform(pool->count)]);
return (pool->pool[i % pool->count]);
} }
int int

View File

@ -32,162 +32,95 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.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/random.h>
#include <isc/result.h> #include <isc/result.h>
#include <isc/types.h> #include <isc/types.h>
#include <isc/util.h> #include <isc/util.h>
#if defined(_WIN32) || defined(_WIN64)
#include <isc/once.h> #include <isc/once.h>
#endif
#if defined(__linux__) #include "entropy_private.h"
# 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) { * The specific implementation for PRNG is included as a C file
uint16_t buf; * that has to provide a static variable named seed, and a function
ssize_t ret; * uint32_t next(void) that provides next random number.
ret = getrandom(&buf, sizeof(buf), 1 /*GRND_NONBLOCK*/); *
return (ret == sizeof(buf) || * The implementation must be thread-safe.
(ret == -1 && errno == EAGAIN)); */
}
# else /* defined(SYS_getrandom) */ /*
# define have_getrandom() 0 * Two contestants have been considered: the xoroshiro family of the
# define getrandom(dst,s,flags) -1 * functions by Villa&Blackman, and PCG by O'Neill. After
# endif /* defined(SYS_getrandom) */ * consideration, the xoshiro128starstar function has been chosen as
# endif /* ifdef HAVE_GETRANDOM */ * the uint32_t random number provider because it is very fast and has
* good enough properties for our usage pattern.
static int */
getrandom_buf(void *buf, size_t buflen) { #include "xoshiro128starstar.c"
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;
}
}
return(0);
}
#endif /* __linux__ */
#if defined(_WIN32) || defined(_WIN64)
static isc_once_t isc_random_once = ISC_ONCE_INIT; static isc_once_t isc_random_once = ISC_ONCE_INIT;
static HCRYPTPROV isc_random_hcryptprov; static void
isc_random_initialize(void) {
static void isc_random_initialize(void) { isc_entropy_get(seed, sizeof(seed));
RUNTIME_CHECK(CryptAcquireContext(&isc_random_hcryptprov,
NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
} }
#endif /* defined(_WIN32) || defined(_WIN64) */ uint8_t
isc_random8(void) {
RUNTIME_CHECK(isc_once_do(&isc_random_once,
isc_random_initialize) == ISC_R_SUCCESS);
return (next() & 0xff);
}
uint16_t
isc_random16(void) {
RUNTIME_CHECK(isc_once_do(&isc_random_once,
isc_random_initialize) == ISC_R_SUCCESS);
return (next() & 0xffff);
}
uint32_t uint32_t
isc_random(void) { isc_random32(void) {
#if defined(HAVE_ARC4RANDOM) RUNTIME_CHECK(isc_once_do(&isc_random_once,
return(arc4random()); isc_random_initialize) == ISC_R_SUCCESS);
#else /* HAVE_ARC4RANDOM */ return (next());
uint32_t ret;
isc_random_buf(&ret, sizeof(ret));
return (ret);
#endif /* HAVE_ARC4RANDOM */
} }
/*
* Fill the region buf of length buflen with random data.
*/
void void
isc_random_buf(void *buf, size_t buflen) { isc_random_buf(void *buf, size_t buflen) {
REQUIRE(buf); REQUIRE(buf);
REQUIRE(buflen > 0); REQUIRE(buflen > 0);
#if defined(_WIN32) || defined(_WIN64)
RUNTIME_CHECK(isc_once_do(&isc_random_once, RUNTIME_CHECK(isc_once_do(&isc_random_once,
isc_random_initialize) == ISC_R_SUCCESS); 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__) int i;
/* uint32_t r;
* We need to check the availability of the SYS_getrandom
* syscall at runtime and fall back to crypto library provider for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) {
* if not available r = next();
*/ memmove((uint8_t *)buf + i, &r, sizeof(r)); /* Buffers cannot
if (have_getrandom()) { * really overlap
getrandom_buf(buf, buflen); * here */
return;
} }
r = next();
# endif /* defined(__linux__) */ memmove((uint8_t *)buf + i, &r, buflen % sizeof(r)); /* Buffer cannot
* really overlap
/* Use crypto library as fallback when no other CSPRNG is available */ * here */
# if HAVE_OPENSSL return;
if (RAND_bytes(buf, buflen) < 1) {
FATAL_ERROR(__FILE__, __LINE__, "RAND_bytes(): %s", ERR_error_string(ERR_get_error(), NULL));
}
# elif HAVE_PKCS11
RUNTIME_CHECK(pk11_rand_bytes(buf, buflen) == ISC_R_SUCCESS);
# endif /* if defined(HAVE_ARC4RANDOM_BUF) */
#endif
} }
uint32_t uint32_t
isc_random_uniform(uint32_t upper_bound) { 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 */ /* Copy of arc4random_uniform from OpenBSD */
uint32_t r, min; uint32_t r, min;
RUNTIME_CHECK(isc_once_do(&isc_random_once,
isc_random_initialize) == ISC_R_SUCCESS);
if (upper_bound < 2) { if (upper_bound < 2) {
return (0); return (0);
} }
@ -211,12 +144,11 @@ isc_random_uniform(uint32_t upper_bound) {
* to re-roll. * to re-roll.
*/ */
for (;;) { for (;;) {
r = isc_random(); r = next();
if (r >= min) { if (r >= min) {
break; break;
} }
} }
return (r % upper_bound); return (r % upper_bound);
#endif /* if defined(HAVE_ARC4RANDOM_UNIFORM) */
} }

View File

@ -95,8 +95,7 @@ isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
void void
isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) { isc_taskpool_gettask(isc_taskpool_t *pool, isc_task_t **targetp) {
isc_uint32_t i = isc_random(); isc_task_attach(pool->tasks[isc_random_uniform(pool->ntasks)], targetp);
isc_task_attach(pool->tasks[i % pool->ntasks], targetp);
} }
int int

View File

@ -21,6 +21,7 @@
#include <isc/random.h> #include <isc/random.h>
#include <isc/result.h> #include <isc/result.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/nonce.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/util.h> #include <isc/util.h>
@ -53,6 +54,15 @@ static double biginv = 2.22044604925031308085e-16;
static double igamc(double a, double x); static double igamc(double a, double x);
static double igam(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 static double
igamc(double a, double x) { igamc(double a, double x) {
double ans, ax, c, yc, r, t, y, z; double ans, ax, c, yc, r, t, y, z;
@ -250,7 +260,7 @@ matrix_binaryrank(isc_uint32_t *bits, size_t rows, size_t cols) {
} }
static void 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_mem_t *mctx = NULL;
isc_result_t result; isc_result_t result;
isc_uint32_t m; isc_uint32_t m;
@ -274,18 +284,48 @@ random_test(pvalue_func_t *func, isc_boolean_t word_sized) {
for (j = 0; j < m; j++) { for (j = 0; j < m; j++) {
isc_uint32_t i; isc_uint32_t i;
isc_uint16_t values[REPS]; isc_uint32_t values[REPS];
isc_uint16_t *uniform_values;
double p_value; double p_value;
if (word_sized) { switch (test_func) {
for (i = 0; i < REPS; i++) { case ISC_RANDOM8:
isc_random_buf(&values[i], sizeof(values[i])); 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)); 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) { if (p_value >= 0.01) {
passed++; passed++;
} }
@ -364,7 +404,7 @@ monobit(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
UNUSED(mctx); UNUSED(mctx);
numbits = length * 16; numbits = length * sizeof(*values) * 8;
scount = 0; scount = 0;
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
@ -403,10 +443,10 @@ runs(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
UNUSED(mctx); UNUSED(mctx);
numbits = length * 16; numbits = length * sizeof(*values) * 8;
bcount = 0; bcount = 0;
for (i = 0; i < REPS; i++) for (i = 0; i < length; i++)
bcount += bitcounts_table[values[i]]; bcount += bitcounts_table[values[i]];
/* Debug message, not displayed when running via atf-run */ /* Debug message, not displayed when running via atf-run */
@ -472,7 +512,7 @@ blockfrequency(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
double chi_square; double chi_square;
double p_value; double p_value;
numbits = length * 16; numbits = length * sizeof(*values) * 8;
mbits = 32000; mbits = 32000;
mwords = mbits / 16; mwords = mbits / 16;
numblocks = numbits / mbits; numblocks = numbits / mbits;
@ -512,7 +552,7 @@ blockfrequency(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
isc_mem_put(mctx, pi, numblocks * sizeof(double)); isc_mem_put(mctx, pi, numblocks * sizeof(double));
/* Debug message, not displayed when running via atf-run */ /* 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); p_value = igamc(numblocks * 0.5, chi_square * 0.5);
@ -605,114 +645,208 @@ binarymatrixrank(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
return (p_value); return (p_value);
} }
ATF_TC(isc_random_monobit_16); /* Tests for isc_random32() function */
ATF_TC_HEAD(isc_random_monobit_16, tc) {
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_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); UNUSED(tc);
random_test(monobit, ISC_TRUE); random_test(monobit, ISC_RANDOM_BYTES);
} }
ATF_TC(isc_random_runs_16); ATF_TC(isc_random_bytes_runs);
ATF_TC_HEAD(isc_random_runs_16, tc) { ATF_TC_HEAD(isc_random_bytes_runs, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM"); 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); UNUSED(tc);
random_test(runs, ISC_TRUE); random_test(runs, ISC_RANDOM_BYTES);
} }
ATF_TC(isc_random_blockfrequency_16); ATF_TC(isc_random_bytes_blockfrequency);
ATF_TC_HEAD(isc_random_blockfrequency_16, tc) { ATF_TC_HEAD(isc_random_bytes_blockfrequency, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM"); 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); UNUSED(tc);
random_test(blockfrequency, ISC_TRUE); random_test(blockfrequency, ISC_RANDOM_BYTES);
} }
ATF_TC(isc_random_binarymatrixrank_16); ATF_TC(isc_random_bytes_binarymatrixrank);
ATF_TC_HEAD(isc_random_binarymatrixrank_16, tc) { ATF_TC_HEAD(isc_random_bytes_binarymatrixrank, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM"); atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
} }
/* ATF_TC_BODY(isc_random_bytes_binarymatrixrank, tc) {
* 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) {
UNUSED(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_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); UNUSED(tc);
random_test(monobit, ISC_FALSE); random_test(monobit, ISC_RANDOM_UNIFORM);
} }
ATF_TC(isc_random_runs_bytes); ATF_TC(isc_random_uniform_runs);
ATF_TC_HEAD(isc_random_runs_bytes, tc) { ATF_TC_HEAD(isc_random_uniform_runs, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RANDOM"); 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); UNUSED(tc);
random_test(runs, ISC_FALSE); random_test(runs, ISC_RANDOM_UNIFORM);
} }
ATF_TC(isc_random_blockfrequency_bytes); ATF_TC(isc_random_uniform_blockfrequency);
ATF_TC_HEAD(isc_random_blockfrequency_bytes, tc) { ATF_TC_HEAD(isc_random_uniform_blockfrequency, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RANDOM"); 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); UNUSED(tc);
random_test(blockfrequency, ISC_FALSE); random_test(blockfrequency, ISC_RANDOM_UNIFORM);
} }
ATF_TC(isc_random_binarymatrixrank_bytes); ATF_TC(isc_random_uniform_binarymatrixrank);
ATF_TC_HEAD(isc_random_binarymatrixrank_bytes, tc) { ATF_TC_HEAD(isc_random_uniform_binarymatrixrank, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM"); atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RANDOM");
} }
/* ATF_TC_BODY(isc_random_uniform_binarymatrixrank, tc) {
* 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) {
UNUSED(tc); UNUSED(tc);
random_test(binarymatrixrank, ISC_FALSE); 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_NONCE_BYTES);
} }
/* /*
* Main * Main
*/ */
ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, isc_random_monobit_16); ATF_TP_ADD_TC(tp, isc_random32_monobit);
ATF_TP_ADD_TC(tp, isc_random_runs_16); ATF_TP_ADD_TC(tp, isc_random32_runs);
ATF_TP_ADD_TC(tp, isc_random_blockfrequency_16); ATF_TP_ADD_TC(tp, isc_random32_blockfrequency);
ATF_TP_ADD_TC(tp, isc_random_binarymatrixrank_16); ATF_TP_ADD_TC(tp, isc_random32_binarymatrixrank);
ATF_TP_ADD_TC(tp, isc_random_monobit_bytes); ATF_TP_ADD_TC(tp, isc_random_bytes_monobit);
ATF_TP_ADD_TC(tp, isc_random_runs_bytes); ATF_TP_ADD_TC(tp, isc_random_bytes_runs);
ATF_TP_ADD_TC(tp, isc_random_blockfrequency_bytes); ATF_TP_ADD_TC(tp, isc_random_bytes_blockfrequency);
ATF_TP_ADD_TC(tp, isc_random_binarymatrixrank_bytes); 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()); return (atf_no_error());
} }

View File

@ -272,8 +272,7 @@ isc_file_renameunique(const char *file, char *templet) {
x = cp--; x = cp--;
while (cp >= templet && *cp == 'X') { while (cp >= templet && *cp == 'X') {
isc_uint32_t which = isc_random(); *cp = alphnum[isc_random_uniform(sizeof(alphnum) - 1)];
*cp = alphnum[which % (sizeof(alphnum) - 1)];
x = cp--; x = cp--;
} }
while (link(file, templet) == -1) { while (link(file, templet) == -1) {
@ -329,8 +328,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
x = cp--; x = cp--;
while (cp >= templet && *cp == 'X') { while (cp >= templet && *cp == 'X') {
isc_uint32_t which = isc_random(); *cp = alphnum[isc_random_uniform(sizeof(alphnum) - 1)];
*cp = alphnum[which % (sizeof(alphnum) - 1)];
x = cp--; x = cp--;
} }

View File

@ -56,8 +56,8 @@ gettemp(char *path, isc_boolean_t binary, int *doopen) {
trv++; trv++;
/* extra X's get set to 0's */ /* extra X's get set to 0's */
while (*--trv == 'X') { while (*--trv == 'X') {
isc_uint32_t which = isc_random(); isc_uint32_t which = isc_random_uniform(sizeof(alphnum) - 1);
*trv = alphnum[which % (sizeof(alphnum) - 1)]; *trv = alphnum[which];
} }
/* /*
* check the target directory; if you have six X's and it * check the target directory; if you have six X's and it

View File

@ -0,0 +1,58 @@
/*
* 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);
}

View File

@ -17,6 +17,7 @@
#include <isc/hmacsha.h> #include <isc/hmacsha.h>
#include <isc/mutex.h> #include <isc/mutex.h>
#include <isc/once.h> #include <isc/once.h>
#include <isc/nonce.h>
#include <isc/platform.h> #include <isc/platform.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/queue.h> #include <isc/queue.h>
@ -1652,7 +1653,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
isc_buffer_init(&buf, cookie, sizeof(cookie)); isc_buffer_init(&buf, cookie, sizeof(cookie));
isc_stdtime_get(&now); 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); compute_cookie(client, now, nonce, client->sctx->secret, &buf);

View File

@ -534,7 +534,6 @@ attach_query_msg_to_client(ns_client_t *client, const char *qnamestr,
isc_buffer_t querybuf; isc_buffer_t querybuf;
dns_compress_t cctx; dns_compress_t cctx;
isc_result_t result; isc_result_t result;
isc_uint32_t qid;
REQUIRE(client != NULL); REQUIRE(client != NULL);
REQUIRE(qnamestr != NULL); REQUIRE(qnamestr != NULL);
@ -550,8 +549,7 @@ attach_query_msg_to_client(ns_client_t *client, const char *qnamestr,
/* /*
* Set query ID to a random value. * Set query ID to a random value.
*/ */
qid = isc_random(); message->id = isc_random16();
message->id = (dns_messageid_t)(qid & 0xffff);
/* /*
* Set query flags as requested by the caller. * Set query flags as requested by the caller.

View File

@ -3482,6 +3482,9 @@
./lib/isc/commandline.c C.PORTION 1999,2000,2001,2004,2005,2007,2008,2014,2015,2016,2018 ./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/counter.c C 2014,2016,2018
./lib/isc/crc64.c C 2013,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/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/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/fsaccess.c C 2000,2001,2004,2005,2007,2016,2017,2018
@ -3547,6 +3550,7 @@
./lib/isc/include/isc/mutexblock.h C 1999,2000,2001,2004,2005,2006,2007,2016,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/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/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/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/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/include/isc/platform.h.in C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013,2014,2015,2016,2017,2018
@ -3618,6 +3622,7 @@
./lib/isc/noatomic/include/Makefile.in MAKE 2007,2012,2016,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/Makefile.in MAKE 2007,2012,2015,2016,2018
./lib/isc/noatomic/include/isc/atomic.h C 2005,2007,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/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/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/nothreads/include/Makefile.in MAKE 2000,2001,2004,2007,2012,2016,2018
@ -3827,6 +3832,7 @@
./lib/isc/x86_64/include/Makefile.in MAKE 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/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/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/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/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 ./lib/isccc/api X 2001,2006,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018