Commit bebc1b9c authored by Jan Včelák's avatar Jan Včelák 🚀

use pseudo-random generator from OpenSSL, drop SFMT

parent a5e86834
......@@ -164,6 +164,7 @@ libknot_la_SOURCES = \
libknot/dnssec/nsec3.c \
libknot/dnssec/nsec3.h \
libknot/dnssec/policy.h \
libknot/dnssec/random.h \
libknot/dnssec/rrset-sign.c \
libknot/dnssec/rrset-sign.h \
libknot/dnssec/sig0.c \
......@@ -216,12 +217,6 @@ libknots_la_SOURCES = \
common/errors.c \
common/errcode.h \
common/errcode.c \
common/dSFMT.h \
common/dSFMT-params.h \
common/dSFMT-params521.h \
common/dSFMT.c \
common/prng.h \
common/prng.c \
common/fdset.h \
common/fdset.c \
common/getline.h \
......
#ifndef DSFMT_PARAMS_H
#define DSFMT_PARAMS_H
#include "common/dSFMT.h"
/*----------------------
the parameters of DSFMT
following definitions are in dSFMT-paramsXXXX.h file.
----------------------*/
/** the pick up position of the array.
#define DSFMT_POS1 122
*/
/** the parameter of shift left as four 32-bit registers.
#define DSFMT_SL1 18
*/
/** the parameter of shift right as four 32-bit registers.
#define DSFMT_SR1 12
*/
/** A bitmask, used in the recursion. These parameters are introduced
* to break symmetry of SIMD.
#define DSFMT_MSK1 (uint64_t)0xdfffffefULL
#define DSFMT_MSK2 (uint64_t)0xddfecb7fULL
*/
/** These definitions are part of a 128-bit period certification vector.
#define DSFMT_PCV1 UINT64_C(0x00000001)
#define DSFMT_PCV2 UINT64_C(0x00000000)
*/
#define DSFMT_LOW_MASK UINT64_C(0x000FFFFFFFFFFFFF)
#define DSFMT_HIGH_CONST UINT64_C(0x3FF0000000000000)
#define DSFMT_SR 12
/* for sse2 */
#if defined(HAVE_SSE2)
#define SSE2_SHUFF 0x1b
#elif defined(HAVE_ALTIVEC)
#if defined(__APPLE__) /* For OSX */
#define ALTI_SR (vector unsigned char)(4)
#define ALTI_SR_PERM \
(vector unsigned char)(15,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14)
#define ALTI_SR_MSK \
(vector unsigned int)(0x000fffffU,0xffffffffU,0x000fffffU,0xffffffffU)
#define ALTI_PERM \
(vector unsigned char)(12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3)
#else
#define ALTI_SR {4}
#define ALTI_SR_PERM {15,0,1,2,3,4,5,6,15,8,9,10,11,12,13,14}
#define ALTI_SR_MSK {0x000fffffU,0xffffffffU,0x000fffffU,0xffffffffU}
#define ALTI_PERM {12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3}
#endif
#endif
#if DSFMT_MEXP == 521
#include "common/dSFMT-params521.h"
#elif DSFMT_MEXP == 1279
#include "dSFMT-params1279.h"
#elif DSFMT_MEXP == 2203
#include "dSFMT-params2203.h"
#elif DSFMT_MEXP == 4253
#include "dSFMT-params4253.h"
#elif DSFMT_MEXP == 11213
#include "dSFMT-params11213.h"
#elif DSFMT_MEXP == 19937
#include "dSFMT-params19937.h"
#elif DSFMT_MEXP == 44497
#include "dSFMT-params44497.h"
#elif DSFMT_MEXP == 86243
#include "dSFMT-params86243.h"
#elif DSFMT_MEXP == 132049
#include "dSFMT-params132049.h"
#elif DSFMT_MEXP == 216091
#include "dSFMT-params216091.h"
#else
#ifdef __GNUC__
#error "DSFMT_MEXP is not valid."
#undef DSFMT_MEXP
#else
#undef DSFMT_MEXP
#endif
#endif
#endif /* DSFMT_PARAMS_H */
#ifndef DSFMT_PARAMS521_H
#define DSFMT_PARAMS521_H
/* #define DSFMT_N 4 */
/* #define DSFMT_MAXDEGREE 544 */
#define DSFMT_POS1 3
#define DSFMT_SL1 25
#define DSFMT_MSK1 UINT64_C(0x000fbfefff77efff)
#define DSFMT_MSK2 UINT64_C(0x000ffeebfbdfbfdf)
#define DSFMT_MSK32_1 0x000fbfefU
#define DSFMT_MSK32_2 0xff77efffU
#define DSFMT_MSK32_3 0x000ffeebU
#define DSFMT_MSK32_4 0xfbdfbfdfU
#define DSFMT_FIX1 UINT64_C(0xcfb393d661638469)
#define DSFMT_FIX2 UINT64_C(0xc166867883ae2adb)
#define DSFMT_PCV1 UINT64_C(0xccaa588000000000)
#define DSFMT_PCV2 UINT64_C(0x0000000000000001)
#define DSFMT_IDSTR "dSFMT2-521:3-25:fbfefff77efff-ffeebfbdfbfdf"
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(1, 1, 1, 1)
#define ALTI_SL1_PERM \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SL1_MSK \
(vector unsigned int)(0xffffffffU,0xfe000000U,0xffffffffU,0xfe000000U)
#define ALTI_MSK (vector unsigned int)(DSFMT_MSK32_1, \
DSFMT_MSK32_2, DSFMT_MSK32_3, DSFMT_MSK32_4)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {1, 1, 1, 1}
#define ALTI_SL1_PERM \
{3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SL1_MSK \
{0xffffffffU,0xfe000000U,0xffffffffU,0xfe000000U}
#define ALTI_MSK \
{DSFMT_MSK32_1, DSFMT_MSK32_2, DSFMT_MSK32_3, DSFMT_MSK32_4}
#endif
#endif /* DSFMT_PARAMS521_H */
This diff is collapsed.
This diff is collapsed.
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <config.h>
#ifdef HAVE_POSIX_MEMALIGN
#include <stdlib.h>
#endif
#include "libknot/common.h"
#include "common/prng.h"
#include "common/dSFMT.h"
/*! \brief TLS unique key for each thread seed. */
static pthread_key_t tls_prng_key;
static pthread_once_t tls_prng_once = PTHREAD_ONCE_INIT;
static void tls_prng_deinit(void *ptr)
{
free(ptr);
}
static void tls_prng_deinit_main()
{
tls_prng_deinit(pthread_getspecific(tls_prng_key));
UNUSED(pthread_setspecific(tls_prng_key, NULL));
}
static void tls_prng_init()
{
UNUSED(pthread_key_create(&tls_prng_key, tls_prng_deinit));
atexit(tls_prng_deinit_main); // Main thread cleanup
}
double tls_rand()
{
/* Setup PRNG state for current thread. */
UNUSED(pthread_once(&tls_prng_once, tls_prng_init));
/* Create PRNG state if not exists. */
dsfmt_t* s = pthread_getspecific(tls_prng_key);
if (!s) {
/* Initialize seed from system PRNG generator. */
uint32_t seed = 0;
FILE *fp = fopen("/dev/urandom", "r");
if (fp == NULL) {
fp = fopen("/dev/random", "r");
}
if (fp != NULL) {
if (fread(&seed, sizeof(uint32_t), 1, fp) != 1) {
fclose(fp);
fp = NULL;
}
}
if (fp == NULL) {
fprintf(stderr, "error: PRNG: cannot seed from "
"/dev/urandom, seeding from local time\n");
struct timeval tv;
if (gettimeofday(&tv, NULL) == 0) {
seed = (uint32_t)(tv.tv_sec ^ tv.tv_usec);
} else {
/* Last resort. */
seed = (uint32_t)time(NULL);
}
} else {
fclose(fp);
}
/* Initialize PRNG state. */
#ifdef HAVE_POSIX_MEMALIGN
if (posix_memalign((void **)&s, 16, sizeof(dsfmt_t)) != 0) {
fprintf(stderr, "error: PRNG: not enough memory\n");
return .0;
}
#else
if ((s = malloc(sizeof(dsfmt_t))) == NULL) {
fprintf(stderr, "error: PRNG: not enough memory\n");
return .0;
}
#endif
dsfmt_init_gen_rand(s, seed);
UNUSED(pthread_setspecific(tls_prng_key, s));
}
return dsfmt_genrand_close_open(s);
}
......@@ -19,7 +19,6 @@
#include "knot/ctl/remote.h"
#include "common/log.h"
#include "common/fdset.h"
#include "common/prng.h"
#include "knot/knot.h"
#include "knot/conf/conf.h"
#include "knot/server/socket.h"
......@@ -32,6 +31,7 @@
#include "libknot/nameserver/name-server.h"
#include "libknot/tsig-op.h"
#include "libknot/rdata.h"
#include "libknot/dnssec/random.h"
#include "libknot/dnssec/zone-sign.h"
#include "libknot/dnssec/zone-nsec.h"
......@@ -137,7 +137,7 @@ static int remote_zone_refresh(server_t *s, const knot_zone_t *z)
if (zd->xfr_in.timer) {
evsched_cancel(sch, zd->xfr_in.timer);
evsched_schedule(sch, zd->xfr_in.timer,
tls_rand() * 1000);
knot_random_uint32_t() % 1000);
}
return KNOT_EOK;
......@@ -161,7 +161,7 @@ static int remote_zone_flush(server_t *s, const knot_zone_t *z)
if (zd->ixfr_dbsync) {
evsched_cancel(sch, zd->ixfr_dbsync);
evsched_schedule(sch, zd->ixfr_dbsync,
tls_rand() * 1000);
knot_random_uint32_t() % 1000);
}
return KNOT_EOK;
......
......@@ -26,7 +26,7 @@
#include "libknot/consts.h"
#include "libknot/util/wire.h"
#include "common/hattrie/murmurhash3.h"
#include "common/prng.h"
#include "libknot/dnssec/random.h"
#include "common/descriptor.h"
#include "common/errors.h"
......@@ -508,7 +508,7 @@ int rrl_reseed(rrl_table_t *rrl)
}
memset(rrl->arr, 0, rrl->size * sizeof(rrl_item_t));
rrl->seed = (uint32_t)(tls_rand() * (double)UINT32_MAX);
rrl->seed = knot_random_uint32_t();
dbg_rrl("%s: reseed to '%u'\n", __func__, rrl->seed);
if (rrl->lk_count > 0) {
......
......@@ -22,7 +22,6 @@
#include <errno.h>
#include <assert.h>
#include "common/prng.h"
#include "knot/knot.h"
#include "knot/server/server.h"
#include "knot/server/udp-handler.h"
......@@ -35,6 +34,7 @@
#include "libknot/zone/zonedb.h"
#include "libknot/dname.h"
#include "libknot/dnssec/crypto.h"
#include "libknot/dnssec/random.h"
/*! \brief Event scheduler loop. */
static int evsched_run(dthread_t *thread)
......@@ -482,7 +482,7 @@ int server_refresh(server_t *server)
if (zd->xfr_in.timer) {
evsched_cancel(sch, zd->xfr_in.timer);
evsched_schedule(sch, zd->xfr_in.timer,
tls_rand() * 500 + i/2);
knot_random_int() % 500 + i/2);
/* Cumulative delay. */
}
}
......
......@@ -64,7 +64,7 @@ enum {
/*! \brief Calculate TCP throttle time (random). */
static inline int tcp_throttle() {
//(TCP_THROTTLE_LO + (int)(tls_rand() * TCP_THROTTLE_HI));
//(TCP_THROTTLE_LO + knot_random_int() % TCP_THROTTLE_HI;
return (rand() % TCP_THROTTLE_HI) + TCP_THROTTLE_LO;
}
......
......@@ -39,9 +39,9 @@
#include "knot/server/zones.h"
#include "libknot/tsig-op.h"
#include "common/evsched.h"
#include "common/prng.h"
#include "common/descriptor.h"
#include "libknot/rrset.h"
#include "libknot/dnssec/random.h"
/* Constants */
#define XFR_MAX_TASKS 1024 /*! Maximum pending tasks. */
......@@ -322,7 +322,7 @@ static int xfr_task_close(knot_ns_xfr_t *rq)
/* Reschedule failed bootstrap. */
if (rq->type == XFR_TYPE_AIN && !knot_zone_contents(rq->zone)) {
/* Progressive retry interval up to AXFR_RETRY_MAXTIME */
zd->xfr_in.bootstrap_retry += AXFR_BOOTSTRAP_RETRY * tls_rand();
zd->xfr_in.bootstrap_retry += knot_random_uint32_t() % AXFR_BOOTSTRAP_RETRY;
if (zd->xfr_in.bootstrap_retry > AXFR_RETRY_MAXTIME)
zd->xfr_in.bootstrap_retry = AXFR_RETRY_MAXTIME;
event_t *ev = zd->xfr_in.timer;
......@@ -554,7 +554,7 @@ static int xfr_async_finish(fdset_t *set, unsigned id)
* To accomodate for this, <0, 5>s random delay is set on
* event startup, so the first query fires when this timer
* expires. */
fdset_set_watchdog(set, id, (int)(tls_rand() * 5));
fdset_set_watchdog(set, id, knot_random_int() % 6);
return KNOT_EOK;
case XFR_TYPE_SOA:
case XFR_TYPE_FORWARD:
......
......@@ -19,7 +19,6 @@
#include <sys/stat.h>
#include <inttypes.h>
#include "common/prng.h"
#include "knot/conf/conf.h"
#include "knot/other/debug.h"
#include "knot/server/zone-load.h"
......@@ -27,6 +26,7 @@
#include "knot/zone/zone-load.h"
#include "libknot/dname.h"
#include "libknot/dnssec/crypto.h"
#include "libknot/dnssec/random.h"
#include "libknot/nameserver/name-server.h"
#include "libknot/rdata.h"
#include "libknot/zone/zone.h"
......@@ -121,7 +121,7 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
/* Initialize XFR-IN. */
sockaddr_init(&zd->xfr_in.master, -1);
zd->xfr_in.bootstrap_retry = (XFRIN_BOOTSTRAP_DELAY * tls_rand());
zd->xfr_in.bootstrap_retry = knot_random_uint32_t() % XFRIN_BOOTSTRAP_DELAY;
/* Initialize IXFR database. */
zd->ixfr_db = journal_open(cfg->ixfr_db, cfg->ixfr_fslimit, JOURNAL_DIRTY);
......
......@@ -21,7 +21,6 @@
#include "common/lists.h"
#include "common/log.h"
#include "common/prng.h"
#include "knot/conf/conf.h"
#include "knot/other/debug.h"
#include "knot/server/server.h"
......@@ -30,6 +29,7 @@
#include "knot/server/zones.h"
#include "knot/zone/zone-dump.h"
#include "libknot/dname.h"
#include "libknot/dnssec/random.h"
#include "libknot/dnssec/zone-events.h"
#include "libknot/nameserver/chaos.h"
#include "libknot/packet/response.h"
......@@ -58,7 +58,7 @@ static int zones_dump_zone_text(knot_zone_contents_t *zone, const char *zf);
*/
static uint32_t zones_jitter(uint32_t interval)
{
return (interval * (100 - (tls_rand() * ZONES_JITTER_PCT))) / 100;
return (interval * (100 - (knot_random_uint32_t() % ZONES_JITTER_PCT))) / 100;
}
/*!
......
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2013 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -12,32 +12,61 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
/*!
* \file prng.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
* \file random.h
*
* \brief Pseudo-random number generator interface.
* \author Jan Vcelak <jan.vcelak@nic.cz>
*
* Interface for accessing underlying PRNG.
* \brief Interface for pseudo-random generator from OpenSSL.
*
* \addtogroup common_lib
* \addtogroup dnssec
* @{
*/
#ifndef _KNOTD_PRNG_H_
#define _KNOTD_PRNG_H_
#ifndef _KNOT_DNSSEC_RANDOM_H
#define _KNOT_DNSSEC_RANDOM_H
#include <assert.h>
#include <openssl/rand.h>
#include <stdint.h>
#include "common/errcode.h"
/*!
* \brief Get pseudorandom number from PRNG initialized in thread-local storage.
* \brief Fill a buffer with random data.
*
* No need for initialization, TLS will take care of it.
* \note Always succeeds, but might not provide cryptographically strong random.
*
* \retval Pseudorandom number.
* \param dest Pointer to output buffer.
* \param size Size of output buffer.
*
* \retval 1 Cryptographically strong random data were written.
* \retval 0 Cryptographically weak random data were written.
*/
static inline int knot_random_buffer(void *dest, size_t size)
{
assert(dest);
int result = RAND_pseudo_bytes(dest, (int)size);
assert(result != -1);
return result;
}
/*!
* \brief Declare function knot_random_<type>().
*/
double tls_rand();
#define _knot_register_random_type(type) \
static inline type knot_random_##type(void) { \
type buffer; \
knot_random_buffer(&buffer, sizeof(buffer)); \
return buffer; \
}
_knot_register_random_type(int);
_knot_register_random_type(uint16_t);
_knot_register_random_type(uint32_t);
#endif //_KNOTD_ACL_H_
#endif // _KNOT_DNSSEC_RANDOM_H
/*! @} */
......@@ -38,6 +38,7 @@
#include "libknot/updates/ddns.h"
#include "libknot/tsig-op.h"
#include "libknot/rdata.h"
#include "libknot/dnssec/random.h"
#include "libknot/dnssec/zone-nsec.h"
/*----------------------------------------------------------------------------*/
......@@ -4229,7 +4230,7 @@ int knot_ns_create_forward_query(const knot_packet_t *query,
memcpy(query_wire, knot_packet_wireformat(query),
knot_packet_size(query));
*size = knot_packet_size(query);
knot_wire_set_id(query_wire, knot_random_id());
knot_wire_set_id(query_wire, knot_random_uint16_t());
return ret;
}
......
......@@ -21,6 +21,7 @@
#include "libknot/packet/packet.h"
#include "libknot/util/debug.h"
#include "libknot/common.h"
#include "libknot/dnssec/random.h"
#include "common/descriptor.h"
#include "libknot/util/wire.h"
#include "libknot/tsig.h"
......@@ -719,7 +720,7 @@ void knot_packet_set_random_id(knot_packet_t *packet)
return;
}
knot_wire_set_id(packet->wireformat, knot_random_id());
knot_wire_set_id(packet->wireformat, knot_random_uint16_t());
}
/*----------------------------------------------------------------------------*/
......
......@@ -22,7 +22,6 @@
#include "libknot/common.h"
#include "libknot/util/utils.h"
#include "common/prng.h"
/*----------------------------------------------------------------------------*/
......@@ -56,11 +55,6 @@ knot_lookup_table_t *knot_lookup_by_id(knot_lookup_table_t *table,
/*----------------------------------------------------------------------------*/
uint16_t knot_random_id()
{
return (uint16_t)(tls_rand() * ((uint16_t)~0));
}
struct flock* knot_file_lock(short type, short whence)
{
static struct flock ret;
......
......@@ -175,11 +175,6 @@ static inline void knot_wire_write_u64(uint8_t *pos, uint64_t data)
*(uint64_t *)pos = htobe64(data);
}
/*!
* \brief Get random packet id.
*/
uint16_t knot_random_id();
/*!
* \brief Helper function for simple locking.
*
......
......@@ -26,7 +26,7 @@
#include "libknot/packet/query.h"
#include "libknot/nameserver/name-server.h"
#include "common/descriptor.h"
#include "common/prng.h"
#include "libknot/dnssec/random.h"
/* Enable time-dependent tests. */
//#define ENABLE_TIMED_TESTS
......@@ -62,7 +62,7 @@ static void* rrl_runnable(void *arg)
uint32_t now = time(NULL);
struct bucketmap_t *m = malloc(RRL_INSERTS * sizeof(struct bucketmap_t));
for (unsigned i = 0; i < RRL_INSERTS; ++i) {
m[i].i = tls_rand() * UINT32_MAX;
m[i].i = knot_random_uint32_t(UINT32_MAX);
addr.addr4.sin_addr.s_addr = m[i].i;
rrl_item_t *b = rrl_hash(d->rrl, &addr, d->rq, d->zone, now, &lock);
rrl_unlock(d->rrl, lock);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment