Browse Source

added XORSHIFT128+ random number generator

pull/256/head
Logan007 4 years ago
parent
commit
fad7c191f6
  1. 4
      Makefile.in
  2. 3
      edge.c
  3. 3
      edge_utils.c
  4. 5
      example_edge_embed_quick_edge_init.c
  5. 116
      random_numbers.c
  6. 34
      random_numbers.h
  7. 9
      transform_aes.c
  8. 5
      transform_cc20.c
  9. 5
      transform_speck.c
  10. 3
      transform_tf.c
  11. 3
      tuntap_linux.c
  12. 5
      twofish.c

4
Makefile.in

@ -7,7 +7,7 @@ GIT_COMMITS=@GIT_COMMITS@
CC?=gcc
DEBUG?=-g3
OPTIMIZATION?=-O3 #-march=native
OPTIMIZATION?=-O3 -march=native
WARN?=-Wall
#Ultrasparc64 users experiencing SIGBUS should try the following gcc options
@ -51,7 +51,7 @@ N2N_LIB=libn2n.a
N2N_OBJS=n2n.o wire.o minilzo.o twofish.o speck.o \
edge_utils.o sn_utils.o \
transform_null.o transform_tf.o transform_aes.o transform_cc20.o transform_speck.o \
tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o \
tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o random_numbers.o \
tuntap_osx.o
LIBS_EDGE+=$(LIBS_EDGE_OPT)
LIBS_SN=

3
edge.c

