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