summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/openbsd-compat/bsd-arc4random.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/openbsd-compat/bsd-arc4random.c')
-rw-r--r--crypto/openssh/openbsd-compat/bsd-arc4random.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/crypto/openssh/openbsd-compat/bsd-arc4random.c b/crypto/openssh/openbsd-compat/bsd-arc4random.c
new file mode 100644
index 0000000..d45fb18
--- /dev/null
+++ b/crypto/openssh/openbsd-compat/bsd-arc4random.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1999,2000,2004 Damien Miller <djm@mindrot.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "log.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
+
+/* Number of bytes to reseed after */
+#define REKEY_BYTES (1 << 24)
+
+static int rc4_ready = 0;
+static RC4_KEY rc4;
+
+unsigned int
+arc4random(void)
+{
+ unsigned int r = 0;
+ static int first_time = 1;
+
+ if (rc4_ready <= 0) {
+ if (first_time)
+ seed_rng();
+ first_time = 0;
+ arc4random_stir();
+ }
+
+ RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r);
+
+ rc4_ready -= sizeof(r);
+
+ return(r);
+}
+
+void
+arc4random_stir(void)
+{
+ unsigned char rand_buf[SEED_SIZE];
+ int i;
+
+ memset(&rc4, 0, sizeof(rc4));
+ if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0)
+ fatal("Couldn't obtain random bytes (error %ld)",
+ ERR_get_error());
+ RC4_set_key(&rc4, sizeof(rand_buf), rand_buf);
+
+ /*
+ * 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);
+
+ memset(rand_buf, 0, sizeof(rand_buf));
+
+ rc4_ready = REKEY_BYTES;
+}
+#endif /* !HAVE_ARC4RANDOM */
OpenPOWER on IntegriCloud