This patch adds kernel support for the OneRNG hardware random number
generator, which is similar to ualea(4).  onerng(4) is configured to
deliver ~319kb/s of true randomness.

Since usbdevs.h and usbdevs_data.h are generated files, it's not clear
to me that they are supposed to be part of the patch, but they are
included none the less.

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 4 Jan 2016 17:13:33 -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.808
diff -u -p -r1.808 GENERIC
--- sys/arch/i386/conf/GENERIC  29 Oct 2015 07:47:02 -0000      1.808
+++ sys/arch/i386/conf/GENERIC  4 Jan 2016 17:13:44 -0000
@@ -232,6 +232,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       4 Jan 2016 17:14:14 -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        4 Jan 2016 17:14:14 -0000
@@ -0,0 +1,547 @@
+/*     $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 <dev/usb/usb.h>
+#include <dev/usb/usbdi.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 implementation was timed for different values of
+ * ONERNG_MSECS and ONERNG_BUFSIZ while running on a Thinkpad T42
+ * (Pentium M processor 1.8GHz).  The timing code is enabled by
+ * defining ONERNG_MEASURE_RATE. The results are below:
+ *
+ * ONERNG_BUFSIZ | ONERNG_MSECS | Rate | Approximate
+ *              |              | kb/s  | System Time
+ *     1024            100       159           1.5%
+ *     1024             50       160           1.5%
+ *     2048            100       159           2%
+ *     2048             50       319           3%
+ *     2048             20       289           2.5%
+ *     2048             10       473           4%
+ *     4096            100       289           2.5%
+ *     4096             50       525           5%
+ *     4096             10       459           4%
+ *     4096              5       464           4%
+ *
+ * Some of the above measurements were redone on faster hardware
+ * (Intel Core2 Duo E6850 @3GHz, GENERIC.MP) and achieved the
+ * same rate but with no significant system time (effectively 0%).
+ *
+ * Based on the above (which was working in default mode with
+ * the whitener) it appears that we can pull data at a greater
+ * rate than the theoretical entropy rate.  This is not inconsistent;
+ * it just reflects the behavior of the whitener. We therefore tune
+ * it down to something that gives close to the theoretical entropy
+ * rate.
+ */
+#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 added to
+ * the Linux implementation 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
+
+/*
+ * If ONERNG_MEASURE_RATE is defined, then we measure the rate at which
+ * we're able to provide random data to the kernel.  ONERNG_RATE_SECONDS
+ * is the sampling period at which we print the results.
+ */
+#ifdef ONERNG_MEASURE_RATE
+#define ONERNG_RATE_SECONDS 30
+#endif
+
+/*
+ * OneRNG commands:
+ *   cmdO (cap-oh)     Turn the device on
+ *   cmdo (lower-oh)   Turn the device off
+ *   cmdw              Flush entropy pool
+ *   cmdX              Extract firmware image (the cmd4 opmode should
+ *                      be in effect during this operation)
+ *
+ * OneRNG operation modes:
+ *   cmd0 (zero)       Avalanche noise with whitener (default)
+ *   cmd1              Raw avalanche noise
+ *   cmd2              Avalanche noise and RF noise with whitener
+ *   cmd3              Raw avalanche noise and RF noise
+ *   cmd4              No noise
+ *   cmd5              No noise
+ *   cmd6              RF noise with whitener
+ *   cmd7              Raw RF noise
+ */
+#define OP_RANDOM  "cmd0\n"
+#define OP_ENABLE  "cmdO\n"
+
+#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
+
+struct onerng_softc {
+       struct  device sc_dev;                  /* base device */
+       struct  usbd_device *sc_udev;           /* USB device */
+
+       int                      sc_ctl_iface_no;
+       struct  usbd_interface  *sc_ctl_iface;  /* control interface */
+       struct  usbd_interface  *sc_data_iface; /* data interface */
+
+       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_get_caps(struct usb_attach_arg *, int, 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);
+void onerng_set_line_state(struct onerng_softc *sc);
+void 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
+};
+
+/*
+ * Determine the index of data interface.  Place it into data_iface_idx
+ * (or -1 if it isn't found)
+ */
+void
+onerng_get_caps(struct usb_attach_arg *uaa, int ctl_iface_no,
+    int *data_iface_idx /*, int *cm_cap, int *acm_cap*/)
+{
+       const usb_descriptor_t *desc;
+       const usb_interface_descriptor_t *id;
+       struct usbd_desc_iter iter;
+       int current_iface_no = -1;
+       int data_iface_no = -1;
+       int i;
+
+       *data_iface_idx = -1;
+       usbd_desc_iter_init(uaa->device, &iter);
+       desc = usbd_desc_iter_next(&iter);
+       while (desc) {
+               if (desc->bDescriptorType == UDESC_INTERFACE) {
+                       id = (usb_interface_descriptor_t *)desc;
+                       current_iface_no = id->bInterfaceNumber;
+                       if (current_iface_no != ctl_iface_no &&
+                           id->bInterfaceClass == UICLASS_CDC_DATA &&
+                           id->bInterfaceSubClass == UISUBCLASS_DATA &&
+                           data_iface_no == -1) {
+                               data_iface_no = current_iface_no;
+                       }
+               }
+               desc = usbd_desc_iter_next(&iter);
+       }
+
+       /*
+        * If we got a data interface number, make sure the corresponding
+        * interface exists and is not already claimed.
+        */
+       if (data_iface_no != -1) {
+               for (i = 0; i < uaa->nifaces; i++) {
+                       id = usbd_get_interface_descriptor(uaa->ifaces[i]);
+
+                       if (id == NULL)
+                               continue;
+
+                       if (id->bInterfaceNumber == data_iface_no) {
+                               if (!usbd_iface_claimed(uaa->device, i))
+                                       *data_iface_idx = i;
+                               break;
+                       }
+               }
+       }
+}
+
+
+int
+onerng_match(struct device *parent, void *match, void *aux)
+{
+       struct usb_attach_arg *uaa = aux;
+       usb_interface_descriptor_t *id;
+       int data_iface_idx, ret = UMATCH_NONE;
+
+       if (uaa->iface == NULL) {
+               return (ret);
+       }
+
+       id = usbd_get_interface_descriptor(uaa->iface);
+       if (id == NULL) {
+               return (ret);
+       }
+
+       /* There are two interfaces; only match on the control interface. */
+       if (id->bInterfaceClass == UICLASS_CDC &&
+           id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL &&
+           id->bInterfaceProtocol == UIPROTO_CDC_AT &&
+           uaa->vendor == USB_VENDOR_OPENMOKO2 &&
+           uaa->product == USB_PRODUCT_OPENMOKO2_ONERNG) {
+               ret = UMATCH_VENDOR_PRODUCT;
+       }
+       if (ret == UMATCH_NONE) {
+               return (ret);
+       }
+
+       /* onerng doesn't support devices without a data iface */
+       onerng_get_caps(uaa, id->bInterfaceNumber, &data_iface_idx);
+       if (data_iface_idx == -1) {
+               ret = UMATCH_NONE;
+       }
+
+       return (ret);
+}
+
+/*
+ * Put the OneRNG into the desired operating mode and then enable it.
+ */
+int
+onerng_enable(struct onerng_softc *sc)
+{
+       onerng_rts(sc, 0);
+
+       if (onerng_write(sc, OP_RANDOM, sizeof(OP_RANDOM)) != 0) {
+               printf("%s: failed to set operating mode\n", DEVNAME(sc));
+               return (1);
+       }
+       if (onerng_write(sc, OP_ENABLE, sizeof(OP_ENABLE)) != 0) {
+               printf("%s: failed to enable device\n", DEVNAME(sc));
+               return (1);
+       }
+       return (0);
+}
+
+/*
+ * Write a command to the device.
+ */
+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);
+}
+
+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;
+       usb_interface_descriptor_t *id;
+       usb_endpoint_descriptor_t *ed;
+       int ep_ibulk = -1, ep_obulk = -1;
+       usbd_status err;
+       int data_iface_idx = -1;
+       int i;
+
+       sc->sc_udev = uaa->device;
+       sc->sc_ctl_iface = uaa->iface;
+       sc->sc_dtr = -1;
+       sc->sc_rts = -1;
+
+       usb_init_task(&sc->sc_task, onerng_task, sc, USB_TASK_TYPE_GENERIC);
+
+       /* Get the capabilities. */
+       onerng_get_caps(uaa, id->bInterfaceNumber, &data_iface_idx);
+
+       usbd_claim_iface(sc->sc_udev, data_iface_idx);
+       sc->sc_data_iface = uaa->ifaces[data_iface_idx];
+       id = usbd_get_interface_descriptor(sc->sc_data_iface);
+
+       printf("%s: data interface %d\n", DEVNAME(sc), id->bInterfaceNumber);
+
+       /*
+        * Find the bulk endpoints.
+        * Iterate over all endpoints in the data interface and take note.
+        */
+       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",
+                               sc->sc_dev.dv_xname, 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));
+               return;
+       }
+       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_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;
+       }
+}
+
+void
+onerng_rts(struct onerng_softc *sc, int onoff)
+{
+       if (sc->sc_rts == onoff)
+               return;
+       sc->sc_rts = onoff;
+
+       onerng_set_line_state(sc);
+}
+
+void
+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);
+
+       (void)usbd_do_request(sc->sc_udev, &req, 0);
+
+}
+
+/*
+ * This function gets called periodically to read pending data from the OneRNG
+ */
+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) {
+               if (elapsed < 1) {
+                       elapsed = 1;
+               }
+               rate = (8 * sc->sc_counted_bytes) / (elapsed * 1024);
+               printf("%s: transfer rate = %d kb/s", 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);
+
+                       if (sc->sc_discarded_bytes >= ONERNG_WASTE_ENTROPY) {
+                               printf("%s: discarded %d initial bytes\n",
+                                   DEVNAME(sc), sc->sc_discarded_bytes);
+                       }
+               } 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 4 Jan 2016 17:14:14 -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: sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.673
diff -u -p -r1.673 usbdevs.h
--- sys/dev/usb/usbdevs.h       27 Nov 2015 10:58:28 -0000      1.673
+++ sys/dev/usb/usbdevs.h       4 Jan 2016 17:14:14 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs.h,v 1.673 2015/11/27 10:58:28 mpi Exp $       */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -609,6 +609,7 @@
 #define        USB_VENDOR_DRESDENELEC  0x1cf1          /* Dresden Elektronic */
 #define        USB_VENDOR_DREAMLINK    0x1d34          /* Dream Link */
 #define        USB_VENDOR_PEGATRON     0x1d4d          /* Pegatron */
