diff options
| author | Mark Murray <markm@FreeBSD.org> | 2015-07-13 08:38:21 +0000 |
|---|---|---|
| committer | Mark Murray <markm@FreeBSD.org> | 2015-07-13 08:38:21 +0000 |
| commit | b712101cf7832ce8d57f6ceedd013836163a9eee (patch) | |
| tree | 364eecba9cdbd2c2057d302f88e8745f49ac8ee6 /sys/dev/random | |
| parent | 6f7c45c9d531b7c452583c13487aa0e9c8b251ca (diff) | |
Notes
Diffstat (limited to 'sys/dev/random')
| -rw-r--r-- | sys/dev/random/randomdev.c | 31 |
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); |
