From owner-svn-src-all@freebsd.org Mon Jul 13 08:38:22 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3A7D899BCF7; Mon, 13 Jul 2015 08:38:22 +0000 (UTC) (envelope-from markm@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 12BA21CBB; Mon, 13 Jul 2015 08:38:22 +0000 (UTC) (envelope-from markm@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t6D8cLY1076019; Mon, 13 Jul 2015 08:38:21 GMT (envelope-from markm@FreeBSD.org) Received: (from markm@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t6D8cLEZ076018; Mon, 13 Jul 2015 08:38:21 GMT (envelope-from markm@FreeBSD.org) Message-Id: <201507130838.t6D8cLEZ076018@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markm set sender to markm@FreeBSD.org using -f From: Mark Murray Date: Mon, 13 Jul 2015 08:38:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285439 - head/sys/dev/random X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Jul 2015 08:38:22 -0000 Author: markm Date: Mon Jul 13 08:38:21 2015 New Revision: 285439 URL: https://svnweb.freebsd.org/changeset/base/285439 Log: Rework the read routines to keep the PRNG sources happy. These work in units of crypto blocks, so must have adequate space to write. This means needing to be careful about buffers and keeping track of external read request length. 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 Mon Jul 13 05:59:41 2015 (r285438) +++ head/sys/dev/random/randomdev.c Mon Jul 13 08:38:21 2015 (r285439) @@ -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 /* 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);