# Original work Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Modified work Copyright 2022 Michael Gmelin. All Rights Reserved. # This file, with modifications, is licensed under the above Apache License. # # Modified work Copyright 2022 Yubico AB. All Rights Reserved. # This file, with modifications, is licensed under the above Apache License. # FreeBSD HID driver. # # There are two options to access UHID on FreeBSD: # # hidraw(4) - New method, not enabled by default # on FreeBSD 13.x and earlier # uhid(4) - Classic method, default option on # FreeBSD 13.x and earlier # # To avoid attaching the Yubikey as a keyboard, do: # # usbconfig ugenX.Y add_quirk UQ_KBD_IGNORE # usbconfig ugenX.Y reset # # The list of available devices is shown using `usbconfig list` # You can make these changes permanent by altering loader.conf. # # Starting from FreeBSD 13 hidraw(4) can be enabled using: # # sysrc kld_list+="hidraw hkbd" # cat >>/boot/loader.conf< HIDIOCGRAWINFO = 0x40085520 HIDIOCGRDESC = 0x2000551F HIDIOCGRDESCSIZE = 0x4004551E HIDIOCGFEATURE_9 = 0xC0095524 HIDIOCSFEATURE_9 = 0x80095523 class HidrawConnection(OtpConnection): """ hidraw(4) is FreeBSD's modern raw access driver, based on usbhid(4). It is available since FreeBSD 13 and can be activated by adding `hw.usb.usbhid.enable="1"` to `/boot/loader.conf`. The actual kernel module is loaded with `kldload hidraw`. """ def __init__(self, path): self.fd = os.open(path, os.O_RDWR) def close(self): os.close(self.fd) def receive(self): buf = bytearray(1 + 8) fcntl.ioctl(self.fd, HIDIOCGFEATURE_9, buf, True) return buf[1:] def send(self, data): buf = bytes([0]) + data fcntl.ioctl(self.fd, HIDIOCSFEATURE_9, buf) @staticmethod def get_info(dev): buf = bytearray(4 + 2 + 2) fcntl.ioctl(dev, HIDIOCGRAWINFO, buf, True) return struct.unpack("B", data)[0], data[1:] key, size = REPORT_DESCRIPTOR_KEY_MASK & head, SIZE_MASK & head value = struct.unpack_from("