1 /* $OpenBSD: fido.c,v 1.4 2021/11/15 15:36:24 anton 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/kernel.h> 24 #include <sys/malloc.h> 25 #include <sys/signalvar.h> 26 #include <sys/device.h> 27 #include <sys/ioctl.h> 28 #include <sys/conf.h> 29 #include <sys/tty.h> 30 #include <sys/selinfo.h> 31 #include <sys/proc.h> 32 #include <sys/vnode.h> 33 #include <sys/poll.h> 34 35 #include <dev/usb/usb.h> 36 #include <dev/usb/usbhid.h> 37 38 #include <dev/usb/usbdevs.h> 39 #include <dev/usb/usbdi.h> 40 #include <dev/usb/usbdi_util.h> 41 42 #include <dev/usb/uhidev.h> 43 #include <dev/usb/uhid.h> 44 45 int fido_match(struct device *, void *, void *); 46 47 struct cfdriver fido_cd = { 48 NULL, "fido", DV_DULL 49 }; 50 51 const struct cfattach fido_ca = { 52 sizeof(struct uhid_softc), 53 fido_match, 54 uhid_attach, 55 uhid_detach, 56 }; 57 58 int 59 fido_match(struct device *parent, void *match, void *aux) 60 { 61 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; 62 int size; 63 void *desc; 64 int ret = UMATCH_NONE; 65 66 if (UHIDEV_CLAIM_MULTIPLE_REPORTID(uha)) 67 return (ret); 68 69 /* Find the FIDO usage page and U2F collection */ 70 uhidev_get_report_desc(uha->parent, &desc, &size); 71 if (hid_is_collection(desc, size, uha->reportid, 72 HID_USAGE2(HUP_FIDO, HUF_U2FHID))) 73 ret = UMATCH_IFACECLASS; 74 75 return (ret); 76 } 77 78 int 79 fidoopen(dev_t dev, int flag, int mode, struct proc *p) 80 { 81 return (uhid_do_open(dev, flag, mode, p)); 82 } 83 84 int 85 fidoioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 86 { 87 int error; 88 89 switch (cmd) { 90 case FIONBIO: 91 case FIOASYNC: 92 case USB_GET_DEVICEINFO: 93 break; 94 default: 95 /* 96 * Users don't need USB/HID ioctl access to fido(4) devices 97 * but it can still be useful for debugging by root. 98 */ 99 if ((error = suser(p)) != 0) 100 return (error); 101 break; 102 } 103 104 return (uhidioctl(dev, cmd, addr, flag, p)); 105 } 106