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