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;

Reply via email to