@ -17,6 +17,7 @@
*/
#include "n2n.h"
#include "random_numbers.h"
#ifdef WIN32
#include <sys/stat.h>
#else
@ -871,7 +872,7 @@ int main(int argc, char* argv[]) {
traceEvent(TRACE_NORMAL, "Using %s cipher.", transop_str(conf.transop_id));
/* Random seed */
srand(time(NULL));
n2n_srand (n2n_seed());
if(0 == strcmp("dhcp", ec.ip_mode)) {
traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled.");

3
edge_utils.c

@ -18,6 +18,7 @@
#include "n2n.h"
#include "lzoconf.h"
#include "random_numbers.h"
#ifdef HAVE_LIBZSTD
#include <zstd.h>
@ -759,7 +760,7 @@ static void send_register_super(n2n_edge_t * eee,
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
for(idx=0; idx < N2N_COOKIE_SIZE; ++idx)
eee->last_cookie[idx] = rand() % 0xff;
eee->last_cookie[idx] = n2n_rand() % 0xff;
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
reg.auth.scheme=0; /* No auth yet */

5
example_edge_embed_quick_edge_init.c

@ -17,6 +17,7 @@
*/
#include "n2n.h"
#include "random_numbers.h"
/*
This tool demonstrates how to easily embed
@ -36,7 +37,7 @@ int main(int argc, char* argv[]) {
setTraceLevel(10);
/* Random seed */
srand(time(NULL));
n2n_srand (n2n_seed());
/*
NOTE
@ -51,4 +52,4 @@ int main(int argc, char* argv[]) {
my_ipv4_addr,
supernode,
&keep_on_running));
}
}

116
random_numbers.c

@ -0,0 +1,116 @@
/* The following code offers an alterate pseudo random number generator
namely XORSHIFT128+ to use instead of C's rand(). Its performance is
on par with C's rand().
*/
#include "random_numbers.h"
/* The state must be seeded in a way that it is not all zero, choose some
arbitrary defaults (in this case: taken from splitmix64) */
static struct rn_generator_state_t rn_current_state = {
.a = 0x9E3779B97F4A7C15,
.b = 0xBF58476D1CE4E5B9 };
/* used for mixing the initializing seed */
static uint64_t splitmix64 (struct splitmix64_state_t *state) {
uint64_t result = state->s;
state->s = result + 0x9E3779B97F4A7C15;
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
return result ^ (result >> 31);
}
int n2n_srand (uint64_t seed) {
struct splitmix64_state_t smstate = {seed};
rn_current_state.a = 0;
rn_current_state.b = 0;
rn_current_state.a = splitmix64 (&smstate);
rn_current_state.b = splitmix64 (&smstate);
/* the following lines could be deleted as soon as it is formally prooved that
there is no seed leading to (a == b == 0). Until then, just to be safe: */
if ( (rn_current_state.a == 0) && (rn_current_state.b == 0) ) {
rn_current_state.a = 0x9E3779B97F4A7C15;
rn_current_state.b = 0xBF58476D1CE4E5B9;
}
/* stabilize in unlikely case of weak state with only a few bits set */
for (uint8_t i = 0; i < 32; i++)
n2n_rand();
return 0;
}
/* The following code of xorshift128p was taken from
https://en.wikipedia.org/wiki/Xorshift as of July, 2019
and thus is considered public domain. */
uint64_t n2n_rand () {
uint64_t t = rn_current_state.a;
uint64_t const s = rn_current_state.b;
rn_current_state.a = s;
t ^= t << 23;
t ^= t >> 17;
t ^= s ^ (s >> 26);
rn_current_state.b = t;
return t + s;
}
/* The following code tries to gather some entropy from several sources
for use as seed. Note, that this code does not set the random generator
state yet, a call to n2n_srand ( n2n_seed() ) would do. */
uint64_t n2n_seed (void) {
uint64_t seed = 0;
uint64_t ret = 0;
#ifdef SYS_getrandom
syscall (SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK);
ret += seed;
#endif
// __RDRND__ is set only if architecturual feature is set, e.g. compile with -march=native
#ifdef __RDRND__
_rdrand64_step ((unsigned long long*)&seed);
ret += seed;
#endif
// __RDSEED__ ist set only if architecturual feature is set, e.g. compile with -march=native
#ifdef __RDSEED__
_rdseed64_step((unsigned long long*)&seed);
ret += seed;
#endif
/* The WIN32 code is still untested and thus commented
#ifdef WIN32
HCRYPTPROV crypto_provider;
CryptAcquireContext (&crypto_provider, NULL, (LPCWSTR)L"Microsoft Base Cryptographic Provider v1.0",
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptGenRandom (crypto_provider, 8, &seed);
CryptReleaseContext (crypto_provider, 0);
ret += seed;
#endif */
seed = time(NULL); /* UTC in seconds */
ret += seed;
seed = clock() * 8996146197; /* clock() = ticks since program start */
ret += seed;
return ret;
}

34
random_numbers.h

@ -0,0 +1,34 @@
#include <stdint.h>
#include <time.h>
#if defined (__linux__)
#include <sys/syscall.h>
#include <unistd.h>
#define GRND_NONBLOCK 1
#endif
#if defined (__RDRND__) || defined (__RDSEED__)
#include <immintrin.h>
#endif
/* The WIN32 code is still untested and thus commented
#if defined (WIN32)
#include <Wincrypt.h>
#endif */
struct rn_generator_state_t {
uint64_t a, b;
};
struct splitmix64_state_t {
uint64_t s;
};
int n2n_srand (uint64_t seed);
uint64_t n2n_rand ();
uint64_t n2n_seed ();

9
transform_aes.c

@ -18,6 +18,7 @@
#include "n2n.h"
#include "n2n_transforms.h"
#include "random_numbers.h"
#ifdef N2N_HAVE_AES
@ -169,17 +170,17 @@ static int transop_encode_aes(n2n_trans_op_t * arg,
/* Encode the aes format version. */
encode_uint8(outbuf, &idx, N2N_AES_TRANSFORM_VERSION);
/* Generate and encode the IV seed using as many calls to rand() as neccessary.
/* Generate and encode the IV seed using as many calls to n2n_rand() as neccessary.
* Note: ( N2N_AES_IV_SEED_SIZE % sizeof(rand_value) ) not neccessarily equals 0. */
uint32_t rand_value;
uint64_t rand_value;
int8_t i;
for (i = TRANSOP_AES_IV_SEED_SIZE; i >= sizeof(rand_value); i -= sizeof(rand_value)) {
rand_value = rand(); // CONCERN: rand() is not consideren cryptographicly secure, REPLACE later
rand_value = n2n_rand();
memcpy(iv_seed + TRANSOP_AES_IV_SEED_SIZE - i, &rand_value, sizeof(rand_value));
}
/* Are there bytes left to fill? */
if (i != 0) {
rand_value = rand(); // CONCERN: rand() is not consideren cryptographicly secure, REPLACE later
rand_value = n2n_rand();
memcpy(iv_seed, &rand_value, i);
}
encode_buf(outbuf, &idx, iv_seed, TRANSOP_AES_IV_SEED_SIZE);

5
transform_cc20.c

@ -18,6 +18,7 @@
#include "n2n.h"
#include "n2n_transforms.h"
#include "random_numbers.h"
#ifdef HAVE_OPENSSL_1_1
@ -79,9 +80,9 @@ static char *openssl_err_as_string (void) {
static void set_cc20_iv(transop_cc20_t *priv, n2n_cc20_ivec_t ivec) {
// keep in mind the following condition: N2N_CC20_IVEC_SIZE % sizeof(rand_value) == 0 !
uint32_t rand_value;
uint64_t rand_value;
for (uint8_t i = 0; i < N2N_CC20_IVEC_SIZE; i += sizeof(rand_value)) {
rand_value = rand(); // CONCERN: rand() is not consideren cryptographicly secure, REPLACE later
rand_value = n2n_rand();
memcpy(ivec + i, &rand_value, sizeof(rand_value));
}
}

5
transform_speck.c

@ -19,6 +19,7 @@
#include "n2n.h"
#include "n2n_transforms.h"
#include "speck.h"
#include "random_numbers.h"
#define N2N_SPECK_TRANSFORM_VERSION 1 /* version of the transform encoding */
#define N2N_SPECK_IVEC_SIZE 16
@ -53,11 +54,11 @@ static int transop_deinit_speck(n2n_trans_op_t *arg) {
static void set_speck_iv(transop_speck_t *priv, n2n_speck_ivec_t ivec) {
// keep in mind the following condition: N2N_SPECK_IVEC_SIZE % sizeof(rand_value) == 0 !
uint32_t rand_value;
uint64_t rand_value;
uint8_t i;
for (i = 0; i < N2N_SPECK_IVEC_SIZE; i += sizeof(rand_value)) {
rand_value = rand(); // CONCERN: rand() is not considered cryptographicly secure, REPLACE later
rand_value = n2n_rand();
memcpy(ivec + i, &rand_value, sizeof(rand_value));
}
}

3
transform_tf.c

@ -19,6 +19,7 @@
#include "n2n.h"
#include "n2n_transforms.h"
#include "twofish.h"
#include "random_numbers.h"
#ifndef _MSC_VER
/* Not included in Visual Studio 2008 */
#include <strings.h> /* index() */
@ -89,7 +90,7 @@ static int transop_encode_twofish( n2n_trans_op_t * arg,
* written in first followed by the packet payload. The whole
* contents of assembly are encrypted. */
pnonce = (uint32_t *)assembly;
*pnonce = rand();
*pnonce = n2n_rand();
memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len );
/* Encrypt the assembly contents and write the ciphertext after the SA. */

3
tuntap_linux.c

@ -25,6 +25,7 @@
#include <linux/if_tun.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include "random_numbers.h"
/* ********************************** */
@ -152,7 +153,7 @@ int tuntap_open(tuntap_dev *device,
int i;
for(i = 0; i < 6; i++)
device->mac_addr[i] = rand();
device->mac_addr[i] = n2n_rand();
device->mac_addr[0] &= ~0x01; /* Clear multicast bit */
device->mac_addr[0] |= 0x02; /* Set locally-assigned bit */

5
twofish.c

@ -41,6 +41,7 @@
#include <ctype.h>
#include <sys/types.h>
#include "twofish.h"
#include "random_numbers.h"
/* Fixed 8x8 permutation S-boxes */
static const uint8_t TwoFish_P[2][256] =
@ -403,7 +404,7 @@ uint32_t TwoFishEncrypt(uint8_t *in,
*out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */
if(*out!=NULL)
{ tfdata->output=*out; /* set output buffer. */
tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */
tfdata->header.salt=n2n_rand()*65536+n2n_rand(); /* toss in some salt. */
tfdata->header.length[0]= (uint8_t)(ilen);
tfdata->header.length[1]= (uint8_t)(ilen>>8);
tfdata->header.length[2]= (uint8_t)(ilen>>16);
@ -980,7 +981,7 @@ int main(int argc, char* argv[])
for ( i=0; i<TEST_DATA_SIZE; ++i )
{
in[i] = rand() & 0xff;
in[i] = n2n_rand() & 0xff;
}
outp=outbuf;

Loading…
Cancel
Save