Optimise the buffer-size calculation. It was possible to get one block too many.
Approved by: so (/dev/random blanket)
This commit is contained in:
parent
8672831bb4
commit
3ed54293a2
@ -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 nonblock)
|
||||
* 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 nonblock)
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user