+#define        USB_VENDOR_OPENMOKO2    0x1d50          /* OpenMoko */
 #define        USB_VENDOR_SELUXIT      0x1d6f          /* Seluxit */
 #define        USB_VENDOR_METAGEEK     0x1dd5          /* MetaGeek */
 #define        USB_VENDOR_FESTO        0x1e29          /* Festo */
@@ -3253,6 +3254,12 @@
 #define        USB_PRODUCT_OQO_BT01    0x0003          /* model 01 Bluetooth */
 #define        USB_PRODUCT_OQO_ETHER01PLUS     0x7720          /* model 01+ 
Ethernet */
 #define        USB_PRODUCT_OQO_ETHER01 0x8150          /* model 01 Ethernet */
+
+/*
+ * OpenMoko permits other open hardware products to use their
+ * product ID allocations
+ */
+#define        USB_PRODUCT_OPENMOKO2_ONERNG    0x6086          /* Moonbase 
Otago OneRNG */
 
 /* Oregon Scientific */
 #define        USB_PRODUCT_OREGONSCI_OWL_CM160 0xca05          /* OWL CM-160 */
Index: sys/dev/usb/usbdevs_data.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v
retrieving revision 1.667
diff -u -p -r1.667 usbdevs_data.h
--- sys/dev/usb/usbdevs_data.h  27 Nov 2015 10:58:28 -0000      1.667
+++ sys/dev/usb/usbdevs_data.h  4 Jan 2016 17:14:14 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdevs_data.h,v 1.667 2015/11/27 10:58:28 mpi Exp $  */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -7910,6 +7910,10 @@ const struct usb_known_product usb_known
            "model 01 Ethernet",
        },
        {
+           USB_VENDOR_OPENMOKO2, USB_PRODUCT_OPENMOKO2_ONERNG,
+           "Moonbase Otago OneRNG",
+       },
+       {
            USB_VENDOR_OREGONSCI, USB_PRODUCT_OREGONSCI_OWL_CM160,
            "OWL CM-160",
        },
@@ -13708,6 +13712,10 @@ const struct usb_known_vendor usb_known_
        {
            USB_VENDOR_PEGATRON,
            "Pegatron",
+       },
+       {
+           USB_VENDOR_OPENMOKO2,
+           "OpenMoko",
        },
        {
            USB_VENDOR_SELUXIT,
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     4 Jan 2016 17:14:22 -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     4 Jan 2016 17:14:22 -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 is not
+configurable, but could be.

Reply via email to