Re: random(4): use arc4random_ctx_buf() for large device reads

2020-05-24 Thread Theo de Raadt
Makes sense to me.


Christian Weisgerber  wrote:

> (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 -  1.213
> +++ rnd.c 24 May 2020 15:54:00 -
> @@ -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  na...@mips.inka.de
> 



Re: random(4): use arc4random_ctx_buf() for large device reads

2020-05-25 Thread Sebastien Marie
On Sun, May 24, 2020 at 09:33:27PM +0200, Christian Weisgerber wrote:
> (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?

ok semarie@

Eventually, I would get ride of myctx, initialize lctx to NULL, and use
(lctx == NULL) to replace (myctx == 0). But feel free to discard my remark.

> 
> 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 -  1.213
> +++ rnd.c 24 May 2020 15:54:00 -
> @@ -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  na...@mips.inka.de
> 

-- 
Sebastien Marie



Re: random(4): use arc4random_ctx_buf() for large device reads

2020-05-25 Thread Christian Weisgerber
Sebastien Marie:

> > 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.
> 
> Eventually, I would get ride of myctx, initialize lctx to NULL, and use
> (lctx == NULL) to replace (myctx == 0).

Right.  Here we go:

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 -  1.213
+++ rnd.c   25 May 2020 14:58:43 -
@@ -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,40 +704,31 @@ 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 = NULL;
size_t  total = uio->uio_resid;
u_char  *buf;
-   int myctx = 0, ret = 0;
+   int ret = 0;
 
if (uio->uio_resid == 0)
return 0;
 
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));
-   myctx = 1;
-   }
+   if (total > RND_MAIN_MAX_BYTES)
+   lctx = arc4random_ctx_new();
 
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 (lctx != NULL)
+   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));
+   if (lctx != NULL)
+   arc4random_ctx_free(lctx);
explicit_bzero(buf, POOLBYTES);
free(buf, M_TEMP, POOLBYTES);
return ret;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: random(4): use arc4random_ctx_buf() for large device reads

2020-05-25 Thread Sebastien Marie
On Mon, May 25, 2020 at 05:27:37PM +0200, Christian Weisgerber wrote:
> Sebastien Marie:
> 
> > > 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.
> > 
> > Eventually, I would get ride of myctx, initialize lctx to NULL, and use
> > (lctx == NULL) to replace (myctx == 0).
> 
> Right.  Here we go:

Thanks. ok semarie@
 
> 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 -  1.213
> +++ rnd.c 25 May 2020 14:58:43 -
> @@ -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,40 +704,31 @@ 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 = NULL;
>   size_t  total = uio->uio_resid;
>   u_char  *buf;
> - int myctx = 0, ret = 0;
> + int ret = 0;
>  
>   if (uio->uio_resid == 0)
>   return 0;
>  
>   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));
> - myctx = 1;
> - }
> + if (total > RND_MAIN_MAX_BYTES)
> + lctx = arc4random_ctx_new();
>  
>   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 (lctx != NULL)
> + 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));
> + if (lctx != NULL)
> + arc4random_ctx_free(lctx);
>   explicit_bzero(buf, POOLBYTES);
>   free(buf, M_TEMP, POOLBYTES);
>   return ret;
> -- 
> Christian "naddy" Weisgerber  na...@mips.inka.de

-- 
Sebastien Marie