Module Name: src
Committed By: riastradh
Date: Mon May 18 16:05:09 UTC 2020
Modified Files:
src/sys/arch/mips/cavium/dev: octeon_rnm.c
Log Message:
Adjust entropy estimate for the Octeon.
We are hedging in serial and in parallel, and more conservative than
the Linux driver from Cavium seems to be, so although I don't know
exactly what the thermal jitter of the device is, this seems like a
reasonable compromise.
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/mips/cavium/dev/octeon_rnm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/cavium/dev/octeon_rnm.c
diff -u src/sys/arch/mips/cavium/dev/octeon_rnm.c:1.5 src/sys/arch/mips/cavium/dev/octeon_rnm.c:1.6
--- src/sys/arch/mips/cavium/dev/octeon_rnm.c:1.5 Wed May 13 21:09:02 2020
+++ src/sys/arch/mips/cavium/dev/octeon_rnm.c Mon May 18 16:05:09 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: octeon_rnm.c,v 1.5 2020/05/13 21:09:02 riastradh Exp $ */
+/* $NetBSD: octeon_rnm.c,v 1.6 2020/05/18 16:05:09 riastradh Exp $ */
/*
* Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -67,27 +67,39 @@
* The first sample of each RO always seems to be zero. Further,
* consecutive samples from a single ring oscillator are not
* independent, so naive debiasing like a von Neumann extractor
- * falls flat on its face.
- *
- * We read out one FIFO's worth of raw samples from all 128 ring
- * oscillators by going through them round-robin, and without a
- * more detailed assessment of the jitter on the physical devices,
- * we assume it takes a couple thousand samples of ring
- * oscillators (one bit per sample) to reach one bit of entropy,
- * so we read out 8 KB to get about 256 bits of entropy.
- *
- * We could use the on-board LFSR/SHA-1 conditioner, but it's not
- * clear how many RO samples go into the conditioner, and our
- * entropy pool is a perfectly good conditioner itself, so it
- * seems there is little advantage -- other than expedience -- to
- * using the LFSR/SHA-1 conditioner.
+ * falls flat on its face. And parallel ring oscillators powered
+ * by the same source may not be independent either, if they end
+ * up locked.
+ *
+ * We read out one FIFO's worth of raw samples from groups of 8
+ * ring oscillators at a time, of 128 total, by going through them
+ * round robin. We take 32 consecutive samples from each ring
+ * oscillator in a group of 8 in parallel before we count one bit
+ * of entropy. To get 256 bits of entropy, we read 4Kbit of data
+ * from each of two 8-RO groups.
+ *
+ * We could use the on-board LFSR/SHA-1 conditioner like the Linux
+ * driver written by Cavium does, but it's not clear how many RO
+ * samples go into the conditioner, and our entropy pool is a
+ * perfectly good conditioner itself, so it seems there is little
+ * advantage -- other than expedience -- to using the LFSR/SHA-1
+ * conditioner. All the manual says is that it samples 125 of the
+ * 128 ROs. But the Cavium SHA-1 CPU instruction is advertised to
+ * have a latency of 100 cycles, so it seems implausible that much
+ * more than one sample from each RO could be squeezed in there.
+ *
+ * The hardware exposes only 64 bits of each SHA-1 hash, and the
+ * Linux driver uses 32 bits of that -- which, if treated as full
+ * entropy, would mean an assessment of 3.9 bits of RO samples to
+ * get 1 bit of entropy, whereas we take 256 bits of RO samples to
+ * get one bit of entropy, so this seems reasonably conservative.
*
* Reference: Cavium Networks OCTEON Plus CN50XX Hardware Reference
* Manual, CN50XX-HM-0.99E PRELIMINARY, July 2008.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: octeon_rnm.c,v 1.5 2020/05/13 21:09:02 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: octeon_rnm.c,v 1.6 2020/05/18 16:05:09 riastradh Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -209,8 +221,7 @@ octeon_rnm_attach(device_t parent, devic
static void
octeon_rnm_rng(size_t nbytes, void *vsc)
{
- /* Assume we need 2048 RO samples to get one bit of entropy. */
- const unsigned BPB = 2048;
+ const unsigned BPB = 256; /* bits of data per bit of entropy */
uint64_t sample[32];
struct octeon_rnm_softc *sc = vsc;
size_t needed = NBBY*nbytes;