1 /* $OpenBSD: uonerng.c,v 1.5 2020/05/29 04:42:25 deraadt 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 /* 48 * The OneRNG is documented to provide ~350kbits/s of entropy at 49 * ~7.8 bits/byte, and when used at a lower rate providing close 50 * to 8 bits/byte. 51 * 52 * Although this driver is able to consume the data at the full rate, 53 * we tune this down to 10kbit/s as the OpenBSD RNG is better off 54 * with small amounts of input at a time so as to not saturate the 55 * input queue and mute other sources of entropy. 56 * 57 * Furthermore, unlike other implementations, for us there is no benefit 58 * to discarding the initial bytes retrieved from the OneRNG, regardless 59 * of the quality of the data. (Empirical tests suggest that the initial 60 * quality is fine, anyway.) 61 */ 62 #define ONERNG_BUFSIZ 128 63 #define ONERNG_MSECS 100 64 65 #define ONERNG_TIMEOUT 1000 /* ms */ 66 67 /* 68 * Define ONERNG_MEASURE_RATE to periodically log rate at which we provide 69 * random data to the kernel. 70 */ 71 #ifdef ONERNG_MEASURE_RATE 72 #define ONERNG_RATE_SECONDS 30 73 #endif 74 75 /* OneRNG operational modes */ 76 #define ONERNG_OP_ENABLE "cmdO\n" /* start emitting data */ 77 #define ONERNG_OP_DISABLE "cmdo\n" /* stop emitting data */ 78 #define ONERNG_OP_FLUSH_ENTROPY "cmdw\n" 79 80 /* permits extracting the firmware in order to check the crypto signature */ 81 #define ONERNG_OP_EXTRACT_FIRMWARE "cmdX\n" 82 83 /* 84 * Noise sources include an avalache circuit and an RF circuit. 85 * There is also a whitener to provide a uniform distribution. 86 * Different combinations are possible. 87 */ 88 #define ONERNG_AVALANCHE_WHITENER "cmd0\n" /* device default */ 89 #define ONERNG_AVALANCHE "cmd1\n" 90 #define ONERNG_AVALANCHE_RF_WHITENER "cmd2\n" 91 #define ONERNG_AVALANCHE_RF "cmd3\n" 92 #define ONERNG_SILENT "cmd4\n" /* none; necessary for cmdX */ 93 #define ONERNG_SILENT2 "cmd5\n" 94 #define ONERNG_RF_WHITENER "cmd6\n" 95 #define ONERNG_RF "cmd7\n" 96 97 98 #define ONERNG_IFACE_CTRL_INDEX 0 99 #define ONERNG_IFACE_DATA_INDEX 1 100 101 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname) 102 103 struct uonerng_softc { 104 struct device sc_dev; 105 struct usbd_device *sc_udev; 106 107 int sc_ctl_iface_no; /* control */ 108 struct usbd_interface *sc_data_iface; /* data */ 109 110 struct usbd_pipe *sc_inpipe; 111 struct usbd_pipe *sc_outpipe; 112 113 struct timeout sc_timeout; 114 struct usb_task sc_task; 115 struct usbd_xfer *sc_xfer; 116 int *sc_buf; 117 #ifdef ONERNG_MEASURE_RATE 118 struct timeval sc_start; 119 struct timeval sc_cur; 120 int sc_counted_bytes; 121 #endif 122 u_char sc_dtr; /* current DTR state */ 123 u_char sc_rts; /* current RTS state */ 124 u_char sc_first_run; 125 }; 126 127 int uonerng_match(struct device *, void *, void *); 128 void uonerng_attach(struct device *, struct device *, void *); 129 int uonerng_detach(struct device *, int); 130 void uonerng_task(void *); 131 void uonerng_timeout(void *); 132 int uonerng_enable(struct uonerng_softc *sc); 133 void uonerng_cleanup(struct uonerng_softc *sc); 134 usbd_status uonerng_set_line_state(struct uonerng_softc *sc); 135 usbd_status uonerng_rts(struct uonerng_softc *sc, int onoff); 136 137 struct cfdriver uonerng_cd = { 138 NULL, "uonerng", DV_DULL 139 }; 140 141 const struct cfattach uonerng_ca = { 142 sizeof(struct uonerng_softc), uonerng_match, uonerng_attach, uonerng_detach 143 }; 144 145 int 146 uonerng_match(struct device *parent, void *match, void *aux) 147 { 148 struct usb_attach_arg *uaa = aux; 149 150 if (uaa->iface == NULL) 151 return UMATCH_NONE; 152 153 if (uaa->vendor != USB_VENDOR_OPENMOKO2 || 154 uaa->product != USB_PRODUCT_OPENMOKO2_ONERNG) 155 return UMATCH_NONE; 156 157 return UMATCH_VENDOR_PRODUCT; 158 } 159 160 void 161 uonerng_attach(struct device *parent, struct device *self, void *aux) 162 { 163 struct uonerng_softc *sc = (struct uonerng_softc *)self; 164 struct usb_attach_arg *uaa = aux; 165 struct usbd_interface *iface = uaa->iface; 166 usb_interface_descriptor_t *id; 167 usb_endpoint_descriptor_t *ed; 168 int ep_ibulk = -1, ep_obulk = -1; 169 usbd_status err; 170 int i; 171 172 sc->sc_udev = uaa->device; 173 sc->sc_dtr = -1; 174 sc->sc_rts = -1; 175 sc->sc_first_run = 1; 176 177 usb_init_task(&sc->sc_task, uonerng_task, sc, USB_TASK_TYPE_GENERIC); 178 179 /* locate the control interface number and the data interface */ 180 err = usbd_device2interface_handle(sc->sc_udev, 181 ONERNG_IFACE_CTRL_INDEX, &iface); 182 if (err || iface == NULL) { 183 printf("%s: failed to locate control interface, err=%s\n", 184 DEVNAME(sc), usbd_errstr(err)); 185 goto fail; 186 } 187 id = usbd_get_interface_descriptor(iface); 188 if (id != NULL && 189 id->bInterfaceClass == UICLASS_CDC && 190 id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL && 191 id->bInterfaceProtocol == UIPROTO_CDC_AT) { 192 sc->sc_ctl_iface_no = id->bInterfaceNumber; 193 } else { 194 printf("%s: control interface number not found\n", 195 DEVNAME(sc)); 196 goto fail; 197 } 198 199 err = usbd_device2interface_handle(sc->sc_udev, 200 ONERNG_IFACE_DATA_INDEX, &sc->sc_data_iface); 201 if (err || sc->sc_data_iface == NULL) { 202 printf("%s: failed to locate data interface, err=%s\n", 203 DEVNAME(sc), usbd_errstr(err)); 204 goto fail; 205 } 206 207 /* Find the bulk endpoints */ 208 id = usbd_get_interface_descriptor(sc->sc_data_iface); 209 if (id == NULL || 210 id->bInterfaceClass != UICLASS_CDC_DATA || 211 id->bInterfaceSubClass != UISUBCLASS_DATA) { 212 printf("%s: no data interface descriptor\n", DEVNAME(sc)); 213 goto fail; 214 } 215 for (i = 0; i < id->bNumEndpoints; i++) { 216 ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i); 217 if (ed == NULL) { 218 printf("%s: no endpoint descriptor for %d\n", 219 DEVNAME(sc), i); 220 goto fail; 221 } 222 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 223 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 224 ep_ibulk = ed->bEndpointAddress; 225 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 226 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 227 ep_obulk = ed->bEndpointAddress; 228 } 229 } 230 231 if (ep_ibulk == -1) { 232 printf("%s: Could not find data bulk in\n", DEVNAME(sc)); 233 goto fail; 234 } 235 if (ep_obulk == -1) { 236 printf("%s: Could not find data bulk out\n", DEVNAME(sc)); 237 goto fail; 238 } 239 240 /* Open pipes */ 241 err = usbd_open_pipe(sc->sc_data_iface, ep_ibulk, 242 USBD_EXCLUSIVE_USE, &sc->sc_inpipe); 243 if (err) { 244 printf("%s: failed to open bulk-in pipe: %s\n", 245 DEVNAME(sc), usbd_errstr(err)); 246 goto fail; 247 } 248 err = usbd_open_pipe(sc->sc_data_iface, ep_obulk, 249 USBD_EXCLUSIVE_USE, &sc->sc_outpipe); 250 if (err) { 251 printf("%s: failed to open bulk-out pipe: %s\n", 252 DEVNAME(sc), usbd_errstr(err)); 253 goto fail; 254 } 255 256 /* Allocate xfer/buffer for bulk transfers */ 257 sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev); 258 if (sc->sc_xfer == NULL) { 259 printf("%s: could not alloc xfer\n", DEVNAME(sc)); 260 goto fail; 261 } 262 sc->sc_buf = usbd_alloc_buffer(sc->sc_xfer, ONERNG_BUFSIZ); 263 if (sc->sc_buf == NULL) { 264 printf("%s: could not alloc %d-byte buffer\n", DEVNAME(sc), 265 ONERNG_BUFSIZ); 266 goto fail; 267 } 268 269 if (uonerng_enable(sc) != 0) { 270 goto fail; 271 } 272 273 timeout_set(&sc->sc_timeout, uonerng_timeout, sc); 274 275 /* get the initial random data as early as possible */ 276 uonerng_task(sc); 277 278 usb_add_task(sc->sc_udev, &sc->sc_task); 279 return; 280 281 fail: 282 usbd_deactivate(sc->sc_udev); 283 uonerng_cleanup(sc); 284 } 285 286 int 287 uonerng_enable(struct uonerng_softc *sc) 288 { 289 int err; 290 291 if ((err = uonerng_rts(sc, 0))) { 292 printf("%s: failed to clear RTS: %s\n", DEVNAME(sc), 293 usbd_errstr(err)); 294 return (1); 295 } 296 297 usbd_setup_xfer(sc->sc_xfer, sc->sc_outpipe, sc, 298 ONERNG_AVALANCHE_WHITENER, sizeof(ONERNG_AVALANCHE_WHITENER), 299 USBD_SYNCHRONOUS, ONERNG_TIMEOUT, NULL); 300 if ((err = usbd_transfer(sc->sc_xfer))) { 301 printf("%s: failed to set operating mode: %s\n", 302 DEVNAME(sc), usbd_errstr(err)); 303 return (1); 304 } 305 306 usbd_setup_xfer(sc->sc_xfer, sc->sc_outpipe, sc, 307 ONERNG_OP_ENABLE, sizeof(ONERNG_OP_ENABLE), 308 USBD_SYNCHRONOUS, ONERNG_TIMEOUT, NULL); 309 if ((err = usbd_transfer(sc->sc_xfer))) { 310 printf("%s: failed to enable device: %s\n", 311 DEVNAME(sc), usbd_errstr(err)); 312 return (1); 313 } 314 315 return (0); 316 } 317 318 int 319 uonerng_detach(struct device *self, int flags) 320 { 321 struct uonerng_softc *sc = (struct uonerng_softc *)self; 322 323 usb_rem_task(sc->sc_udev, &sc->sc_task); 324 if (timeout_initialized(&sc->sc_timeout)) { 325 timeout_del(&sc->sc_timeout); 326 } 327 uonerng_cleanup(sc); 328 return (0); 329 } 330 331 void 332 uonerng_cleanup(struct uonerng_softc *sc) 333 { 334 if (sc->sc_inpipe != NULL) { 335 usbd_close_pipe(sc->sc_inpipe); 336 sc->sc_inpipe = NULL; 337 } 338 if (sc->sc_outpipe != NULL) { 339 usbd_close_pipe(sc->sc_outpipe); 340 sc->sc_outpipe = NULL; 341 } 342 343 /* usbd_free_xfer will also free the buffer if necessary */ 344 if (sc->sc_xfer != NULL) { 345 usbd_free_xfer(sc->sc_xfer); 346 sc->sc_xfer = NULL; 347 } 348 } 349 350 usbd_status 351 uonerng_rts(struct uonerng_softc *sc, int onoff) 352 { 353 if (sc->sc_rts == onoff) 354 return USBD_NORMAL_COMPLETION; 355 sc->sc_rts = onoff; 356 357 return uonerng_set_line_state(sc); 358 } 359 360 usbd_status 361 uonerng_set_line_state(struct uonerng_softc *sc) 362 { 363 usb_device_request_t req; 364 int ls; 365 366 ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) | 367 (sc->sc_rts ? UCDC_LINE_RTS : 0); 368 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 369 req.bRequest = UCDC_SET_CONTROL_LINE_STATE; 370 USETW(req.wValue, ls); 371 USETW(req.wIndex, sc->sc_ctl_iface_no); 372 USETW(req.wLength, 0); 373 374 return usbd_do_request(sc->sc_udev, &req, 0); 375 } 376 377 void 378 uonerng_task(void *arg) 379 { 380 struct uonerng_softc *sc = (struct uonerng_softc *) arg; 381 usbd_status error; 382 u_int32_t len, int_count, i; 383 #ifdef ONERNG_MEASURE_RATE 384 time_t elapsed; 385 int rate; 386 #endif 387 388 usbd_setup_xfer(sc->sc_xfer, sc->sc_inpipe, NULL, sc->sc_buf, 389 ONERNG_BUFSIZ, 390 USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS | USBD_NO_COPY, 391 ONERNG_TIMEOUT, NULL); 392 error = usbd_transfer(sc->sc_xfer); 393 if (error) { 394 printf("%s: xfer failed: %s\n", DEVNAME(sc), 395 usbd_errstr(error)); 396 goto bail; 397 } 398 usbd_get_xfer_status(sc->sc_xfer, NULL, NULL, &len, NULL); 399 if (len < sizeof(int)) { 400 printf("%s: xfer too short (%u bytes) - dropping\n", 401 DEVNAME(sc), len); 402 goto bail; 403 } 404 405 #ifdef ONERNG_MEASURE_RATE 406 if (sc->sc_first_run) { 407 sc->sc_counted_bytes = 0; 408 getmicrotime(&(sc->sc_start)); 409 } 410 sc->sc_counted_bytes += len; 411 getmicrotime(&(sc->sc_cur)); 412 elapsed = sc->sc_cur.tv_sec - sc->sc_start.tv_sec; 413 if (elapsed >= ONERNG_RATE_SECONDS) { 414 rate = (8 * sc->sc_counted_bytes) / (elapsed * 1024); 415 printf("%s: transfer rate = %d kb/s\n", DEVNAME(sc), rate); 416 417 /* set up for next measurement */ 418 sc->sc_counted_bytes = 0; 419 getmicrotime(&(sc->sc_start)); 420 } 421 #endif 422 423 int_count = len / sizeof(int); 424 for (i = 0; i < int_count; i++) { 425 enqueue_randomness(sc->sc_buf[i]); 426 } 427 bail: 428 429 if (sc->sc_first_run) { 430 sc->sc_first_run = 0; 431 } else { 432 timeout_add_msec(&sc->sc_timeout, ONERNG_MSECS); 433 } 434 } 435 436 void 437 uonerng_timeout(void *arg) 438 { 439 struct uonerng_softc *sc = arg; 440 441 usb_add_task(sc->sc_udev, &sc->sc_task); 442 } 443