Second submission, based on feedback from mpi@ and @deraadt.
* match is now on the device level
* attach now looks for interfaces by index (and verifies it gets
the right ones) since it can no longer iterate over the device array
* added missing failure check
* fixed incorrect failure check
* removed extraneous comments and reduced verbosity
Tested on:
5.8 stable on i386/GENERIC; and
5.9 beta snapshot (27 Dec 2015) on amd64/GENERIC.MP
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.406
diff -u -p -r1.406 GENERIC
--- sys/arch/amd64/conf/GENERIC 31 Dec 2015 13:06:49 -0000 1.406
+++ sys/arch/amd64/conf/GENERIC 7 Jan 2016 04:58:26 -0000
@@ -183,6 +183,7 @@ usb* at ohci?
uhub* at usb? # USB Hubs
uhub* at uhub? # USB Hubs
ualea* at uhub? # Araneus Alea II TRNG
+onerng* at uhub? # Moonbase Otago OneRNG
umodem* at uhub? # USB Modems/Serial
ucom* at umodem?
uvisor* at uhub? # Handspring Visor
Index: sys/arch/i386/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.809
diff -u -p -r1.809 GENERIC
--- sys/arch/i386/conf/GENERIC 3 Jan 2016 05:50:00 -0000 1.809
+++ sys/arch/i386/conf/GENERIC 7 Jan 2016 04:58:34 -0000
@@ -233,6 +233,7 @@ usb* at ohci?
uhub* at usb? # USB Hubs
uhub* at uhub? # USB Hubs
ualea* at uhub? # Araneus Alea II TRNG
+onerng* at uhub? # Moonbase Otago OneRNG
umodem* at uhub? # USB Modems/Serial
ucom* at umodem?
uvisor* at uhub? # Handspring Visor
Index: sys/dev/usb/files.usb
===================================================================
RCS file: /cvs/src/sys/dev/usb/files.usb,v
retrieving revision 1.124
diff -u -p -r1.124 files.usb
--- sys/dev/usb/files.usb 11 May 2015 06:46:22 -0000 1.124
+++ sys/dev/usb/files.usb 7 Jan 2016 04:58:58 -0000
@@ -175,6 +175,11 @@ device ualea
attach ualea at uhub
file dev/usb/ualea.c ualea
+# Moonbase Otago OneRNG TRNG
+device onerng
+attach onerng at uhub
+file dev/usb/onerng.c onerng
+
# Gude Expert mouseCLOCK DCF77 time signal station receiver
device udcf
attach udcf at uhub
Index: sys/dev/usb/onerng.c
===================================================================
RCS file: sys/dev/usb/onerng.c
diff -N sys/dev/usb/onerng.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/usb/onerng.c 7 Jan 2016 04:58:58 -0000
@@ -0,0 +1,470 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (C) 2015 Devin Reade <[email protected]>
+ * Copyright (C) 2015 Sean Levy <[email protected]>
+ * Copyright (c) 2007 Marc Balmer <[email protected]>
+ * Copyright (c) 2006 Alexander Yurchenko <[email protected]>
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Moonbase Otago OneRNG TRNG. Note that the encoded vendor for this
+ * device is OpenMoko as OpenMoko has made its device ranges available
+ * for other open source / open hardware vendors.
+ *
+ * Product information can be found here:
+ * http://onerng.info/onerng
+ *
+ * Based on the ualea(4), uow(4), and umodem(4) source code.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/time.h>
+#include <sys/timeout.h>
+#include <machine/bus.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/usbcdc.h>
+
+#include <dev/rndvar.h>
+
+/*
+ * The OneRNG is documented to provide ~350kbits/s of entropy at
+ * ~7.8 bits/byte, and when used at a lower rate providing close
+ * to 8 bits/byte.
+ *
+ * The current choice of ONERNG_BUFSIZ and ONERNG_MSECS gives us
+ * ~319kbits/s with about 3% system time on slow hardware and 0% st
+ * on fast hardware.
+ */
+#define ONERNG_BUFSIZ 2048
+#define ONERNG_MSECS 50
+
+#define ONERNG_TIMEOUT 1000 /* ms */
+
+/*
+ * On attach, we extract and throw away this number of bytes before
+ * feeding bytes to the kernel. This is a behavior that was in the original
+ * non-OpenBSD source written by the cryptographer who created the OneRNG.
+ * It is unclear whether it is specifically intended to discard power-up
+ * state, or is just general healthy paranoia.
+ */
+#define ONERNG_WASTE_ENTROPY 10240
+
+/*
+ * Define ONERNG_MEASURE_RATE to periodically log rate at which we provide
+ * random data to the kernel.
+ */
+#ifdef ONERNG_MEASURE_RATE
+#define ONERNG_RATE_SECONDS 30
+#endif
+
+/* OneRNG operational modes */
+#define ONERNG_OP_ENABLE "cmdO\n" /* start emitting data */
+#define ONERNG_OP_DISABLE "cmdo\n" /* stop emitting data */
+#define ONERNG_OP_FLUSH_ENTROPY "cmdw\n"
+
+/* permits extracting the firmware in order to check the crypto signature */
+#define ONERNG_OP_EXTRACT_FIRMWARE "cmdX\n"
+
+/*
+ * Noise sources include an avalache circuit and an RF circuit.
+ * There is also a whitener to provide a uniform distribution.
+ * Different combinations are possible.
+ */
+#define ONERNG_AVALANCHE_WHITENER "cmd0\n" /* device default */
+#define ONERNG_AVALANCHE "cmd1\n"
+#define ONERNG_AVALANCHE_RF_WHITENER "cmd2\n"
+#define ONERNG_AVALANCHE_RF "cmd3\n"
+#define ONERNG_SILENT "cmd4\n" /* none; necessary for cmdX */
+#define ONERNG_SILENT2 "cmd5\n"
+#define ONERNG_RF_WHITENER "cmd6\n"
+#define ONERNG_RF "cmd7\n"
+
+
+#define ONERNG_CONFIG_INDEX 0
+#define ONERNG_IFACE_CTRL_INDEX 0
+#define ONERNG_IFACE_DATA_INDEX 1
+
+#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
+
+struct onerng_softc {
+ struct device sc_dev;
+ struct usbd_device *sc_udev;
+
+ int sc_ctl_iface_no; /* control */
+ struct usbd_interface *sc_data_iface; /* data */
+
+ struct usbd_pipe *sc_inpipe;
+ struct usbd_pipe *sc_outpipe;
+
+ struct timeout sc_timeout;
+ struct usb_task sc_task;
+ struct usbd_xfer *sc_xfer;
+ int *sc_buf;
+ int sc_discarded_bytes;
+#ifdef ONERNG_MEASURE_RATE
+ struct timeval sc_start;
+ struct timeval sc_cur;
+ int sc_counted_bytes;
+ u_char sc_timer_running;
+#endif
+ u_char sc_dtr; /* current DTR state */
+ u_char sc_rts; /* current RTS state */
+};
+
+int onerng_match(struct device *, void *, void *);
+void onerng_attach(struct device *, struct device *, void *);
+int onerng_detach(struct device *, int);
+void onerng_task(void *);
+void onerng_timeout(void *);
+int onerng_write(struct onerng_softc *sc, const void *buf, int len);
+int onerng_enable(struct onerng_softc *sc);
+void onerng_freesc(struct onerng_softc *sc);
+usbd_status onerng_set_line_state(struct onerng_softc *sc);
+usbd_status onerng_rts(struct onerng_softc *sc, int onoff);
+
+struct cfdriver onerng_cd = {
+ NULL, "onerng", DV_DULL
+};
+
+const struct cfattach onerng_ca = {
+ sizeof(struct onerng_softc), onerng_match, onerng_attach, onerng_detach
+};
+
+int
+onerng_match(struct device *parent, void *match, void *aux)
+{
+ struct usb_attach_arg *uaa = aux;
+
+ if (uaa->iface != NULL) {
+ return UMATCH_NONE;
+ }
+
+ return uaa->vendor == USB_VENDOR_OPENMOKO2 &&
+ uaa->product == USB_PRODUCT_OPENMOKO2_ONERNG ?
+ UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+}
+
+void
+onerng_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct onerng_softc *sc = (struct onerng_softc *)self;
+ struct usb_attach_arg *uaa = aux;
+ struct usbd_interface *iface = uaa->iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ int ep_ibulk = -1, ep_obulk = -1;
+ usbd_status err;
+ int i;
+
+ sc->sc_udev = uaa->device;
+ sc->sc_dtr = -1;
+ sc->sc_rts = -1;
+
+ usb_init_task(&sc->sc_task, onerng_task, sc, USB_TASK_TYPE_GENERIC);
+
+ err = usbd_set_config_index(sc->sc_udev, ONERNG_CONFIG_INDEX, 1);
+ if (err) {
+ printf("%s: failed to set configuration, err=%s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ goto fail;
+ }
+
+ /* locate the control interface number and the data interface */
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ONERNG_IFACE_CTRL_INDEX, &iface);
+ if (err || iface == NULL) {
+ printf("%s: failed to locate control interface, err=%s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ goto fail;
+ }
+ id = usbd_get_interface_descriptor(iface);
+ if (id != NULL &&
+ id->bInterfaceClass == UICLASS_CDC &&
+ id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL &&
+ id->bInterfaceProtocol == UIPROTO_CDC_AT) {
+ sc->sc_ctl_iface_no = id->bInterfaceNumber;
+ } else {
+ printf("%s: control interface number not found\n",
+ DEVNAME(sc));
+ goto fail;
+ }
+
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ONERNG_IFACE_DATA_INDEX, &sc->sc_data_iface);
+ if (err || sc->sc_data_iface == NULL) {
+ printf("%s: failed to locate data interface, err=%s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ goto fail;
+ }
+
+ /* Find the bulk endpoints */
+ id = usbd_get_interface_descriptor(sc->sc_data_iface);
+ if (id == NULL ||
+ id->bInterfaceClass != UICLASS_CDC_DATA ||
+ id->bInterfaceSubClass != UISUBCLASS_DATA) {
+ printf("%s: no data interface descriptor\n", DEVNAME(sc));
+ goto fail;
+ }
+ for (i = 0; i < id->bNumEndpoints; i++) {
+ ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i);
+ if (ed == NULL) {
+ printf("%s: no endpoint descriptor for %d\n",
+ DEVNAME(sc), i);
+ goto fail;
+ }
+ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
+ (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
+ ep_ibulk = ed->bEndpointAddress;
+ } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
+ (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
+ ep_obulk = ed->bEndpointAddress;
+ }
+ }
+
+ if (ep_ibulk == -1) {
+ printf("%s: Could not find data bulk in\n", DEVNAME(sc));
+ goto fail;
+ }
+ if (ep_obulk == -1) {
+ printf("%s: Could not find data bulk out\n", DEVNAME(sc));
+ goto fail;
+ }
+
+ /* Open pipes */
+ err = usbd_open_pipe(sc->sc_data_iface, ep_ibulk,
+ USBD_EXCLUSIVE_USE, &sc->sc_inpipe);
+ if (err) {
+ printf("%s: failed to open bulk-in pipe: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ goto fail;
+ }
+ err = usbd_open_pipe(sc->sc_data_iface, ep_obulk,
+ USBD_EXCLUSIVE_USE, &sc->sc_outpipe);
+ if (err) {
+ printf("%s: failed to open bulk-out pipe: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ goto fail;
+ }
+
+ /* Allocate xfer/buffer for bulk transfers */
+ sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (sc->sc_xfer == NULL) {
+ printf("%s: could not alloc xfer\n", DEVNAME(sc));
+ goto fail;
+ }
+ sc->sc_buf = usbd_alloc_buffer(sc->sc_xfer, ONERNG_BUFSIZ);
+ if (sc->sc_buf == NULL) {
+ printf("%s: could not alloc %d-byte buffer\n", DEVNAME(sc),
+ ONERNG_BUFSIZ);
+ goto fail;
+ }
+
+ if (onerng_enable(sc) != 0) {
+ /* already logged */
+ goto fail;
+ }
+
+ timeout_set(&sc->sc_timeout, onerng_timeout, sc);
+ usb_add_task(sc->sc_udev, &sc->sc_task);
+ return;
+
+ fail:
+ usbd_deactivate(sc->sc_udev);
+ onerng_freesc(sc);
+}
+
+int
+onerng_enable(struct onerng_softc *sc)
+{
+ int err;
+
+ if ((err = onerng_rts(sc, 0))) {
+ printf("%s: failed to clear RTS: %s\n", DEVNAME(sc),
+ usbd_errstr(err));
+ return (1);
+ }
+
+ err = onerng_write(sc, ONERNG_AVALANCHE_WHITENER,
+ sizeof(ONERNG_AVALANCHE_WHITENER));
+ if (err != 0) {
+ printf("%s: failed to set operating mode\n", DEVNAME(sc));
+ return (1);
+ }
+ err = onerng_write(sc, ONERNG_OP_ENABLE, sizeof(ONERNG_OP_ENABLE));
+ if (err != 0) {
+ printf("%s: failed to enable device\n", DEVNAME(sc));
+ return (1);
+ }
+ return (0);
+}
+
+int
+onerng_write(struct onerng_softc *sc, const void *buf, int len)
+{
+ usbd_status error;
+
+ if (len > ONERNG_BUFSIZ) {
+ printf("%s: write %d bytes, xfer too big\n", DEVNAME(sc), len);
+ return (1);
+ }
+
+ usbd_setup_xfer(sc->sc_xfer, sc->sc_outpipe, sc, (void *)buf, len,
+ USBD_SYNCHRONOUS, ONERNG_TIMEOUT, NULL);
+ error = usbd_transfer(sc->sc_xfer);
+ if (error != 0) {
+ printf("%s: write failed, len %d: %s\n", DEVNAME(sc), len,
+ usbd_errstr(error));
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+onerng_detach(struct device *self, int flags)
+{
+ struct onerng_softc *sc = (struct onerng_softc *)self;
+
+ /*
+ * all of these are safe, including where onerng_attach() didn't
+ * complete
+ */
+ usb_rem_task(sc->sc_udev, &sc->sc_task);
+ if (timeout_initialized(&sc->sc_timeout)) {
+ timeout_del(&sc->sc_timeout);
+ }
+ onerng_freesc(sc);
+ return (0);
+}
+
+void
+onerng_freesc(struct onerng_softc *sc)
+{
+ if (sc->sc_inpipe != NULL) {
+ usbd_close_pipe(sc->sc_inpipe);
+ sc->sc_inpipe = NULL;
+ }
+ if (sc->sc_outpipe != NULL) {
+ usbd_close_pipe(sc->sc_outpipe);
+ sc->sc_outpipe = NULL;
+ }
+
+ /* usbd_free_xfer will also free the buffer if necessary */
+ if (sc->sc_xfer != NULL) {
+ usbd_free_xfer(sc->sc_xfer);
+ sc->sc_xfer = NULL;
+ }
+}
+
+usbd_status
+onerng_rts(struct onerng_softc *sc, int onoff)
+{
+ if (sc->sc_rts == onoff)
+ return USBD_NORMAL_COMPLETION;
+ sc->sc_rts = onoff;
+
+ return onerng_set_line_state(sc);
+}
+
+usbd_status
+onerng_set_line_state(struct onerng_softc *sc)
+{
+ usb_device_request_t req;
+ int ls;
+
+ ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
+ (sc->sc_rts ? UCDC_LINE_RTS : 0);
+ req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
+ req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
+ USETW(req.wValue, ls);
+ USETW(req.wIndex, sc->sc_ctl_iface_no);
+ USETW(req.wLength, 0);
+
+ return usbd_do_request(sc->sc_udev, &req, 0);
+}
+
+void
+onerng_task(void *arg)
+{
+ struct onerng_softc *sc = (struct onerng_softc *) arg;
+ usbd_status error;
+ u_int32_t len, int_count, i;
+#ifdef ONERNG_MEASURE_RATE
+ time_t elapsed;
+ int rate;
+#endif
+
+ usbd_setup_xfer(sc->sc_xfer, sc->sc_inpipe, NULL, sc->sc_buf,
+ ONERNG_BUFSIZ, USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS,
+ ONERNG_TIMEOUT, NULL);
+ error = usbd_transfer(sc->sc_xfer);
+ if (error) {
+ printf("%s: xfer failed: %s\n", DEVNAME(sc),
+ usbd_errstr(error));
+ goto bail;
+ }
+ usbd_get_xfer_status(sc->sc_xfer, NULL, NULL, &len, NULL);
+ if (len < sizeof(int)) {
+ printf("%s: xfer too short (%u bytes) - dropping\n",
+ DEVNAME(sc), len);
+ goto bail;
+ }
+
+#ifdef ONERNG_MEASURE_RATE
+ if (!sc->sc_timer_running) {
+ sc->sc_timer_running = 1;
+ sc->sc_counted_bytes = 0;
+ getmicrotime(&(sc->sc_start));
+ }
+ sc->sc_counted_bytes += len;
+ getmicrotime(&(sc->sc_cur));
+ elapsed = sc->sc_cur.tv_sec - sc->sc_start.tv_sec;
+ if (elapsed >= ONERNG_RATE_SECONDS) {
+ rate = (8 * sc->sc_counted_bytes) / (elapsed * 1024);
+ printf("%s: transfer rate = %d kb/s\n", DEVNAME(sc), rate);
+
+ /* set up for next measurement */
+ sc->sc_counted_bytes = 0;
+ getmicrotime(&(sc->sc_start));
+ }
+#endif
+
+ int_count = len / sizeof(int);
+ for (i = 0; i < int_count; i++) {
+ if (sc->sc_discarded_bytes < ONERNG_WASTE_ENTROPY) {
+ sc->sc_discarded_bytes += sizeof(int);
+ } else {
+ add_true_randomness(sc->sc_buf[i]);
+ }
+ }
+bail:
+ timeout_add_msec(&sc->sc_timeout, ONERNG_MSECS);
+}
+
+void
+onerng_timeout(void *arg)
+{
+ struct onerng_softc *sc = arg;
+
+ usb_add_task(sc->sc_udev, &sc->sc_task);
+}
Index: sys/dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.661
diff -u -p -r1.661 usbdevs
--- sys/dev/usb/usbdevs 27 Nov 2015 10:58:05 -0000 1.661
+++ sys/dev/usb/usbdevs 7 Jan 2016 04:58:58 -0000
@@ -602,6 +602,7 @@ vendor LONGCHEER 0x1c9e Longcheer Techno
vendor DRESDENELEC 0x1cf1 Dresden Elektronic
vendor DREAMLINK 0x1d34 Dream Link
vendor PEGATRON 0x1d4d Pegatron
+vendor OPENMOKO2 0x1d50 OpenMoko
vendor SELUXIT 0x1d6f Seluxit
vendor METAGEEK 0x1dd5 MetaGeek
vendor FESTO 0x1e29 Festo
@@ -3246,6 +3247,12 @@ product OQO WIFI01 0x0002 model 01 WiFi
product OQO BT01 0x0003 model 01 Bluetooth
product OQO ETHER01PLUS 0x7720 model 01+ Ethernet
product OQO ETHER01 0x8150 model 01 Ethernet
+
+/*
+ * OpenMoko permits other open hardware products to use their
+ * product ID allocations
+ */
+product OPENMOKO2 ONERNG 0x6086 Moonbase Otago OneRNG
/* Oregon Scientific */
product OREGONSCI OWL_CM160 0xca05 OWL CM-160
Index: share/man/man4/Makefile
===================================================================
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.610
diff -u -p -r1.610 Makefile
--- share/man/man4/Makefile 31 Dec 2015 13:17:31 -0000 1.610
+++ share/man/man4/Makefile 7 Jan 2016 04:59:04 -0000
@@ -38,7 +38,7 @@ MAN= aac.4 ac97.4 acphy.4 \
mpw.4 msts.4 mtd.4 mtdphy.4 multicast.4 mtio.4 myx.4 \
ne.4 neo.4 nep.4 netintro.4 nfe.4 nge.4 nmea.4 \
nsclpcsio.4 nsgphy.4 nsphy.4 nsphyter.4 null.4 nviic.4 nvt.4 \
- oce.4 ohci.4 options.4 onewire.4 oosiop.4 osiop.4 otus.4 \
+ oce.4 ohci.4 options.4 onerng.4 onewire.4 oosiop.4 osiop.4 otus.4 \
owid.4 owctr.4 owsbm.4 owtemp.4 \
pair.4 pcagpio.4 pcaled.4 pcdisplay.4 pchb.4 pchtemp.4 pci.4 pcib.4 \
pcfadc.4 pcfiic.4 pciide.4 pckbc.4 pckbd.4 pcmcia.4 pcn.4 pcppi.4 \
Index: share/man/man4/onerng.4
===================================================================
RCS file: share/man/man4/onerng.4
diff -N share/man/man4/onerng.4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ share/man/man4/onerng.4 7 Jan 2016 04:59:04 -0000
@@ -0,0 +1,98 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2015 Devin Reade <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: December 29 2015 $
+.Dt ONERNG 4
+.Os
+.Sh NAME
+.Nm onerng
+.Nd Moonbase Otago OneRNG TRNG
+.Sh SYNOPSIS
+.Cd "onerng* at uhub?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the Moonbase Otago OneRNG, a USB true random
+number generator (TRNG).
+.Nm
+reads raw entropy from the OneRNG and uses
+.Xr add_true_randomness 9
+to add it to the system entropy pool.
+.Pp
+The OneRNG hardware is documented as being capable of ~350kbit/sec of
+hardware-generated entropy at ~7.8 bits/byte and providing close to
+8 bits/byte when being sampled at less than full rate. The
+.Nm
+implementation currently limits this to ~319kbit/sec.
+.Sh IMPLEMENTATION NOTES
+The OneRNG is capable of operating in one of several modes, some of
+which are intended for production use and some of which are for testing
+and validating the hardware:
+.Bl -bullet
+.It
+Avalanche noise with whitener
+.It
+Raw avalanche noise
+.It
+Avalanche noise and RF noise with whitener
+.It
+Raw avalanche noise and RF noise
+.It
+RF noise with whitener
+.It
+Raw RF noise
+.It
+No noise
+.El
+.Pp
+.Nm
+operates in the
+.Do
+Avalanche noise with whitener
+.Dc
+mode, which is also the manufacturer
+.Ap s
+default.
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr usb 4 ,
+.Xr add_true_randomness 9
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Ox 5.9 .
+.Sh AUTHORS
+The
+.Nm
+driver was written by
+.An Devin Reade Aq Mt [email protected] .
+.Sh BUGS
+The OneRNG permits downloading the device firmware so that one may check
+the firmware
+.Ap s
+cryptographic signature as provided by the manufacturer. The
+.Nm
+driver does not perform nor support this action. In order to currently
+perform such a validation, it would be necessary to disable
+.Nm
+in the kernel and then download the firmware via the OneRNG
+.Ap s
+emulated
+AT modem command set.
+.Pp
+The rate at which random data is extracted from the OneRNG and the source
+of noise that is used are not configurable, but could be.
Index: share/man/man4/usb.4
===================================================================
RCS file: /cvs/src/share/man/man4/usb.4,v
retrieving revision 1.170
diff -u -p -r1.170 usb.4
--- share/man/man4/usb.4 21 Nov 2015 08:04:20 -0000 1.170
+++ share/man/man4/usb.4 7 Jan 2016 04:59:04 -0000
@@ -276,6 +276,8 @@ YUREX USB twitch/jiggle of knee sensor
.El
.Ss Miscellaneous devices
.Bl -tag -width 12n -offset ind -compact
+.It Xr onerng 4
+Moonbase Otago OneRNG TRNG
.It Xr ualea 4
Araneus Alea II USB TRNG
.It Xr uberry 4