Hi tech@,

Ping?

attila <[email protected]> writes:

> Hi tech@,
>
> I've written a driver for the Araneus Alea II USB TRNG:
>     http://www.araneus.fi/products/alea2/en/
>
> It produces 100kbit/sec of entropy, which my driver stuffs into
> add_true_randomness().  A small thing, but maybe valuable in
> situations that do a lot of crypto.  I mainly did it to get my head
> around more of the codebase, and I happened to have one lying around,
> so...  According to the docs the interface has not changed between the
> Alea I and the Alea II so this driver should work for both, but I only
> have a II.  I'm interested in writing drivers for other TRNGs if
> anyone else finds it useful.
>
> Tested under i386 and amd64.
>
> I'm sure I've made many mistakes.  Comments and feedback most welcome.
>
> Pax, -A
>
> diff -Nurp src.orig/sys/arch/amd64/conf/GENERIC 
> src/sys/arch/amd64/conf/GENERIC
> --- src.orig/sys/arch/amd64/conf/GENERIC      Thu Apr  2 08:24:02 2015
> +++ src/sys/arch/amd64/conf/GENERIC   Thu Apr  9 16:02:27 2015
> @@ -271,6 +271,7 @@ uvideo*   at uhub?                # USB Video
>  video*       at uvideo?
>  udl* at uhub?                # DisplayLink USB displays
>  wsdisplay* at udl?
> +ualea*       at uhub?                # Araneus Alea II USB TRNG
>  
>  puc* at pci?                 # PCI "universal" communication device
>  com* at cardbus?
> diff -Nurp src.orig/sys/arch/i386/conf/GENERIC src/sys/arch/i386/conf/GENERIC
> --- src.orig/sys/arch/i386/conf/GENERIC       Thu Apr  2 08:24:02 2015
> +++ src/sys/arch/i386/conf/GENERIC    Thu Apr  9 16:02:01 2015
> @@ -325,6 +325,7 @@ uvideo* at uhub?          # USB video
>  video*  at uvideo?
>  udl* at uhub?                # DisplayLink USB displays
>  wsdisplay* at udl?
> +ualea*       at uhub?                # Araneus Alea II USB TRNG
>  
>  puc* at pci?                 # PCI "universal" communication device
>  com* at cardbus?
> diff -Nurp src.orig/sys/arch/macppc/conf/GENERIC 
> src/sys/arch/macppc/conf/GENERIC
> --- src.orig/sys/arch/macppc/conf/GENERIC     Thu Apr  2 08:24:02 2015
> +++ src/sys/arch/macppc/conf/GENERIC  Thu Apr  9 16:02:43 2015
> @@ -292,6 +292,7 @@ utrh*     at uhidev?              # USBRH sensor
>  utwitch* at uhidev?          # YUREX BBU sensor
>  uow* at uhub?                # Maxim/Dallas DS2490 1-Wire adapter
>  onewire* at uow?
> +ualea*       at uhub?                # Araneus Alea II USB TRNG
>  
>  # USB Video
>  uvideo* at uhub?
> diff -Nurp src.orig/sys/arch/sparc64/conf/GENERIC 
> src/sys/arch/sparc64/conf/GENERIC
> --- src.orig/sys/arch/sparc64/conf/GENERIC    Tue Mar 24 06:00:39 2015
> +++ src/sys/arch/sparc64/conf/GENERIC Thu Apr  9 16:02:58 2015
> @@ -245,6 +245,7 @@ ugold*    at uhidev?              # gold TEMPer sensor
>  utwitch* at uhidev?          # UYUREX BBU sensor
>  uow* at uhub?                # Maxim/Dallas DS2490 1-Wire adapter
>  onewire* at uow?
> +ualea*       at uhub?                # Araneus Alea II USB TRNG
>  
>  # USB Video
>  uvideo* at uhub?
> diff -Nurp src.orig/sys/arch/zaurus/conf/GENERIC 
> src/sys/arch/zaurus/conf/GENERIC
> --- src.orig/sys/arch/zaurus/conf/GENERIC     Sat Jan  3 15:24:19 2015
> +++ src/sys/arch/zaurus/conf/GENERIC  Thu Apr  9 16:03:25 2015
> @@ -135,6 +135,7 @@ umbg*             at uhub?                # Meinberg 
> Funkuhren USB5131
>  uow*         at uhub?                # Maxim/Dallas DS2490 1-Wire adapter
>  onewire*     at uow?
>  utwitch*     at uhidev?              # YUREX BBU sensor
> +ualea*               at uhub?                # Araneus Alea II USB TRNG
>  
>  scsibus*     at scsi?
>  sd*          at scsibus?             # SCSI disk drives
> diff -Nurp src.orig/sys/dev/usb/files.usb src/sys/dev/usb/files.usb
> --- src.orig/sys/dev/usb/files.usb    Thu Apr  2 08:24:02 2015
> +++ src/sys/dev/usb/files.usb Thu Apr  9 16:04:38 2015
> @@ -195,6 +195,11 @@ device   utwitch: hid
>  attach       utwitch at uhidbus
>  file dev/usb/utwitch.c               utwitch
>  
> +# Araneus Alea II TRNG
> +device       ualea
> +attach       ualea at uhub
> +file dev/usb/ualea.c                 ualea
> +
>  # Ethernet adapters
>  # ADMtek AN986 Pegasus
>  device       aue: ether, ifnet, mii, ifmedia
> diff -Nurp src.orig/sys/dev/usb/ualea.c src/sys/dev/usb/ualea.c
> --- src.orig/sys/dev/usb/ualea.c      Wed Dec 31 18:00:00 1969
> +++ src/sys/dev/usb/ualea.c   Fri Apr 10 15:46:30 2015
> @@ -0,0 +1,265 @@
> +/* -*- mode:c; tab-width:8; indent-tabs-mode:t; c-basic-offset:8 -*- */
> +/*
> + * Copyright (C) 2015 by attila <[email protected]>
> + *
> + * Permission to use, copy, modify, and/or 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.
> + */
> +
> +/*
> + * Alea II TRNG.  Produces 100kbit/sec of entropy by black magic
> + *
> + * Product information in English can be found here:
> + *     http://www.araneus.fi/products/alea2/en/
> + *
> + * I only have an Alea II to play with but the documentation says
> + * that the Alea I is the same, so they should also work.
> + *
> + * I cribbed liberally from both the uow and umbg drivers, both of
> + * which are similar to this situation in different ways.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/device.h>
> +#include <sys/kernel.h>
> +#include <sys/time.h>
> +#include <sys/timeout.h>
> +
> +#include <dev/usb/usb.h>
> +#include <dev/usb/usbdevs.h>
> +#include <dev/usb/usbdi.h>
> +#include <dev/usb/usbdi_util.h>
> +
> +#include <dev/rndvar.h>
> +
> +#define ALEA_IFACE   0
> +#define ALEA_MSECS   10
> +#define ALEA_READ_TOUT       1100
> +#define ALEA_BUFSIZ  ((1024/8)*100)  /* 100 kbits */
> +/*#define ALEA_DEBUG 1*/             /* comment out */
> +
> +#define OURNAME(x)   x->sc_dev.dv_xname
> +
> +struct ualea_softc {
> +     struct  device sc_dev;
> +     struct  usbd_device *sc_udev;
> +     struct  usbd_interface *sc_iface;
> +     struct  usbd_pipe *sc_ibulk;
> +     struct  timeout sc_tout;
> +     struct  usb_task sc_task;
> +#ifdef ALEA_DEBUG
> +     struct  timespec sc_tattach;
> +     u_int32_t sc_nbits;
> +#endif
> +};
> +
> +int ualea_match(struct device *, void *, void *);
> +void ualea_attach(struct device *, struct device *, void *);
> +int ualea_detach(struct device *, int);
> +void ualea_task(void *);
> +void ualea_intr(void *);
> +
> +struct cfdriver ualea_cd = {
> +     NULL, "ualea", DV_DULL
> +};
> +
> +const struct cfattach ualea_ca = {
> +     sizeof(struct ualea_softc),
> +     ualea_match,
> +     ualea_attach,
> +     ualea_detach
> +};
> +
> +static const struct usb_devno ualea_devs[] = {
> +     { USB_VENDOR_ARANEUS,   USB_PRODUCT_ARANEUS_ALEA }
> +};
> +
> +int
> +ualea_match(struct device *parent, void *match, void *aux)
> +{
> +     struct usb_attach_arg *uaa = aux;
> +
> +     if (uaa->iface != NULL)
> +             return (UMATCH_NONE);
> +#ifdef ALEA_DEBUG
> +     if (uaa->vendor == USB_VENDOR_ARANEUS)
> +             printf("ualea: vendor 0x%x (%d) (ARANEUS) product 0x%x (%d)\n",
> +                 uaa->vendor, uaa->vendor, uaa->product, uaa->product);
> +#endif
> +     return ((usb_lookup(ualea_devs, uaa->vendor, uaa->product) != NULL) ?
> +         UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
> +}
> +
> +void
> +ualea_attach(struct device *parent, struct device *self, void *aux)
> +{
> +     struct ualea_softc *sc = (struct ualea_softc *)self;
> +     struct usb_attach_arg *uaa = aux;
> +     usb_interface_descriptor_t *id;
> +     usb_endpoint_descriptor_t *ed;
> +     int ep_ibulk = -1;
> +     usbd_status error;
> +     int i;
> +
> +     sc->sc_udev = uaa->device;
> +     error = usbd_set_config_index(sc->sc_udev, 0, 1);
> +     if (error != 0) {
> +             printf("%s: failed to set config: %s\n",
> +                    OURNAME(sc), usbd_errstr(error));
> +     }
> +     error = usbd_device2interface_handle(
> +                 sc->sc_udev, ALEA_IFACE, &sc->sc_iface);
> +     if (error != 0) {
> +             printf("%s: failed to get iface %d: %s\n",
> +                 OURNAME(sc), ALEA_IFACE, usbd_errstr(error));
> +             return;
> +     }
> +     /* Get endpoint (there can be only one) */
> +     id = usbd_get_interface_descriptor(sc->sc_iface);
> +     for (i = 0; i < id->bNumEndpoints; i++) {
> +             ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
> +             if (ed == NULL) {
> +                     printf("%s: failed to get endpoint %d descriptor\n",
> +                         OURNAME(sc), i);
> +                     return;
> +             }
> +
> +#ifdef ALEA_DEBUG
> +             printf("%s: iface#%d endpoint#%d type %d\n",
> +                 OURNAME(sc), i, UE_GET_DIR(ed->bEndpointAddress),
> +                 UE_GET_XFERTYPE(ed->bmAttributes));
> +#endif /* ALEA_DEBUG */
> +
> +             if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
> +                 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
> +                 ep_ibulk == -1) {
> +                     ep_ibulk = ed->bEndpointAddress;
> +#ifdef ALEA_DEBUG
> +                     printf("%s: chosing ibulk endpoint#%d\n",
> +                         OURNAME(sc), ep_ibulk);
> +#else
> +                     break;
> +#endif /* ALEA_DEBUG */
> +             }
> +     }
> +     if (ep_ibulk == -1) {
> +             printf("%s: missing ibulk endpoint - cannot initialize\n",
> +                 OURNAME(sc));
> +             return;
> +     }
> +     /* Open pipe */
> +     error = usbd_open_pipe(sc->sc_iface, ep_ibulk, USBD_EXCLUSIVE_USE,
> +                 &sc->sc_ibulk);
> +     if (error) {
> +             printf("%s: failed to open bulk-in pipe: %s\n",
> +                 OURNAME(sc), usbd_errstr(error));
> +             return;
> +     }
> +     /* Get our task going */
> +     usb_init_task(&sc->sc_task, ualea_task, sc, USB_TASK_TYPE_GENERIC);
> +     timeout_set(&sc->sc_tout, ualea_intr, sc);
> +     timeout_add_msec(&sc->sc_tout, ALEA_MSECS);
> +#ifdef ALEA_DEBUG
> +     nanotime(&sc->sc_tattach);
> +     sc->sc_nbits = 0;
> +#endif /* ALEA_DEBUG */
> +}
> +
> +int
> +ualea_detach(struct device *self, int flags)
> +{
> +     struct ualea_softc *sc = (struct ualea_softc *)self;
> +
> +     if (timeout_initialized(&sc->sc_tout))
> +             timeout_del(&sc->sc_tout);
> +     if (sc->sc_ibulk != NULL) {
> +             usbd_abort_pipe(sc->sc_ibulk);
> +             usbd_close_pipe(sc->sc_ibulk);
> +             sc->sc_ibulk = NULL;
> +     }
> +
> +     return 0;
> +}
> +
> +void
> +ualea_task(void *arg)
> +{
> +     struct ualea_softc *sc = (struct ualea_softc *)arg;
> +     usbd_status error;
> +     u_int32_t n, i;
> +     int *buf;
> +     struct usbd_xfer *xfer;
> +#ifdef ALEA_DEBUG
> +     u_int32_t kbps, dt, nbits;
> +     struct timespec now;
> +#endif /* ALEA_DEBUG */
> +
> +     xfer = usbd_alloc_xfer(sc->sc_udev);
> +     if (xfer == NULL) {
> +             printf("%s: could not alloc xfer\n", OURNAME(sc));
> +             goto bail;
> +     }
> +     /* Is there any chance this buffer is not at least int-aligned? */
> +     buf = usbd_alloc_buffer(xfer, ALEA_BUFSIZ);
> +     usbd_setup_xfer(xfer, sc->sc_ibulk, NULL, (void *)buf,
> +         ALEA_BUFSIZ, USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS,
> +         ALEA_READ_TOUT, NULL);
> +     error = usbd_transfer(xfer);
> +     if (error) {
> +             printf("%s: xfer failed: %s\n", OURNAME(sc),
> +                 usbd_errstr(error));
> +             goto bail;
> +     }
> +     usbd_get_xfer_status(xfer, NULL, NULL, &n, NULL);
> +     if (n < sizeof(int)) {
> +             printf("%s: xfer too short (%u bytes) - dropping\n",
> +                 OURNAME(sc), n);
> +             goto bail;
> +     }
> +#ifdef ALEA_DEBUG
> +     else if (n != ALEA_BUFSIZ)
> +             printf("%s: short read got %u bytes (exp. %u)\n", OURNAME(sc),
> +                 n, ALEA_BUFSIZ);
> +#endif /* ALEA_DEBUG */
> +     n /= sizeof(int);
> +     /*
> +      * A random(|ness) koan:
> +      *   children chug entropy like thirsty rhinos
> +      *     surfing at the mall
> +      *    privacy died in their hands
> +      */
> +     for (i = 0; i < n; i++)
> +             add_true_randomness(buf[i]);
> +#ifdef ALEA_DEBUG
> +     nanotime(&now);
> +     dt = now.tv_sec - sc->sc_tattach.tv_sec;
> +     nbits = n * sizeof(int) * 8;
> +     sc->sc_nbits += nbits;
> +     kbps = dt ? ((sc->sc_nbits / 1024) / dt) : 0;
> +     printf("%s: added %d bits: %dkbit/sec\n", OURNAME(sc), nbits, kbps);
> +#endif /* ALEA_DEBUG */
> +bail:
> +     if (xfer)
> +             usbd_free_xfer(xfer);
> +     timeout_add_msec(&sc->sc_tout, ALEA_MSECS);
> +}
> +
> +void
> +ualea_intr(void *arg)
> +{
> +     struct ualea_softc *sc = arg;
> +
> +     usb_add_task(sc->sc_udev, &sc->sc_task);
> +}

--
[email protected] | http://trac.haqistan.net/~attila
keyid E6CC1EDB | 4D91 1B98 A210 1D71 2A0E  AC29 9677 D0A6 E6CC 1EDB

Reply via email to