(This is in a different part of the file from Theo's current efforts.)
For large reads from /dev/random, use the arc4random_ctx_*() functions
instead of hand-rolling the same code to set up a temporary ChaCha
instance.
ok?
Index: rnd.c
===================================================================
RCS file: /cvs/src/sys/dev/rnd.c,v
retrieving revision 1.213
diff -u -p -r1.213 rnd.c
--- rnd.c 18 May 2020 15:00:16 -0000 1.213
+++ rnd.c 24 May 2020 15:54:00 -0000
@@ -589,6 +589,9 @@ arc4random_ctx_free(struct arc4random_ct
void
arc4random_ctx_buf(struct arc4random_ctx *ctx, void *buf, size_t n)
{
+#ifndef KEYSTREAM_ONLY
+ memset(buf, 0, n);
+#endif
chacha_encrypt_bytes((chacha_ctx *)ctx, buf, buf, n);
}
@@ -701,8 +704,7 @@ randomclose(dev_t dev, int flag, int mod
int
randomread(dev_t dev, struct uio *uio, int ioflag)
{
- u_char lbuf[KEYSZ+IVSZ];
- chacha_ctx lctx;
+ struct arc4random_ctx *lctx;
size_t total = uio->uio_resid;
u_char *buf;
int myctx = 0, ret = 0;
@@ -712,29 +714,23 @@ randomread(dev_t dev, struct uio *uio, i
buf = malloc(POOLBYTES, M_TEMP, M_WAITOK);
if (total > RND_MAIN_MAX_BYTES) {
- arc4random_buf(lbuf, sizeof(lbuf));
- chacha_keysetup(&lctx, lbuf, KEYSZ * 8);
- chacha_ivsetup(&lctx, lbuf + KEYSZ, NULL);
- explicit_bzero(lbuf, sizeof(lbuf));
+ lctx = arc4random_ctx_new();
myctx = 1;
}
while (ret == 0 && uio->uio_resid > 0) {
size_t n = ulmin(POOLBYTES, uio->uio_resid);
- if (myctx) {
-#ifndef KEYSTREAM_ONLY
- memset(buf, 0, n);
-#endif
- chacha_encrypt_bytes(&lctx, buf, buf, n);
- } else
+ if (myctx)
+ arc4random_ctx_buf(lctx, buf, n);
+ else
arc4random_buf(buf, n);
ret = uiomove(buf, n, uio);
if (ret == 0 && uio->uio_resid > 0)
yield();
}
if (myctx)
- explicit_bzero(&lctx, sizeof(lctx));
+ arc4random_ctx_free(lctx);
explicit_bzero(buf, POOLBYTES);
free(buf, M_TEMP, POOLBYTES);
return ret;
--
Christian "naddy" Weisgerber [email protected]