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;