xref: /openbsd-src/sys/dev/usb/uonerng.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
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