summaryrefslogtreecommitdiff
path: root/sys/dev/random
diff options
context:
space:
mode:
authorMark Murray <markm@FreeBSD.org>2015-07-13 08:38:21 +0000
committerMark Murray <markm@FreeBSD.org>2015-07-13 08:38:21 +0000
commitb712101cf7832ce8d57f6ceedd013836163a9eee (patch)
tree364eecba9cdbd2c2057d302f88e8745f49ac8ee6 /sys/dev/random
parent6f7c45c9d531b7c452583c13487aa0e9c8b251ca (diff)
Notes
Diffstat (limited to 'sys/dev/random')
-rw-r--r--sys/dev/random/randomdev.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c
index a70b3f26e2fe..e27b90957d09 100644
--- a/sys/dev/random/randomdev.c
+++ b/sys/dev/random/randomdev.c
@@ -153,8 +153,8 @@ static int
randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags)
{
uint8_t *random_buf;
- int c, error;
- ssize_t nbytes;
+ int error;
+ ssize_t read_len, total_read, c;
random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK);
random_alg_context.ra_pre_read();
@@ -175,14 +175,24 @@ randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags)
/* XXX: FIX!! Next line as an atomic operation? */
read_rate += (uio->uio_resid + sizeof(uint32_t))/sizeof(uint32_t);
#endif
- nbytes = uio->uio_resid;
+ total_read = 0;
while (uio->uio_resid && !error) {
- c = MIN(uio->uio_resid, PAGE_SIZE);
- /* See the random_buf size requirements in the Yarrow/Fortuna code */
- random_alg_context.ra_read(random_buf, c);
+ read_len = uio->uio_resid;
+ /*
+ * Belt-and-braces.
+ * Round up the read length to a crypto block size multiple,
+ * 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 = 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 (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR) )
+ if (total_read != uio->uio_resid && (error == ERESTART || error == EINTR) )
/* Return partial read, not error. */
error = 0;
}
@@ -212,6 +222,13 @@ read_random(void *random_buf, u_int len)
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);