1 /* $OpenBSD: fido.c,v 1.7 2024/12/30 02:46:00 guenther Exp $ */ 2 3 /* 4 * Copyright (c) 2019 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include "fido.h" 20 21 #include <sys/param.h> 22 #include <sys/systm.h> 23 #include <sys/device.h> 24 #include <sys/ioctl.h> 25 #include <sys/conf.h> 26 #include <sys/tty.h> 27 28 #include <dev/usb/usb.h> 29 #include <dev/usb/usbhid.h> 30 31 #include <dev/usb/usbdi.h> 32 33 #include <dev/usb/uhidev.h> 34 #include <dev/usb/uhid.h> 35 36 int fido_match(struct device *, void *, void *); 37 38 struct cfdriver fido_cd = { 39 NULL, "fido", DV_DULL 40 }; 41 42 const struct cfattach fido_ca = { 43 sizeof(struct uhid_softc), 44 fido_match, 45 uhid_attach, 46 uhid_detach, 47 }; 48 49 int 50 fido_match(struct device *parent, void *match, void *aux) 51 { 52 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; 53 int size; 54 void *desc; 55 int ret = UMATCH_NONE; 56 57 if (UHIDEV_CLAIM_MULTIPLE_REPORTID(uha)) 58 return (ret); 59 60 /* Find the FIDO usage page and U2F collection */ 61 uhidev_get_report_desc(uha->parent, &desc, &size); 62 if (hid_is_collection(desc, size, uha->reportid, 63 HID_USAGE2(HUP_FIDO, HUF_U2FHID))) 64 ret = UMATCH_IFACECLASS; 65 66 return (ret); 67 } 68 69 int 70 fidoopen(dev_t dev, int flag, int mode, struct proc *p) 71 { 72 return (uhid_do_open(dev, flag, mode, p)); 73 } 74 75 int 76 fidoioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 77 { 78 int error; 79 80 switch (cmd) { 81 case FIOASYNC: 82 case USB_GET_DEVICEINFO: 83 break; 84 default: 85 /* 86 * Users don't need USB/HID ioctl access to fido(4) devices 87 * but it can still be useful for debugging by root. 88 */ 89 if ((error = suser(p)) != 0) 90 return (error); 91 break; 92 } 93 94 return (uhidioctl(dev, cmd, addr, flag, p)); 95 } 96