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