xref: /openbsd-src/sys/dev/usb/fido.c (revision b9ae17a00bed12afbf856d60e03f648694a9de20)
1*b9ae17a0Sguenther /*	$OpenBSD: fido.c,v 1.7 2024/12/30 02:46:00 guenther Exp $	*/
21ba9f8e2Sreyk 
31ba9f8e2Sreyk /*
41ba9f8e2Sreyk  * Copyright (c) 2019 Reyk Floeter <reyk@openbsd.org>
51ba9f8e2Sreyk  *
61ba9f8e2Sreyk  * Permission to use, copy, modify, and distribute this software for any
71ba9f8e2Sreyk  * purpose with or without fee is hereby granted, provided that the above
81ba9f8e2Sreyk  * copyright notice and this permission notice appear in all copies.
91ba9f8e2Sreyk  *
101ba9f8e2Sreyk  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111ba9f8e2Sreyk  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121ba9f8e2Sreyk  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131ba9f8e2Sreyk  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141ba9f8e2Sreyk  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151ba9f8e2Sreyk  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161ba9f8e2Sreyk  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171ba9f8e2Sreyk  */
181ba9f8e2Sreyk 
19a4a02513Sderaadt #include "fido.h"
20a4a02513Sderaadt 
211ba9f8e2Sreyk #include <sys/param.h>
22a4a02513Sderaadt #include <sys/systm.h>
23a4a02513Sderaadt #include <sys/device.h>
24a4a02513Sderaadt #include <sys/ioctl.h>
251ba9f8e2Sreyk #include <sys/conf.h>
26a4a02513Sderaadt #include <sys/tty.h>
271ba9f8e2Sreyk 
281ba9f8e2Sreyk #include <dev/usb/usb.h>
291ba9f8e2Sreyk #include <dev/usb/usbhid.h>
30a4a02513Sderaadt 
311ba9f8e2Sreyk #include <dev/usb/usbdi.h>
321ba9f8e2Sreyk 
331ba9f8e2Sreyk #include <dev/usb/uhidev.h>
341ba9f8e2Sreyk #include <dev/usb/uhid.h>
351ba9f8e2Sreyk 
361ba9f8e2Sreyk int fido_match(struct device *, void *, void *);
371ba9f8e2Sreyk 
381ba9f8e2Sreyk struct cfdriver fido_cd = {
391ba9f8e2Sreyk 	NULL, "fido", DV_DULL
401ba9f8e2Sreyk };
411ba9f8e2Sreyk 
421ba9f8e2Sreyk const struct cfattach fido_ca = {
431ba9f8e2Sreyk 	sizeof(struct uhid_softc),
441ba9f8e2Sreyk 	fido_match,
451ba9f8e2Sreyk 	uhid_attach,
461ba9f8e2Sreyk 	uhid_detach,
471ba9f8e2Sreyk };
481ba9f8e2Sreyk 
491ba9f8e2Sreyk int
501ba9f8e2Sreyk fido_match(struct device *parent, void *match, void *aux)
511ba9f8e2Sreyk {
521ba9f8e2Sreyk 	struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
531ba9f8e2Sreyk 	int			  size;
541ba9f8e2Sreyk 	void			 *desc;
551ba9f8e2Sreyk 	int			  ret = UMATCH_NONE;
561ba9f8e2Sreyk 
57faac88c0Santon 	if (UHIDEV_CLAIM_MULTIPLE_REPORTID(uha))
581ba9f8e2Sreyk 		return (ret);
591ba9f8e2Sreyk 
601ba9f8e2Sreyk 	/* Find the FIDO usage page and U2F collection */
611ba9f8e2Sreyk 	uhidev_get_report_desc(uha->parent, &desc, &size);
621ba9f8e2Sreyk 	if (hid_is_collection(desc, size, uha->reportid,
631ba9f8e2Sreyk 	    HID_USAGE2(HUP_FIDO, HUF_U2FHID)))
641ba9f8e2Sreyk 		ret = UMATCH_IFACECLASS;
651ba9f8e2Sreyk 
661ba9f8e2Sreyk 	return (ret);
671ba9f8e2Sreyk }
681ba9f8e2Sreyk 
691ba9f8e2Sreyk int
701ba9f8e2Sreyk fidoopen(dev_t dev, int flag, int mode, struct proc *p)
711ba9f8e2Sreyk {
721ba9f8e2Sreyk 	return (uhid_do_open(dev, flag, mode, p));
731ba9f8e2Sreyk }
741ba9f8e2Sreyk 
751ba9f8e2Sreyk int
761ba9f8e2Sreyk fidoioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
771ba9f8e2Sreyk {
781ba9f8e2Sreyk 	int	 error;
791ba9f8e2Sreyk 
801ba9f8e2Sreyk 	switch (cmd) {
811ba9f8e2Sreyk 	case FIOASYNC:
821ba9f8e2Sreyk 	case USB_GET_DEVICEINFO:
831ba9f8e2Sreyk 		break;
841ba9f8e2Sreyk 	default:
851ba9f8e2Sreyk 		/*
861ba9f8e2Sreyk 		 * Users don't need USB/HID ioctl access to fido(4) devices
871ba9f8e2Sreyk 		 * but it can still be useful for debugging by root.
881ba9f8e2Sreyk 		 */
891ba9f8e2Sreyk 		if ((error = suser(p)) != 0)
901ba9f8e2Sreyk 			return (error);
911ba9f8e2Sreyk 		break;
921ba9f8e2Sreyk 	}
931ba9f8e2Sreyk 
941ba9f8e2Sreyk 	return (uhidioctl(dev, cmd, addr, flag, p));
951ba9f8e2Sreyk }
96