linux/drivers/usb/misc/chaoskey.c
<<
>>
Prefs
   1/*
   2 * chaoskey - driver for ChaosKey device from Altus Metrum.
   3 *
   4 * This device provides true random numbers using a noise source based
   5 * on a reverse-biased p-n junction in avalanche breakdown. More
   6 * details can be found at http://chaoskey.org
   7 *
   8 * The driver connects to the kernel hardware RNG interface to provide
   9 * entropy for /dev/random and other kernel activities. It also offers
  10 * a separate /dev/ entry to allow for direct access to the random
  11 * bit stream.
  12 *
  13 * Copyright © 2015 Keith Packard <keithp@keithp.com>
  14 *
  15 * This program is free software; you can redistribute it and/or modify
  16 * it under the terms of the GNU General Public License as published by
  17 * the Free Software Foundation; version 2 of the License.
  18 *
  19 * This program is distributed in the hope that it will be useful, but
  20 * WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  22 * General Public License for more details.
  23 */
  24
  25#include <linux/module.h>
  26#include <linux/slab.h>
  27#include <linux/usb.h>
  28#include <linux/wait.h>
  29#include <linux/hw_random.h>
  30#include <linux/mutex.h>
  31#include <linux/uaccess.h>
  32
  33static struct usb_driver chaoskey_driver;
  34static struct usb_class_driver chaoskey_class;
  35static int chaoskey_rng_read(struct hwrng *rng, void *data,
  36                             size_t max, bool wait);
  37
  38#define usb_dbg(usb_if, format, arg...) \
  39        dev_dbg(&(usb_if)->dev, format, ## arg)
  40
  41#define usb_err(usb_if, format, arg...) \
  42        dev_err(&(usb_if)->dev, format, ## arg)
  43
  44/* Version Information */
  45#define DRIVER_VERSION  "v0.1"
  46#define DRIVER_AUTHOR   "Keith Packard, keithp@keithp.com"
  47#define DRIVER_DESC     "Altus Metrum ChaosKey driver"
  48#define DRIVER_SHORT    "chaoskey"
  49
  50MODULE_VERSION(DRIVER_VERSION);
  51MODULE_AUTHOR(DRIVER_AUTHOR);
  52MODULE_DESCRIPTION(DRIVER_DESC);
  53MODULE_LICENSE("GPL");
  54
  55#define CHAOSKEY_VENDOR_ID      0x1d50  /* OpenMoko */
  56#define CHAOSKEY_PRODUCT_ID     0x60c6  /* ChaosKey */
  57
  58#define CHAOSKEY_BUF_LEN        64      /* max size of USB full speed packet */
  59
  60#define NAK_TIMEOUT (HZ)                /* stall/wait timeout for device */
  61
  62#ifdef CONFIG_USB_DYNAMIC_MINORS
  63#define USB_CHAOSKEY_MINOR_BASE 0
  64#else
  65
  66/* IOWARRIOR_MINOR_BASE + 16, not official yet */
  67#define USB_CHAOSKEY_MINOR_BASE 224
  68#endif
  69
  70static const struct usb_device_id chaoskey_table[] = {
  71        { USB_DEVICE(CHAOSKEY_VENDOR_ID, CHAOSKEY_PRODUCT_ID) },
  72        { },
  73};
  74MODULE_DEVICE_TABLE(usb, chaoskey_table);
  75
  76/* Driver-local specific stuff */
  77struct chaoskey {
  78        struct usb_interface *interface;
  79        char in_ep;
  80        struct mutex lock;
  81        struct mutex rng_lock;
  82        int open;                       /* open count */
  83        int present;                    /* device not disconnected */
  84        int size;                       /* size of buf */
  85        int valid;                      /* bytes of buf read */
  86        int used;                       /* bytes of buf consumed */
  87        char *name;                     /* product + serial */
  88        struct hwrng hwrng;             /* Embedded struct for hwrng */
  89        int hwrng_registered;           /* registered with hwrng API */
  90        wait_queue_head_t wait_q;       /* for timeouts */
  91        char *buf;
  92};
  93
  94static void chaoskey_free(struct chaoskey *dev)
  95{
  96        usb_dbg(dev->interface, "free");
  97        kfree(dev->name);
  98        kfree(dev->buf);
  99        kfree(dev);
 100}
 101
 102static int chaoskey_probe(struct usb_interface *interface,
 103                          const struct usb_device_id *id)
 104{
 105        struct usb_device *udev = interface_to_usbdev(interface);
 106        struct usb_host_interface *altsetting = interface->cur_altsetting;
 107        int i;
 108        int in_ep = -1;
 109        struct chaoskey *dev;
 110        int result;
 111        int size;
 112
 113        usb_dbg(interface, "probe %s-%s", udev->product, udev->serial);
 114
 115        /* Find the first bulk IN endpoint and its packet size */
 116        for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
 117                if (usb_endpoint_is_bulk_in(&altsetting->endpoint[i].desc)) {
 118                        in_ep = usb_endpoint_num(&altsetting->endpoint[i].desc);
 119                        size = usb_endpoint_maxp(&altsetting->endpoint[i].desc);
 120                        break;
 121                }
 122        }
 123
 124        /* Validate endpoint and size */
 125        if (in_ep == -1) {
 126                usb_dbg(interface, "no IN endpoint found");
 127                return -ENODEV;
 128        }
 129        if (size <= 0) {
 130                usb_dbg(interface, "invalid size (%d)", size);
 131                return -ENODEV;
 132        }
 133
 134        if (size > CHAOSKEY_BUF_LEN) {
 135                usb_dbg(interface, "size reduced from %d to %d\n",
 136                        size, CHAOSKEY_BUF_LEN);
 137                size = CHAOSKEY_BUF_LEN;
 138        }
 139
 140        /* Looks good, allocate and initialize */
 141
 142        dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL);
 143
 144        if (dev == NULL)
 145                return -ENOMEM;
 146
 147        dev->buf = kmalloc(size, GFP_KERNEL);
 148
 149        if (dev->buf == NULL) {
 150                kfree(dev);
 151                return -ENOMEM;
 152        }
 153
 154        /* Construct a name using the product and serial values. Each
 155         * device needs a unique name for the hwrng code
 156         */
 157
 158        if (udev->product && udev->serial) {
 159                dev->name = kmalloc(strlen(udev->product) + 1 +
 160                                    strlen(udev->serial) + 1, GFP_KERNEL);
 161                if (dev->name == NULL) {
 162                        kfree(dev->buf);
 163                        kfree(dev);
 164                        return -ENOMEM;
 165                }
 166
 167                strcpy(dev->name, udev->product);
 168                strcat(dev->name, "-");
 169                strcat(dev->name, udev->serial);
 170        }
 171
 172        dev->interface = interface;
 173
 174        dev->in_ep = in_ep;
 175
 176        dev->size = size;
 177        dev->present = 1;
 178
 179        init_waitqueue_head(&dev->wait_q);
 180
 181        mutex_init(&dev->lock);
 182        mutex_init(&dev->rng_lock);
 183
 184        usb_set_intfdata(interface, dev);
 185
 186        result = usb_register_dev(interface, &chaoskey_class);
 187        if (result) {
 188                usb_err(interface, "Unable to allocate minor number.");
 189                usb_set_intfdata(interface, NULL);
 190                chaoskey_free(dev);
 191                return result;
 192        }
 193
 194        dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
 195        dev->hwrng.read = chaoskey_rng_read;
 196
 197        /* Set the 'quality' metric.  Quality is measured in units of
 198         * 1/1024's of a bit ("mills"). This should be set to 1024,
 199         * but there is a bug in the hwrng core which masks it with
 200         * 1023.
 201         *
 202         * The patch that has been merged to the crypto development
 203         * tree for that bug limits the value to 1024 at most, so by
 204         * setting this to 1024 + 1023, we get 1023 before the fix is
 205         * merged and 1024 afterwards. We'll patch this driver once
 206         * both bits of code are in the same tree.
 207         */
 208        dev->hwrng.quality = 1024 + 1023;
 209
 210        dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0);
 211        if (!dev->hwrng_registered)
 212                usb_err(interface, "Unable to register with hwrng");
 213
 214        usb_enable_autosuspend(udev);
 215
 216        usb_dbg(interface, "chaoskey probe success, size %d", dev->size);
 217        return 0;
 218}
 219
 220static void chaoskey_disconnect(struct usb_interface *interface)
 221{
 222        struct chaoskey *dev;
 223
 224        usb_dbg(interface, "disconnect");
 225        dev = usb_get_intfdata(interface);
 226        if (!dev) {
 227                usb_dbg(interface, "disconnect failed - no dev");
 228                return;
 229        }
 230
 231        if (dev->hwrng_registered)
 232                hwrng_unregister(&dev->hwrng);
 233
 234        usb_deregister_dev(interface, &chaoskey_class);
 235
 236        usb_set_intfdata(interface, NULL);
 237        mutex_lock(&dev->lock);
 238
 239        dev->present = 0;
 240
 241        if (!dev->open) {
 242                mutex_unlock(&dev->lock);
 243                chaoskey_free(dev);
 244        } else
 245                mutex_unlock(&dev->lock);
 246
 247        usb_dbg(interface, "disconnect done");
 248}
 249
 250static int chaoskey_open(struct inode *inode, struct file *file)
 251{
 252        struct chaoskey *dev;
 253        struct usb_interface *interface;
 254
 255        /* get the interface from minor number and driver information */
 256        interface = usb_find_interface(&chaoskey_driver, iminor(inode));
 257        if (!interface)
 258                return -ENODEV;
 259
 260        usb_dbg(interface, "open");
 261
 262        dev = usb_get_intfdata(interface);
 263        if (!dev) {
 264                usb_dbg(interface, "open (dev)");
 265                return -ENODEV;
 266        }
 267
 268        file->private_data = dev;
 269        mutex_lock(&dev->lock);
 270        ++dev->open;
 271        mutex_unlock(&dev->lock);
 272
 273        usb_dbg(interface, "open success");
 274        return 0;
 275}
 276
 277static int chaoskey_release(struct inode *inode, struct file *file)
 278{
 279        struct chaoskey *dev = file->private_data;
 280        struct usb_interface *interface;
 281
 282        if (dev == NULL)
 283                return -ENODEV;
 284
 285        interface = dev->interface;
 286
 287        usb_dbg(interface, "release");
 288
 289        mutex_lock(&dev->lock);
 290
 291        usb_dbg(interface, "open count at release is %d", dev->open);
 292
 293        if (dev->open <= 0) {
 294                usb_dbg(interface, "invalid open count (%d)", dev->open);
 295                mutex_unlock(&dev->lock);
 296                return -ENODEV;
 297        }
 298
 299        --dev->open;
 300
 301        if (!dev->present) {
 302                if (dev->open == 0) {
 303                        mutex_unlock(&dev->lock);
 304                        chaoskey_free(dev);
 305                } else
 306                        mutex_unlock(&dev->lock);
 307        } else
 308                mutex_unlock(&dev->lock);
 309
 310        usb_dbg(interface, "release success");
 311        return 0;
 312}
 313
 314/* Fill the buffer. Called with dev->lock held
 315 */
 316static int _chaoskey_fill(struct chaoskey *dev)
 317{
 318        DEFINE_WAIT(wait);
 319        int result;
 320        int this_read;
 321        struct usb_device *udev = interface_to_usbdev(dev->interface);
 322
 323        usb_dbg(dev->interface, "fill");
 324
 325        /* Return immediately if someone called before the buffer was
 326         * empty */
 327        if (dev->valid != dev->used) {
 328                usb_dbg(dev->interface, "not empty yet (valid %d used %d)",
 329                        dev->valid, dev->used);
 330                return 0;
 331        }
 332
 333        /* Bail if the device has been removed */
 334        if (!dev->present) {
 335                usb_dbg(dev->interface, "device not present");
 336                return -ENODEV;
 337        }
 338
 339        /* Make sure the device is awake */
 340        result = usb_autopm_get_interface(dev->interface);
 341        if (result) {
 342                usb_dbg(dev->interface, "wakeup failed (result %d)", result);
 343                return result;
 344        }
 345
 346        result = usb_bulk_msg(udev,
 347                              usb_rcvbulkpipe(udev, dev->in_ep),
 348                              dev->buf, dev->size, &this_read,
 349                              NAK_TIMEOUT);
 350
 351        /* Let the device go back to sleep eventually */
 352        usb_autopm_put_interface(dev->interface);
 353
 354        if (result == 0) {
 355                dev->valid = this_read;
 356                dev->used = 0;
 357        }
 358
 359        usb_dbg(dev->interface, "bulk_msg result %d this_read %d",
 360                result, this_read);
 361
 362        return result;
 363}
 364
 365static ssize_t chaoskey_read(struct file *file,
 366                             char __user *buffer,
 367                             size_t count,
 368                             loff_t *ppos)
 369{
 370        struct chaoskey *dev;
 371        ssize_t read_count = 0;
 372        int this_time;
 373        int result = 0;
 374        unsigned long remain;
 375
 376        dev = file->private_data;
 377
 378        if (dev == NULL || !dev->present)
 379                return -ENODEV;
 380
 381        usb_dbg(dev->interface, "read %zu", count);
 382
 383        while (count > 0) {
 384
 385                /* Grab the rng_lock briefly to ensure that the hwrng interface
 386                 * gets priority over other user access
 387                 */
 388                result = mutex_lock_interruptible(&dev->rng_lock);
 389                if (result)
 390                        goto bail;
 391                mutex_unlock(&dev->rng_lock);
 392
 393                result = mutex_lock_interruptible(&dev->lock);
 394                if (result)
 395                        goto bail;
 396                if (dev->valid == dev->used) {
 397                        result = _chaoskey_fill(dev);
 398                        if (result) {
 399                                mutex_unlock(&dev->lock);
 400                                goto bail;
 401                        }
 402
 403                        /* Read returned zero bytes */
 404                        if (dev->used == dev->valid) {
 405                                mutex_unlock(&dev->lock);
 406                                goto bail;
 407                        }
 408                }
 409
 410                this_time = dev->valid - dev->used;
 411                if (this_time > count)
 412                        this_time = count;
 413
 414                remain = copy_to_user(buffer, dev->buf + dev->used, this_time);
 415                if (remain) {
 416                        result = -EFAULT;
 417
 418                        /* Consume the bytes that were copied so we don't leak
 419                         * data to user space
 420                         */
 421                        dev->used += this_time - remain;
 422                        mutex_unlock(&dev->lock);
 423                        goto bail;
 424                }
 425
 426                count -= this_time;
 427                read_count += this_time;
 428                buffer += this_time;
 429                dev->used += this_time;
 430                mutex_unlock(&dev->lock);
 431        }
 432bail:
 433        if (read_count) {
 434                usb_dbg(dev->interface, "read %zu bytes", read_count);
 435                return read_count;
 436        }
 437        usb_dbg(dev->interface, "empty read, result %d", result);
 438        return result;
 439}
 440
 441static int chaoskey_rng_read(struct hwrng *rng, void *data,
 442                             size_t max, bool wait)
 443{
 444        struct chaoskey *dev = container_of(rng, struct chaoskey, hwrng);
 445        int this_time;
 446
 447        usb_dbg(dev->interface, "rng_read max %zu wait %d", max, wait);
 448
 449        if (!dev->present) {
 450                usb_dbg(dev->interface, "device not present");
 451                return 0;
 452        }
 453
 454        /* Hold the rng_lock until we acquire the device lock so that
 455         * this operation gets priority over other user access to the
 456         * device
 457         */
 458        mutex_lock(&dev->rng_lock);
 459
 460        mutex_lock(&dev->lock);
 461
 462        mutex_unlock(&dev->rng_lock);
 463
 464        /* Try to fill the buffer if empty. It doesn't actually matter
 465         * if _chaoskey_fill works; we'll just return zero bytes as
 466         * the buffer will still be empty
 467         */
 468        if (dev->valid == dev->used)
 469                (void) _chaoskey_fill(dev);
 470
 471        this_time = dev->valid - dev->used;
 472        if (this_time > max)
 473                this_time = max;
 474
 475        memcpy(data, dev->buf, this_time);
 476
 477        dev->used += this_time;
 478
 479        mutex_unlock(&dev->lock);
 480
 481        usb_dbg(dev->interface, "rng_read this_time %d\n", this_time);
 482        return this_time;
 483}
 484
 485#ifdef CONFIG_PM
 486static int chaoskey_suspend(struct usb_interface *interface,
 487                            pm_message_t message)
 488{
 489        usb_dbg(interface, "suspend");
 490        return 0;
 491}
 492
 493static int chaoskey_resume(struct usb_interface *interface)
 494{
 495        usb_dbg(interface, "resume");
 496        return 0;
 497}
 498#else
 499#define chaoskey_suspend NULL
 500#define chaoskey_resume NULL
 501#endif
 502
 503/* file operation pointers */
 504static const struct file_operations chaoskey_fops = {
 505        .owner = THIS_MODULE,
 506        .read = chaoskey_read,
 507        .open = chaoskey_open,
 508        .release = chaoskey_release,
 509        .llseek = default_llseek,
 510};
 511
 512/* class driver information */
 513static struct usb_class_driver chaoskey_class = {
 514        .name = "chaoskey%d",
 515        .fops = &chaoskey_fops,
 516        .minor_base = USB_CHAOSKEY_MINOR_BASE,
 517};
 518
 519/* usb specific object needed to register this driver with the usb subsystem */
 520static struct usb_driver chaoskey_driver = {
 521        .name = DRIVER_SHORT,
 522        .probe = chaoskey_probe,
 523        .disconnect = chaoskey_disconnect,
 524        .suspend = chaoskey_suspend,
 525        .resume = chaoskey_resume,
 526        .reset_resume = chaoskey_resume,
 527        .id_table = chaoskey_table,
 528        .supports_autosuspend = 1,
 529};
 530
 531module_usb_driver(chaoskey_driver);
 532
 533