summaryrefslogtreecommitdiff
path: root/sys/dev/rnd.c
diff options
context:
space:
mode:
authormortimer <mortimer@cvs.openbsd.org>2018-02-08 09:27:45 +0000
committermortimer <mortimer@cvs.openbsd.org>2018-02-08 09:27:45 +0000
commit8bb6cc188ce3a378bddf100774f013c26a29bb16 (patch)
tree81d966d9e482d27ca0b4a1ee21d7cda4bf11ba55 /sys/dev/rnd.c
parent7b376b4859578f9a85ceb479b00d2d131f62b9c4 (diff)
Use a temporary chacha instance to fill large randomdata sections. Avoids
grabbing the rnglock repeatedly. ok deraadt@ djm@
Diffstat (limited to 'sys/dev/rnd.c')
-rw-r--r--sys/dev/rnd.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c
index 5e44048aa1b..945d947943a 100644
--- a/sys/dev/rnd.c
+++ b/sys/dev/rnd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rnd.c,v 1.195 2017/11/26 17:06:46 mikeb Exp $ */
+/* $OpenBSD: rnd.c,v 1.196 2018/02/08 09:27:44 mortimer Exp $ */
/*
* Copyright (c) 2011 Theo de Raadt.
@@ -652,6 +652,41 @@ arc4random_buf(void *buf, size_t n)
}
/*
+ * Allocate a new ChaCha20 context for the caller to use.
+ */
+struct arc4random_ctx *
+arc4random_ctx_new()
+{
+ char keybuf[KEYSZ + IVSZ];
+
+ chacha_ctx *ctx = malloc(sizeof(chacha_ctx), M_TEMP, M_WAITOK);
+ arc4random_buf(keybuf, KEYSZ + IVSZ);
+ chacha_keysetup(ctx, keybuf, 256);
+ chacha_ivsetup(ctx, keybuf + KEYSZ, NULL);
+ explicit_bzero(keybuf, sizeof(keybuf));
+ return (struct arc4random_ctx *)ctx;
+}
+
+/*
+ * Free a ChaCha20 context created by arc4random_ctx_new()
+ */
+void
+arc4random_ctx_free(struct arc4random_ctx *ctx)
+{
+ explicit_bzero(ctx, sizeof(chacha_ctx));
+ free(ctx, M_TEMP, sizeof(chacha_ctx));
+}
+
+/*
+ * Use a given ChaCha20 context to fill a buffer
+ */
+void
+arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n)
+{
+ chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n);
+}
+
+/*
* Calculate a uniformly distributed random number less than upper_bound
* avoiding "modulo bias".
*