Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Jul 2015 16:05:23 +0000 (UTC)
From:      Mark Murray <markm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285690 - head/sys/dev/random
Message-ID:  <201507191605.t6JG5NV0038485@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markm
Date: Sun Jul 19 16:05:23 2015
New Revision: 285690
URL: https://svnweb.freebsd.org/changeset/base/285690

Log:
  Optimise the buffer-size calculation. It was possible to get one block too many.
  
  Approved by:	so (/dev/random blanket)

Modified:
  head/sys/dev/random/randomdev.c

Modified: head/sys/dev/random/randomdev.c
==============================================================================
--- head/sys/dev/random/randomdev.c	Sun Jul 19 15:44:51 2015	(r285689)
+++ head/sys/dev/random/randomdev.c	Sun Jul 19 16:05:23 2015	(r285690)
@@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$");
 
 #define	RANDOM_UNIT	0
 
+/* Return the largest number >= x that is a multiple of m */
+#define CEIL_TO_MULTIPLE(x, m) ((((x) + (m) - 1)/(m))*(m))
+
 static d_read_t randomdev_read;
 static d_write_t randomdev_write;
 static d_poll_t randomdev_poll;
@@ -191,15 +194,15 @@ read_random_uio(struct uio *uio, bool no
 			 * which is what the underlying generator is expecting.
 			 * See the random_buf size requirements in the Yarrow/Fortuna code.
 			 */
-			read_len += RANDOM_BLOCKSIZE;
-			read_len -= read_len % RANDOM_BLOCKSIZE;
+			read_len = CEIL_TO_MULTIPLE(read_len, RANDOM_BLOCKSIZE);
+			/* Work in chunks page-sized or less */
 			read_len = MIN(read_len, PAGE_SIZE);
 			random_alg_context.ra_read(random_buf, read_len);
 			c = MIN(uio->uio_resid, read_len);
 			error = uiomove(random_buf, c, uio);
 			total_read += c;
 		}
-		if (total_read != uio->uio_resid && (error == ERESTART || error == EINTR) )
+		if (total_read != uio->uio_resid && (error == ERESTART || error == EINTR))
 			/* Return partial read, not error. */
 			error = 0;
 	}
@@ -217,7 +220,7 @@ read_random_uio(struct uio *uio, bool no
 u_int
 read_random(void *random_buf, u_int len)
 {
-	u_int read_len, total_read, c;
+	u_int read_len;
 	uint8_t local_buf[len + RANDOM_BLOCKSIZE];
 
 	KASSERT(random_buf != NULL, ("No suitable random buffer in %s", __func__));
@@ -228,22 +231,16 @@ read_random(void *random_buf, u_int len)
 		/* XXX: FIX!! Next line as an atomic operation? */
 		read_rate += (len + sizeof(uint32_t))/sizeof(uint32_t);
 #endif
-		read_len = len;
-		/*
-		 * Belt-and-braces.
-		 * Round up the read length to a crypto block size multiple,
-		 * which is what the underlying generator is expecting.
-		 */
-		read_len += RANDOM_BLOCKSIZE;
-		read_len -= read_len % RANDOM_BLOCKSIZE;
-		total_read = 0;
-		while (read_len) {
-			c = MIN(read_len, PAGE_SIZE);
-			random_alg_context.ra_read(&local_buf[total_read], c);
-			read_len -= c;
-			total_read += c;
+		if (len > 0) {
+			/*
+			 * Belt-and-braces.
+			 * Round up the read length to a crypto block size multiple,
+			 * which is what the underlying generator is expecting.
+			 */
+			read_len = CEIL_TO_MULTIPLE(len, RANDOM_BLOCKSIZE);
+			random_alg_context.ra_read(local_buf, read_len);
+			memcpy(random_buf, local_buf, len);
 		}
-		memcpy(random_buf, local_buf, len);
 	} else
 		len = 0;
 	return (len);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507191605.t6JG5NV0038485>