1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2022-2023 Vladimir Kondratyev <wulf@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include "opt_hid.h"
29
30 #include <sys/param.h>
31 #ifdef COMPAT_FREEBSD32
32 #include <sys/abi_compat.h>
33 #endif
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/fcntl.h>
37 #include <sys/filio.h>
38 #include <sys/ioccom.h>
39 #include <sys/kernel.h>
40 #include <sys/lock.h>
41 #include <sys/malloc.h>
42 #include <sys/module.h>
43 #include <sys/mutex.h>
44 #include <sys/poll.h>
45 #include <sys/priv.h>
46 #include <sys/proc.h>
47 #include <sys/selinfo.h>
48 #include <sys/sysctl.h>
49 #include <sys/systm.h>
50 #include <sys/taskqueue.h>
51 #include <sys/uio.h>
52
53 #include <dev/evdev/input.h>
54
55 #define HID_DEBUG_VAR u2f_debug
56 #include <dev/hid/hid.h>
57 #include <dev/hid/hidbus.h>
58 #include <dev/hid/hidquirk.h>
59
60 #include <dev/usb/usb_ioctl.h>
61
62 #ifdef HID_DEBUG
63 static int u2f_debug = 0;
64 static SYSCTL_NODE(_hw_hid, OID_AUTO, u2f, CTLFLAG_RW, 0,
65 "FIDO/U2F authenticator");
66 SYSCTL_INT(_hw_hid_u2f, OID_AUTO, debug, CTLFLAG_RWTUN,
67 &u2f_debug, 0, "Debug level");
68 #endif
69
70 #define U2F_MAX_REPORT_SIZE 64
71
72 /* A match on these entries will load u2f */
73 static const struct hid_device_id u2f_devs[] = {
74 { HID_BUS(BUS_USB), HID_TLC(HUP_FIDO, HUF_U2FHID) },
75 };
76
77 struct u2f_softc {
78 device_t sc_dev; /* base device */
79 struct cdev *dev;
80
81 struct mtx sc_mtx; /* hidbus private mutex */
82 struct task sc_kqtask; /* kqueue task */
83 void *sc_rdesc;
84 hid_size_t sc_rdesc_size;
85 hid_size_t sc_isize;
86 hid_size_t sc_osize;
87 struct selinfo sc_rsel;
88 struct { /* driver state */
89 bool open:1; /* device is open */
90 bool aslp:1; /* waiting for device data in read() */
91 bool sel:1; /* waiting for device data in poll() */
92 bool data:1; /* input report is stored in sc_buf */
93 int reserved:28;
94 } sc_state;
95 int sc_fflags; /* access mode for open lifetime */
96
97 uint8_t sc_buf[U2F_MAX_REPORT_SIZE];
98 };
99
100 static d_open_t u2f_open;
101 static d_read_t u2f_read;
102 static d_write_t u2f_write;
103 static d_ioctl_t u2f_ioctl;
104 static d_poll_t u2f_poll;
105 static d_kqfilter_t u2f_kqfilter;
106
107 static d_priv_dtor_t u2f_dtor;
108
109 static struct cdevsw u2f_cdevsw = {
110 .d_version = D_VERSION,
111 .d_open = u2f_open,
112 .d_read = u2f_read,
113 .d_write = u2f_write,
114 .d_ioctl = u2f_ioctl,
115 .d_poll = u2f_poll,
116 .d_kqfilter = u2f_kqfilter,
117 .d_name = "u2f",
118 };
119
120 static hid_intr_t u2f_intr;
121
122 static device_probe_t u2f_probe;
123 static device_attach_t u2f_attach;
124 static device_detach_t u2f_detach;
125
126 static void u2f_kqtask(void *context, int pending);
127 static int u2f_kqread(struct knote *, long);
128 static void u2f_kqdetach(struct knote *);
129 static void u2f_notify(struct u2f_softc *);
130
131 static struct filterops u2f_filterops_read = {
132 .f_isfd = 1,
133 .f_detach = u2f_kqdetach,
134 .f_event = u2f_kqread,
135 };
136
137 static int
u2f_probe(device_t dev)138 u2f_probe(device_t dev)
139 {
140 int error;
141
142 error = HIDBUS_LOOKUP_DRIVER_INFO(dev, u2f_devs);
143 if (error != 0)
144 return (error);
145
146 hidbus_set_desc(dev, "Authenticator");
147
148 return (BUS_PROBE_GENERIC);
149 }
150
151 static int
u2f_attach(device_t dev)152 u2f_attach(device_t dev)
153 {
154 struct u2f_softc *sc = device_get_softc(dev);
155 struct hid_device_info *hw = __DECONST(struct hid_device_info *,
156 hid_get_device_info(dev));
157 struct make_dev_args mda;
158 int error;
159
160 sc->sc_dev = dev;
161
162 error = hid_get_report_descr(dev, &sc->sc_rdesc, &sc->sc_rdesc_size);
163 if (error != 0)
164 return (ENXIO);
165 sc->sc_isize = hid_report_size_max(sc->sc_rdesc, sc->sc_rdesc_size,
166 hid_input, NULL);
167 if (sc->sc_isize > U2F_MAX_REPORT_SIZE) {
168 device_printf(dev, "Input report size too large. Truncate.\n");
169 sc->sc_isize = U2F_MAX_REPORT_SIZE;
170 }
171 sc->sc_osize = hid_report_size_max(sc->sc_rdesc, sc->sc_rdesc_size,
172 hid_output, NULL);
173 if (sc->sc_osize > U2F_MAX_REPORT_SIZE) {
174 device_printf(dev, "Output report size too large. Truncate.\n");
175 sc->sc_osize = U2F_MAX_REPORT_SIZE;
176 }
177
178 mtx_init(&sc->sc_mtx, "u2f lock", NULL, MTX_DEF);
179 knlist_init_mtx(&sc->sc_rsel.si_note, &sc->sc_mtx);
180 TASK_INIT(&sc->sc_kqtask, 0, u2f_kqtask, sc);
181
182 make_dev_args_init(&mda);
183 mda.mda_flags = MAKEDEV_WAITOK;
184 mda.mda_devsw = &u2f_cdevsw;
185 mda.mda_uid = UID_ROOT;
186 mda.mda_gid = GID_U2F;
187 mda.mda_mode = 0660;
188 mda.mda_si_drv1 = sc;
189
190 error = make_dev_s(&mda, &sc->dev, "u2f/%d", device_get_unit(dev));
191 if (error) {
192 device_printf(dev, "Can not create character device\n");
193 u2f_detach(dev);
194 return (error);
195 }
196 #ifndef U2F_DROP_UHID_ALIAS
197 (void)make_dev_alias(sc->dev, "uhid%d", device_get_unit(dev));
198 #endif
199
200 hid_add_dynamic_quirk(hw, HQ_NO_READAHEAD);
201
202 hidbus_set_lock(dev, &sc->sc_mtx);
203 hidbus_set_intr(dev, u2f_intr, sc);
204
205 return (0);
206 }
207
208 static int
u2f_detach(device_t dev)209 u2f_detach(device_t dev)
210 {
211 struct u2f_softc *sc = device_get_softc(dev);
212
213 DPRINTF("sc=%p\n", sc);
214
215 if (sc->dev != NULL) {
216 mtx_lock(&sc->sc_mtx);
217 sc->dev->si_drv1 = NULL;
218 /* Wake everyone */
219 u2f_notify(sc);
220 mtx_unlock(&sc->sc_mtx);
221 destroy_dev(sc->dev);
222 }
223
224 taskqueue_drain(taskqueue_thread, &sc->sc_kqtask);
225 hid_intr_stop(sc->sc_dev);
226
227 knlist_clear(&sc->sc_rsel.si_note, 0);
228 knlist_destroy(&sc->sc_rsel.si_note);
229 seldrain(&sc->sc_rsel);
230 mtx_destroy(&sc->sc_mtx);
231
232 return (0);
233 }
234
235 void
u2f_intr(void * context,void * buf,hid_size_t len)236 u2f_intr(void *context, void *buf, hid_size_t len)
237 {
238 struct u2f_softc *sc = context;
239
240 mtx_assert(&sc->sc_mtx, MA_OWNED);
241
242 DPRINTFN(5, "len=%d\n", len);
243 DPRINTFN(5, "data = %*D\n", len, buf, " ");
244
245 if (sc->sc_state.data)
246 return;
247
248 if (len > sc->sc_isize)
249 len = sc->sc_isize;
250
251 bcopy(buf, sc->sc_buf, len);
252
253 /* Make sure we don't process old data */
254 if (len < sc->sc_isize)
255 bzero(sc->sc_buf + len, sc->sc_isize - len);
256
257 sc->sc_state.data = true;
258
259 u2f_notify(sc);
260 }
261
262 static int
u2f_open(struct cdev * dev,int flag,int mode,struct thread * td)263 u2f_open(struct cdev *dev, int flag, int mode, struct thread *td)
264 {
265 struct u2f_softc *sc = dev->si_drv1;
266 int error;
267
268 if (sc == NULL)
269 return (ENXIO);
270
271 DPRINTF("sc=%p\n", sc);
272
273 mtx_lock(&sc->sc_mtx);
274 if (sc->sc_state.open) {
275 mtx_unlock(&sc->sc_mtx);
276 return (EBUSY);
277 }
278 sc->sc_state.open = true;
279 mtx_unlock(&sc->sc_mtx);
280
281 error = devfs_set_cdevpriv(sc, u2f_dtor);
282 if (error != 0) {
283 mtx_lock(&sc->sc_mtx);
284 sc->sc_state.open = false;
285 mtx_unlock(&sc->sc_mtx);
286 return (error);
287 }
288
289 /* Set up interrupt pipe. */
290 sc->sc_state.data = false;
291 sc->sc_fflags = flag;
292
293 return (0);
294 }
295
296
297 static void
u2f_dtor(void * data)298 u2f_dtor(void *data)
299 {
300 struct u2f_softc *sc = data;
301
302 #ifdef NOT_YET
303 /* Disable interrupts. */
304 hid_intr_stop(sc->sc_dev);
305 #endif
306
307 mtx_lock(&sc->sc_mtx);
308 sc->sc_state.open = false;
309 mtx_unlock(&sc->sc_mtx);
310 }
311
312 static int
u2f_read(struct cdev * dev,struct uio * uio,int flag)313 u2f_read(struct cdev *dev, struct uio *uio, int flag)
314 {
315 uint8_t buf[U2F_MAX_REPORT_SIZE];
316 struct u2f_softc *sc = dev->si_drv1;
317 size_t length = 0;
318 int error;
319
320 DPRINTFN(1, "\n");
321
322 if (sc == NULL)
323 return (EIO);
324
325 if (!sc->sc_state.data)
326 hid_intr_start(sc->sc_dev);
327
328 mtx_lock(&sc->sc_mtx);
329 if (dev->si_drv1 == NULL) {
330 error = EIO;
331 goto exit;
332 }
333
334 while (!sc->sc_state.data) {
335 if (flag & O_NONBLOCK) {
336 error = EWOULDBLOCK;
337 goto exit;
338 }
339 sc->sc_state.aslp = true;
340 DPRINTFN(5, "sleep on %p\n", &sc->sc_buf);
341 error = mtx_sleep(&sc->sc_buf, &sc->sc_mtx, PZERO | PCATCH,
342 "u2frd", 0);
343 DPRINTFN(5, "woke, error=%d\n", error);
344 if (dev->si_drv1 == NULL)
345 error = EIO;
346 if (error) {
347 sc->sc_state.aslp = false;
348 goto exit;
349 }
350 }
351
352 if (sc->sc_state.data && uio->uio_resid > 0) {
353 length = min(uio->uio_resid, sc->sc_isize);
354 memcpy(buf, sc->sc_buf, length);
355 sc->sc_state.data = false;
356 }
357 exit:
358 mtx_unlock(&sc->sc_mtx);
359 if (length != 0) {
360 /* Copy the data to the user process. */
361 DPRINTFN(5, "got %lu chars\n", (u_long)length);
362 error = uiomove(buf, length, uio);
363 }
364
365 return (error);
366 }
367
368 static int
u2f_write(struct cdev * dev,struct uio * uio,int flag)369 u2f_write(struct cdev *dev, struct uio *uio, int flag)
370 {
371 uint8_t buf[U2F_MAX_REPORT_SIZE];
372 struct u2f_softc *sc = dev->si_drv1;
373 int error;
374
375 DPRINTFN(1, "\n");
376
377 if (sc == NULL)
378 return (EIO);
379
380 if (uio->uio_resid != sc->sc_osize)
381 return (EINVAL);
382 error = uiomove(buf, uio->uio_resid, uio);
383 if (error == 0)
384 error = hid_write(sc->sc_dev, buf, sc->sc_osize);
385
386 return (error);
387 }
388
389 #ifdef COMPAT_FREEBSD32
390 static void
update_ugd32(const struct usb_gen_descriptor * ugd,struct usb_gen_descriptor32 * ugd32)391 update_ugd32(const struct usb_gen_descriptor *ugd,
392 struct usb_gen_descriptor32 *ugd32)
393 {
394 /* Don't update hgd_data pointer */
395 CP(*ugd, *ugd32, ugd_lang_id);
396 CP(*ugd, *ugd32, ugd_maxlen);
397 CP(*ugd, *ugd32, ugd_actlen);
398 CP(*ugd, *ugd32, ugd_offset);
399 CP(*ugd, *ugd32, ugd_config_index);
400 CP(*ugd, *ugd32, ugd_string_index);
401 CP(*ugd, *ugd32, ugd_iface_index);
402 CP(*ugd, *ugd32, ugd_altif_index);
403 CP(*ugd, *ugd32, ugd_endpt_index);
404 CP(*ugd, *ugd32, ugd_report_type);
405 /* Don't update reserved */
406 }
407 #endif
408
409 static int
u2f_ioctl(struct cdev * dev,u_long cmd,caddr_t addr,int flag,struct thread * td)410 u2f_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
411 struct thread *td)
412 {
413 #ifdef COMPAT_FREEBSD32
414 struct usb_gen_descriptor local_ugd;
415 struct usb_gen_descriptor32 *ugd32 = NULL;
416 #endif
417 struct u2f_softc *sc = dev->si_drv1;
418 struct usb_gen_descriptor *ugd = (struct usb_gen_descriptor *)addr;
419 uint32_t size;
420
421 DPRINTFN(2, "cmd=%lx\n", cmd);
422
423 if (sc == NULL)
424 return (EIO);
425
426 #ifdef COMPAT_FREEBSD32
427 switch (cmd) {
428 case USB_GET_REPORT_DESC32:
429 cmd = _IOC_NEWTYPE(cmd, struct usb_gen_descriptor);
430 ugd32 = (struct usb_gen_descriptor32 *)addr;
431 ugd = &local_ugd;
432 PTRIN_CP(*ugd32, *ugd, ugd_data);
433 CP(*ugd32, *ugd, ugd_lang_id);
434 CP(*ugd32, *ugd, ugd_maxlen);
435 CP(*ugd32, *ugd, ugd_actlen);
436 CP(*ugd32, *ugd, ugd_offset);
437 CP(*ugd32, *ugd, ugd_config_index);
438 CP(*ugd32, *ugd, ugd_string_index);
439 CP(*ugd32, *ugd, ugd_iface_index);
440 CP(*ugd32, *ugd, ugd_altif_index);
441 CP(*ugd32, *ugd, ugd_endpt_index);
442 CP(*ugd32, *ugd, ugd_report_type);
443 /* Don't copy reserved */
444 break;
445 }
446 #endif
447
448 /* fixed-length ioctls handling */
449 switch (cmd) {
450 case FIONBIO:
451 /* All handled in the upper FS layer. */
452 return (0);
453
454 case USB_GET_REPORT_DESC:
455 size = MIN(sc->sc_rdesc_size, ugd->ugd_maxlen);
456 ugd->ugd_actlen = size;
457 #ifdef COMPAT_FREEBSD32
458 if (ugd32 != NULL)
459 update_ugd32(ugd, ugd32);
460 #endif
461 if (ugd->ugd_data == NULL)
462 return (0); /* descriptor length only */
463
464 return (copyout(sc->sc_rdesc, ugd->ugd_data, size));
465
466 case USB_GET_DEVICEINFO:
467 return(hid_ioctl(
468 sc->sc_dev, USB_GET_DEVICEINFO, (uintptr_t)addr));
469 }
470
471 return (EINVAL);
472 }
473
474 static int
u2f_poll(struct cdev * dev,int events,struct thread * td)475 u2f_poll(struct cdev *dev, int events, struct thread *td)
476 {
477 struct u2f_softc *sc = dev->si_drv1;
478 int revents = 0;
479 bool start_intr = false;
480
481 if (sc == NULL)
482 return (POLLHUP);
483
484 if (events & (POLLOUT | POLLWRNORM) && (sc->sc_fflags & FWRITE))
485 revents |= events & (POLLOUT | POLLWRNORM);
486 if (events & (POLLIN | POLLRDNORM) && (sc->sc_fflags & FREAD)) {
487 mtx_lock(&sc->sc_mtx);
488 if (sc->sc_state.data)
489 revents |= events & (POLLIN | POLLRDNORM);
490 else {
491 sc->sc_state.sel = true;
492 start_intr = true;
493 selrecord(td, &sc->sc_rsel);
494 }
495 mtx_unlock(&sc->sc_mtx);
496 if (start_intr)
497 hid_intr_start(sc->sc_dev);
498 }
499
500 return (revents);
501 }
502
503 static int
u2f_kqfilter(struct cdev * dev,struct knote * kn)504 u2f_kqfilter(struct cdev *dev, struct knote *kn)
505 {
506 struct u2f_softc *sc = dev->si_drv1;
507
508 if (sc == NULL)
509 return (ENXIO);
510
511 switch(kn->kn_filter) {
512 case EVFILT_READ:
513 if (sc->sc_fflags & FREAD) {
514 kn->kn_fop = &u2f_filterops_read;
515 break;
516 }
517 /* FALLTHROUGH */
518 default:
519 return(EINVAL);
520 }
521 kn->kn_hook = sc;
522
523 knlist_add(&sc->sc_rsel.si_note, kn, 0);
524 return (0);
525 }
526
527 static void
u2f_kqtask(void * context,int pending)528 u2f_kqtask(void *context, int pending)
529 {
530 struct u2f_softc *sc = context;
531
532 hid_intr_start(sc->sc_dev);
533 }
534
535 static int
u2f_kqread(struct knote * kn,long hint)536 u2f_kqread(struct knote *kn, long hint)
537 {
538 struct u2f_softc *sc = kn->kn_hook;
539 int ret;
540
541 mtx_assert(&sc->sc_mtx, MA_OWNED);
542
543 if (sc->dev->si_drv1 == NULL) {
544 kn->kn_flags |= EV_EOF;
545 ret = 1;
546 } else {
547 ret = sc->sc_state.data ? 1 : 0;
548 if (!sc->sc_state.data)
549 taskqueue_enqueue(taskqueue_thread, &sc->sc_kqtask);
550 }
551
552 return (ret);
553 }
554
555 static void
u2f_kqdetach(struct knote * kn)556 u2f_kqdetach(struct knote *kn)
557 {
558 struct u2f_softc *sc = kn->kn_hook;
559
560 knlist_remove(&sc->sc_rsel.si_note, kn, 0);
561 }
562
563 static void
u2f_notify(struct u2f_softc * sc)564 u2f_notify(struct u2f_softc *sc)
565 {
566 mtx_assert(&sc->sc_mtx, MA_OWNED);
567
568 if (sc->sc_state.aslp) {
569 sc->sc_state.aslp = false;
570 DPRINTFN(5, "waking %p\n", &sc->sc_buf);
571 wakeup(&sc->sc_buf);
572 }
573 if (sc->sc_state.sel) {
574 sc->sc_state.sel = false;
575 selwakeuppri(&sc->sc_rsel, PZERO);
576 }
577 KNOTE_LOCKED(&sc->sc_rsel.si_note, 0);
578 }
579
580 static device_method_t u2f_methods[] = {
581 /* Device interface */
582 DEVMETHOD(device_probe, u2f_probe),
583 DEVMETHOD(device_attach, u2f_attach),
584 DEVMETHOD(device_detach, u2f_detach),
585
586 DEVMETHOD_END
587 };
588
589 static driver_t u2f_driver = {
590 #ifdef U2F_DROP_UHID_ALIAS
591 "uf2",
592 #else
593 "uhid",
594 #endif
595 u2f_methods,
596 sizeof(struct u2f_softc)
597 };
598
599 DRIVER_MODULE(u2f, hidbus, u2f_driver, NULL, NULL);
600 MODULE_DEPEND(u2f, hidbus, 1, 1, 1);
601 MODULE_DEPEND(u2f, hid, 1, 1, 1);
602 MODULE_VERSION(u2f, 1);
603 HID_PNP_INFO(u2f_devs);
604