1 /* $OpenBSD: uonerng.c,v 1.4 2018/07/09 20:06:12 jasper Exp $ */ 2 /* 3 * Copyright (C) 2015 Devin Reade <gdr@gno.org> 4 * Copyright (C) 2015 Sean Levy <attila@stalphonsos.com> 5 * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> 6 * Copyright (c) 2006 Alexander Yurchenko <grange@openbsd.org> 7 * Copyright (c) 1998 The NetBSD Foundation, Inc. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * Moonbase Otago OneRNG TRNG. Note that the encoded vendor for this 24 * device is OpenMoko as OpenMoko has made its device ranges available 25 * for other open source / open hardware vendors. 26 * 27 * Product information can be found here: 28 * http://onerng.info/onerng 29 * 30 * Based on the ualea(4), uow(4), and umodem(4) source code. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 #include <sys/time.h> 37 #include <sys/timeout.h> 38 #include <machine/bus.h> 39 40 #include <dev/usb/usb.h> 41 #include <dev/usb/usbdi.h> 42 #include <dev/usb/usbdivar.h> 43 #include <dev/usb/usbdi_util.h> 44 #include <dev/usb/usbdevs.h> 45 #include <dev/usb/usbcdc.h> 46 47 #include <dev/rndvar.h> 48 49 /* 50 * The OneRNG is documented to provide ~350kbits/s of entropy at 51 * ~7.8 bits/byte, and when used at a lower rate providing close 52 * to 8 bits/byte. 53 * 54 * Although this driver is able to consume the data at the full rate, 55 * we tune this down to 10kbit/s as the OpenBSD RNG is better off 56 * with small amounts of input at a time so as to not saturate the 57 * input queue and mute other sources of entropy. 58 * 59 * Furthermore, unlike other implementations, for us there is no benefit 60 * to discarding the initial bytes retrieved from the OneRNG, regardless 61 * of the quality of the data. (Empirical tests suggest that the initial 62 * quality is fine, anyway.) 63 */ 64 #define ONERNG_BUFSIZ 128 65 #define ONERNG_MSECS 100 66 67 #define ONERNG_TIMEOUT 1000 /* ms */ 68 69 /* 70 * Define ONERNG_MEASURE_RATE to periodically log rate at which we provide 71 * random data to the kernel. 72 */ 73 #ifdef ONERNG_MEASURE_RATE 74 #define ONERNG_RATE_SECONDS 30 75 #endif 76 77 /* OneRNG operational modes */ 78 #define ONERNG_OP_ENABLE "cmdO\n" /* start emitting data */ 79 #define ONERNG_OP_DISABLE "cmdo\n" /* stop emitting data */ 80 #define ONERNG_OP_FLUSH_ENTROPY "cmdw\n" 81 82 /* permits extracting the firmware in order to check the crypto signature */ 83 #define ONERNG_OP_EXTRACT_FIRMWARE "cmdX\n" 84 85 /* 86 * Noise sources include an avalache circuit and an RF circuit. 87 * There is also a whitener to provide a uniform distribution. 88 * Different combinations are possible. 89 */ 90 #define ONERNG_AVALANCHE_WHITENER "cmd0\n" /* device default */ 91 #define ONERNG_AVALANCHE "cmd1\n" 92 #define ONERNG_AVALANCHE_RF_WHITENER "cmd2\n" 93 #define ONERNG_AVALANCHE_RF "cmd3\n" 94 #define ONERNG_SILENT "cmd4\n" /* none; necessary for cmdX */ 95 #define ONERNG_SILENT2 "cmd5\n" 96 #define ONERNG_RF_WHITENER "cmd6\n" 97 #define ONERNG_RF "cmd7\n" 98 99 100 #define ONERNG_IFACE_CTRL_INDEX 0 101 #define ONERNG_IFACE_DATA_INDEX 1 102 103 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) 104 105 struct uonerng_softc { 106 struct device sc_dev; 107 struct usbd_device *sc_udev; 108 109 int sc_ctl_iface_no; /* control */ 110 struct usbd_interface *sc_data_iface; /* data */ 111 112 struct usbd_pipe *sc_inpipe; 113 struct usbd_pipe *sc_outpipe; 114 115 struct timeout sc_timeout; 116 struct usb_task sc_task; 117 struct usbd_xfer *sc_xfer; 118 int *sc_buf; 119 #ifdef ONERNG_MEASURE_RATE 120 struct timeval sc_start; 121 struct timeval sc_cur; 122 int sc_counted_bytes; 123 #endif 124 u_char sc_dtr; /* current DTR state */ 125 u_char sc_rts; /* current RTS state */ 126 u_char sc_first_run; 127 }; 128 129 int uonerng_match(struct device *, void *, void *); 130 void uonerng_attach(struct device *, struct device *, void *); 131 int uonerng_detach(struct device *, int); 132 void uonerng_task(void *); 133 void uonerng_timeout(void *); 134 int uonerng_enable(struct uonerng_softc *sc); 135 void uonerng_cleanup(struct uonerng_softc *sc); 136 usbd_status uonerng_set_line_state(struct uonerng_softc *sc); 137 usbd_status uonerng_rts(struct uonerng_softc *sc, int onoff); 138 139 struct cfdriver uonerng_cd = { 140 NULL, "uonerng", DV_DULL 141 }; 142 143 const struct cfattach uonerng_ca = { 144 sizeof(struct uonerng_softc), uonerng_match, uonerng_attach, uonerng_detach 145 }; 146 147 int 148 uonerng_match(struct device *parent, void *match, void *aux) 149 { 150 struct usb_attach_arg *uaa = aux; 151 152 if (uaa->iface == NULL) 153 return UMATCH_NONE; 154 155 if (uaa->vendor != USB_VENDOR_OPENMOKO2 || 156 uaa->product != USB_PRODUCT_OPENMOKO2_ONERNG) 157 return UMATCH_NONE; 158 159 return UMATCH_VENDOR_PRODUCT; 160 } 161 162 void 163 uonerng_attach(struct device *parent, struct device *self, void *aux) 164 { 165 struct uonerng_softc *sc = (struct uonerng_softc *)self; 166 struct usb_attach_arg *uaa = aux; 167 struct usbd_interface *iface = uaa->iface; 168 usb_interface_descriptor_t *id; 169 usb_endpoint_descriptor_t *ed; 170 int ep_ibulk = -1, ep_obulk = -1; 171 usbd_status err; 172 int i; 173 174 sc->sc_udev = uaa->device; 175 sc->sc_dtr = -1; 176 sc->sc_rts = -1; 177 sc->sc_first_run = 1; 178 179 usb_init_task(&sc->sc_task, uonerng_task, sc, USB_TASK_TYPE_GENERIC); 180 181 /* locate the control interface number and the data interface */ 182 err = usbd_device2interface_handle(sc->sc_udev, 183 ONERNG_IFACE_CTRL_INDEX, &iface); 184 if (err || iface == NULL) { 185 printf("%s: failed to locate control interface, err=%s\n", 186 DEVNAME(sc), usbd_errstr(err)); 187 goto fail; 188 } 189 id = usbd_get_interface_descriptor(iface); 190 if (id != NULL && 191 id->bInterfaceClass == UICLASS_CDC && 192 id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL && 193 id->bInterfaceProtocol == UIPROTO_CDC_AT) { 194 sc->sc_ctl_iface_no = id->bInterfaceNumber; 195 } else { 196 printf("%s: control interface number not found\n", 197 DEVNAME(sc)); 198 goto fail; 199 } 200 201 err = usbd_device2interface_handle(sc->sc_udev, 202 ONERNG_IFACE_DATA_INDEX, &sc->sc_data_iface); 203 if (err || sc->sc_data_iface == NULL) { 204 printf("%s: failed to locate data interface, err=%s\n", 205 DEVNAME(sc), usbd_errstr(err)); 206 goto fail; 207 } 208 209 /* Find the bulk endpoints */ 210 id = usbd_get_interface_descriptor(sc->sc_data_iface); 211 if (id == NULL || 212 id->bInterfaceClass != UICLASS_CDC_DATA || 213 id->bInterfaceSubClass != UISUBCLASS_DATA) { 214 printf("%s: no data interface descriptor\n", DEVNAME(sc)); 215 goto fail; 216 } 217 for (i = 0; i < id->bNumEndpoints; i++) { 218 ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i); 219 if (ed == NULL) { 220 printf("%s: no endpoint descriptor for %d\n", 221 DEVNAME(sc), i); 222 goto fail; 223 } 224 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 225 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 226 ep_ibulk = ed->bEndpointAddress; 227 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 228 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 229 ep_obulk = ed->bEndpointAddress; 230 } 231 } 232 233 if (ep_ibulk == -1) { 234 printf("%s: Could not find data bulk in\n", DEVNAME(sc)); 235 goto fail; 236 } 237 if (ep_obulk == -1) { 238 printf("%s: Could not find data bulk out\n", DEVNAME(sc)); 239 goto fail; 240 } 241 242 /* Open pipes */ 243 err = usbd_open_pipe(sc->sc_data_iface, ep_ibulk, 244 USBD_EXCLUSIVE_USE, &sc->sc_inpipe); 245 if (err) { 246 printf("%s: failed to open bulk-in pipe: %s\n", 247 DEVNAME(sc), usbd_errstr(err)); 248 goto fail; 249 } 250 err = usbd_open_pipe(sc->sc_data_iface, ep_obulk, 251 USBD_EXCLUSIVE_USE, &sc->sc_outpipe); 252 if (err) { 253 printf("%s: failed to open bulk-out pipe: %s\n", 254 DEVNAME(sc), usbd_errstr(err)); 255 goto fail; 256 } 257 258 /* Allocate xfer/buffer for bulk transfers */ 259 sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev); 260 if (sc->sc_xfer == NULL) { 261 printf("%s: could not alloc xfer\n", DEVNAME(sc)); 262 goto fail; 263 } 264 sc->sc_buf = usbd_alloc_buffer(sc->sc_xfer, ONERNG_BUFSIZ); 265 if (sc->sc_buf == NULL) { 266 printf("%s: could not alloc %d-byte buffer\n", DEVNAME(sc), 267 ONERNG_BUFSIZ); 268 goto fail; 269 } 270 271 if (uonerng_enable(sc) != 0) { 272 goto fail; 273 } 274 275 timeout_set(&sc->sc_timeout, uonerng_timeout, sc); 276 277 /* get the initial random data as early as possible */ 278 uonerng_task(sc); 279 280 usb_add_task(sc->sc_udev, &sc->sc_task); 281 return; 282 283 fail: 284 usbd_deactivate(sc->sc_udev); 285 uonerng_cleanup(sc); 286 } 287 288 int 289 uonerng_enable(struct uonerng_softc *sc) 290 { 291 int err; 292 293 if ((err = uonerng_rts(sc, 0))) { 294 printf("%s: failed to clear RTS: %s\n", DEVNAME(sc), 295 usbd_errstr(err)); 296 return (1); 297 } 298 299 usbd_setup_xfer(sc->sc_xfer, sc->sc_outpipe, sc, 300 ONERNG_AVALANCHE_WHITENER, sizeof(ONERNG_AVALANCHE_WHITENER), 301 USBD_SYNCHRONOUS, ONERNG_TIMEOUT, NULL); 302 if ((err = usbd_transfer(sc->sc_xfer))) { 303 printf("%s: failed to set operating mode: %s\n", 304 DEVNAME(sc), usbd_errstr(err)); 305 return (1); 306 } 307 308 usbd_setup_xfer(sc->sc_xfer, sc->sc_outpipe, sc, 309 ONERNG_OP_ENABLE, sizeof(ONERNG_OP_ENABLE), 310 USBD_SYNCHRONOUS, ONERNG_TIMEOUT, NULL); 311 if ((err = usbd_transfer(sc->sc_xfer))) { 312 printf("%s: failed to enable device: %s\n", 313 DEVNAME(sc), usbd_errstr(err)); 314 return (1); 315 } 316 317 return (0); 318 } 319 320 int 321 uonerng_detach(struct device *self, int flags) 322 { 323 struct uonerng_softc *sc = (struct uonerng_softc *)self; 324 325 usb_rem_task(sc->sc_udev, &sc->sc_task); 326 if (timeout_initialized(&sc->sc_timeout)) { 327 timeout_del(&sc->sc_timeout); 328 } 329 uonerng_cleanup(sc); 330 return (0); 331 } 332 333 void 334 uonerng_cleanup(struct uonerng_softc *sc) 335 { 336 if (sc->sc_inpipe != NULL) { 337 usbd_close_pipe(sc->sc_inpipe); 338 sc->sc_inpipe = NULL; 339 } 340 if (sc->sc_outpipe != NULL) { 341 usbd_close_pipe(sc->sc_outpipe); 342 sc->sc_outpipe = NULL; 343 } 344 345 /* usbd_free_xfer will also free the buffer if necessary */ 346 if (sc->sc_xfer != NULL) { 347 usbd_free_xfer(sc->sc_xfer); 348 sc->sc_xfer = NULL; 349 } 350 } 351 352 usbd_status 353 uonerng_rts(struct uonerng_softc *sc, int onoff) 354 { 355 if (sc->sc_rts == onoff) 356 return USBD_NORMAL_COMPLETION; 357 sc->sc_rts = onoff; 358 359 return uonerng_set_line_state(sc); 360 } 361 362 usbd_status 363 uonerng_set_line_state(struct uonerng_softc *sc) 364 { 365 usb_device_request_t req; 366 int ls; 367 368 ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) | 369 (sc->sc_rts ? UCDC_LINE_RTS : 0); 370 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 371 req.bRequest = UCDC_SET_CONTROL_LINE_STATE; 372 USETW(req.wValue, ls); 373 USETW(req.wIndex, sc->sc_ctl_iface_no); 374 USETW(req.wLength, 0); 375 376 return usbd_do_request(sc->sc_udev, &req, 0); 377 } 378 379 void 380 uonerng_task(void *arg) 381 { 382 struct uonerng_softc *sc = (struct uonerng_softc *) arg; 383 usbd_status error; 384 u_int32_t len, int_count, i; 385 #ifdef ONERNG_MEASURE_RATE 386 time_t elapsed; 387 int rate; 388 #endif 389 390 usbd_setup_xfer(sc->sc_xfer, sc->sc_inpipe, NULL, sc->sc_buf, 391 ONERNG_BUFSIZ, 392 USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS | USBD_NO_COPY, 393 ONERNG_TIMEOUT, NULL); 394 error = usbd_transfer(sc->sc_xfer); 395 if (error) { 396 printf("%s: xfer failed: %s\n", DEVNAME(sc), 397 usbd_errstr(error)); 398 goto bail; 399 } 400 usbd_get_xfer_status(sc->sc_xfer, NULL, NULL, &len, NULL); 401 if (len < sizeof(int)) { 402 printf("%s: xfer too short (%u bytes) - dropping\n", 403 DEVNAME(sc), len); 404 goto bail; 405 } 406 407 #ifdef ONERNG_MEASURE_RATE 408 if (sc->sc_first_run) { 409 sc->sc_counted_bytes = 0; 410 getmicrotime(&(sc->sc_start)); 411 } 412 sc->sc_counted_bytes += len; 413 getmicrotime(&(sc->sc_cur)); 414 elapsed = sc->sc_cur.tv_sec - sc->sc_start.tv_sec; 415 if (elapsed >= ONERNG_RATE_SECONDS) { 416 rate = (8 * sc->sc_counted_bytes) / (elapsed * 1024); 417 printf("%s: transfer rate = %d kb/s\n", DEVNAME(sc), rate); 418 419 /* set up for next measurement */ 420 sc->sc_counted_bytes = 0; 421 getmicrotime(&(sc->sc_start)); 422 } 423 #endif 424 425 int_count = len / sizeof(int); 426 for (i = 0; i < int_count; i++) { 427 enqueue_randomness(sc->sc_buf[i]); 428 } 429 bail: 430 431 if (sc->sc_first_run) { 432 sc->sc_first_run = 0; 433 } else { 434 timeout_add_msec(&sc->sc_timeout, ONERNG_MSECS); 435 } 436 } 437 438 void 439 uonerng_timeout(void *arg) 440 { 441 struct uonerng_softc *sc = arg; 442 443 usb_add_task(sc->sc_udev, &sc->sc_task); 444 } 445