Commit Diff
Diff:
324df6f2e0ccca7ea6d010808e22d33e1d825e35
acc152d18389f5317561d07982b8529eca45b74a
Commit:
acc152d18389f5317561d07982b8529eca45b74a
Tree:
41c5d1a082e9c0e1318ebd5cf0479ec7f1bfa35e
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Sun Apr 13 09:45:42 2014 UTC
Message:
* fix linux, it should compile now * change bsd-arc4random.c to a more updated version that doesn't use the unsafe RC4 cipher anymore but a ChaCha cipher developed by D.J.Bernstein (another DNS developer's code in W's code, yay!) * forgot the chacha.h file, will commit that seperately Tested on Linux Raspbian
blob - 7d7db6e18bbe05df62865878621a755659445953
blob + 1b8b85bece208c5b19734c3f3c045149ef4cd6d4
--- Makefile.linux
+++ Makefile.linux
@@ -1,13 +1,14 @@
CC=gcc
#CFLAGS=-DDEBUG
CFLAGS=
-LDADD= -ldb -lssl
+LDADD= -ldb -lssl -lresolv
YACC=bison
build:
$(YACC) $(CFLAGS) -y -d parse.y
+ mv -f y.tab.c parse.c
$(CC) $(CFLAGS) -c additional.c
$(CC) $(CFLAGS) -c main.c
$(CC) $(CFLAGS) -c parse.c
blob - 5dd1824808c3f9d955cf80c8af727fa310fd3901
blob + 6ad67e480929ef37d2c27bb6f9ef3933c81c110b
--- bsd-arc4random.c
+++ bsd-arc4random.c
@@ -1,5 +1,11 @@
+/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random.c */
+
+/* $OpenBSD: arc4random.c,v 1.25 2013/10/01 18:34:57 markus Exp $ */
+
/*
- * Copyright (c) 1999,2000,2004 Damien Miller <djm@mindrot.org>
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,88 +20,206 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
+/*
+ * ChaCha based random number generator for OpenBSD.
+ */
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
+#include "include.h"
+
#ifndef HAVE_ARC4RANDOM
#include <openssl/rand.h>
-#include <openssl/rc4.h>
#include <openssl/err.h>
-/* Size of key to use */
-#define SEED_SIZE 20
+#define KEYSTREAM_ONLY
+#include "chacha_private.h"
-/* Number of bytes to reseed after */
-#define REKEY_BYTES (1 << 24)
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
-static int rc4_ready = 0;
-static RC4_KEY rc4;
+#ifdef __GNUC__
+#define inline __inline
+#else /* !__GNUC__ */
+#define inline
+#endif /* !__GNUC__ */
-void arc4random_stir(void);
-void seed_rng(void);
-void arc4random_buf(void *_buf, size_t n);
-u_int32_t arc4random_uniform(u_int32_t upper_bound);
+/* OpenSSH isn't multithreaded */
+#define _ARC4_LOCK()
+#define _ARC4_UNLOCK()
-/*
- * We may attempt to re-seed during mkstemp if we are using the one in the
- * compat library (via mkstemp -> _gettemp -> arc4random -> seed_rng) so we
- * need our own seed_rng(). We must also check that we have enough entropy.
- */
-void
-seed_rng(void)
+#define KEYSZ 32
+#define IVSZ 8
+#define BLOCKSZ 64
+#define RSBUFSZ (16*BLOCKSZ)
+static int rs_initialized;
+static pid_t rs_stir_pid;
+static chacha_ctx rs; /* chacha context for random keystream */
+static u_char rs_buf[RSBUFSZ]; /* keystream blocks */
+static size_t rs_have; /* valid bytes at end of rs_buf */
+static size_t rs_count; /* bytes till reseed */
+
+static inline void _rs_rekey(u_char *dat, size_t datlen);
+
+extern void slave_shutdown(void);
+
+static inline void
+_rs_init(u_char *buf, size_t n)
{
- RAND_status();
+ if (n < KEYSZ + IVSZ)
+ return;
+ chacha_keysetup(&rs, buf, KEYSZ * 8, 0);
+ chacha_ivsetup(&rs, buf + KEYSZ);
}
+static void
+_rs_stir(void)
+{
+ u_char rnd[KEYSZ + IVSZ];
-unsigned int
-arc4random(void)
+ if (RAND_bytes(rnd, sizeof(rnd)) <= 0) {
+ dolog(LOG_ERR, "Couldn't obtain random bytes (error %ld)",
+ ERR_get_error());
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (!rs_initialized) {
+ rs_initialized = 1;
+ _rs_init(rnd, sizeof(rnd));
+ } else
+ _rs_rekey(rnd, sizeof(rnd));
+ memset(rnd, 0, sizeof(rnd));
+
+ /* invalidate rs_buf */
+ rs_have = 0;
+ memset(rs_buf, 0, RSBUFSZ);
+
+ rs_count = 1600000;
+}
+
+static inline void
+_rs_stir_if_needed(size_t len)
{
- unsigned int r = 0;
- static int first_time = 1;
+ pid_t pid = getpid();
- if (rc4_ready <= 0) {
- if (first_time)
- seed_rng();
- first_time = 0;
- arc4random_stir();
+ if (rs_count <= len || !rs_initialized || rs_stir_pid != pid) {
+ rs_stir_pid = pid;
+ _rs_stir();
+ } else
+ rs_count -= len;
+}
+
+static inline void
+_rs_rekey(u_char *dat, size_t datlen)
+{
+#ifndef KEYSTREAM_ONLY
+ memset(rs_buf, 0,RSBUFSZ);
+#endif
+ /* fill rs_buf with the keystream */
+ chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ);
+ /* mix in optional user provided data */
+ if (dat) {
+ size_t i, m;
+
+ m = MIN(datlen, KEYSZ + IVSZ);
+ for (i = 0; i < m; i++)
+ rs_buf[i] ^= dat[i];
}
+ /* immediately reinit for backtracking resistance */
+ _rs_init(rs_buf, KEYSZ + IVSZ);
+ memset(rs_buf, 0, KEYSZ + IVSZ);
+ rs_have = RSBUFSZ - KEYSZ - IVSZ;
+}
- RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
+static inline void
+_rs_random_buf(void *_buf, size_t n)
+{
+ u_char *buf = (u_char *)_buf;
+ size_t m;
- rc4_ready -= sizeof(r);
-
- return(r);
+ _rs_stir_if_needed(n);
+ while (n > 0) {
+ if (rs_have > 0) {
+ m = MIN(n, rs_have);
+ memcpy(buf, rs_buf + RSBUFSZ - rs_have, m);
+ memset(rs_buf + RSBUFSZ - rs_have, 0, m);
+ buf += m;
+ n -= m;
+ rs_have -= m;
+ }
+ if (rs_have == 0)
+ _rs_rekey(NULL, 0);
+ }
}
+static inline void
+_rs_random_u32(u_int32_t *val)
+{
+ _rs_stir_if_needed(sizeof(*val));
+ if (rs_have < sizeof(*val))
+ _rs_rekey(NULL, 0);
+ memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val));
+ memset(rs_buf + RSBUFSZ - rs_have, 0, sizeof(*val));
+ rs_have -= sizeof(*val);
+ return;
+}
+
void
arc4random_stir(void)
{
- unsigned char rand_buf[SEED_SIZE];
- int i;
+ _ARC4_LOCK();
+ _rs_stir();
+ _ARC4_UNLOCK();
+}
- memset(&rc4, 0, sizeof(rc4));
- RAND_bytes(rand_buf, sizeof(rand_buf));
- RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
+void
+arc4random_addrandom(u_char *dat, int datlen)
+{
+ int m;
- /*
- * Discard early keystream, as per recommendations in:
- * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps
- */
- for(i = 0; i <= 256; i += sizeof(rand_buf))
- RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf);
+ _ARC4_LOCK();
+ if (!rs_initialized)
+ _rs_stir();
+ while (datlen > 0) {
+ m = MIN(datlen, KEYSZ + IVSZ);
+ _rs_rekey(dat, m);
+ dat += m;
+ datlen -= m;
+ }
+ _ARC4_UNLOCK();
+}
- memset(rand_buf, 0, sizeof(rand_buf));
+u_int32_t
+arc4random(void)
+{
+ u_int32_t val;
- rc4_ready = REKEY_BYTES;
+ _ARC4_LOCK();
+ _rs_random_u32(&val);
+ _ARC4_UNLOCK();
+ return val;
}
+
+/*
+ * If we are providing arc4random, then we can provide a more efficient
+ * arc4random_buf().
+ */
+# ifndef HAVE_ARC4RANDOM_BUF
+void
+arc4random_buf(void *buf, size_t n)
+{
+ _ARC4_LOCK();
+ _rs_random_buf(buf, n);
+ _ARC4_UNLOCK();
+}
+# endif /* !HAVE_ARC4RANDOM_BUF */
#endif /* !HAVE_ARC4RANDOM */
-#ifndef HAVE_ARC4RANDOM_BUF
+/* arc4random_buf() that uses platform arc4random() */
+#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM)
void
arc4random_buf(void *_buf, size_t n)
{
@@ -111,7 +235,7 @@ arc4random_buf(void *_buf, size_t n)
}
i = r = 0;
}
-#endif /* !HAVE_ARC4RANDOM_BUF */
+#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */
#ifndef HAVE_ARC4RANDOM_UNIFORM
/*
@@ -132,17 +256,8 @@ arc4random_uniform(u_int32_t upper_bound)
if (upper_bound < 2)
return 0;
-#if (ULONG_MAX > 0xffffffffUL)
- min = 0x100000000UL % upper_bound;
-#else
- /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
- if (upper_bound > 0x80000000)
- min = 1 + ~upper_bound; /* 2**32 - upper_bound */
- else {
- /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
- min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
- }
-#endif
+ /* 2**32 % x == (2**32 - x) % x */
+ min = -upper_bound % upper_bound;
/*
* This could theoretically loop forever but each retry has
repomaster@centroid.eu