diff --git a/fido2/main.c b/fido2/main.c index 0ed2d90..0faa7b1 100644 --- a/fido2/main.c +++ b/fido2/main.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "cbor.h" #include "device.h" @@ -19,10 +21,44 @@ #if !defined(TEST) -int main() +bool use_udp = true; + +void usage(const char * cmd) +{ + fprintf(stderr, "Usage: %s [-b udp|hidg]\n", cmd); + fprintf(stderr, " -b backing implementation: udp(default) or hidg\n"); + exit(1); +} + +int main(int argc, char *argv[]) { uint8_t hidmsg[64]; uint32_t t1 = 0; + int opt; + + while ((opt = getopt(argc, argv, "b:")) != -1) + { + switch (opt) + { + case 'b': + if (strcmp("udp", optarg) == 0) + { + use_udp = true; + } + else if (strcmp("hidg", optarg) == 0) + { + use_udp = false; + } + else + { + usage(argv[0]); + } + break; + default: + usage(argv[0]); + break; + } + } set_logging_mask( /*0*/ diff --git a/pc/app.h b/pc/app.h index 8d15715..b5e8bd2 100644 --- a/pc/app.h +++ b/pc/app.h @@ -7,6 +7,7 @@ #ifndef SRC_APP_H_ #define SRC_APP_H_ +#include #define USING_DEV_BOARD @@ -20,6 +21,8 @@ void printing_init(); +extern bool use_udp; + // 0xRRGGBB #define LED_INIT_VALUE 0x000800 #define LED_WINK_VALUE 0x000008 diff --git a/pc/device.c b/pc/device.c index c3b4673..a789228 100644 --- a/pc/device.c +++ b/pc/device.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "device.h" #include "cbor.h" @@ -118,12 +119,6 @@ void udp_send(int fd, uint8_t * buf, int size) } } -void udp_close(int fd) -{ - close(fd); -} - - uint32_t millis() { @@ -134,18 +129,42 @@ uint32_t millis() } -static int serverfd = 0; +static int fd = 0; void usbhid_init() { - // just bridge to UDP for now for pure software testing - serverfd = udp_server(); + if (use_udp) + { + fd = udp_server(); + } + else + { + fd = open("/dev/hidg0", O_RDWR); + if (fd < 0) + { + perror("hidg open"); + exit(1); + } + } } // Receive 64 byte USB HID message, don't block, return size of packet, return 0 if nothing int usbhid_recv(uint8_t * msg) { - int l = udp_recv(serverfd, msg, HID_MESSAGE_SIZE); + int l = 0; + if (use_udp) + { + l = udp_recv(fd, msg, HID_MESSAGE_SIZE); + } + else + { + l = read(fd, msg, HID_MESSAGE_SIZE); /* Flawfinder: ignore */ + if (l < 0) + { + perror("hidg read"); + exit(1); + } + } uint8_t magic_cmd[] = "\xac\x10\x52\xca\x95\xe5\x69\xde\x69\xe0\x2e\xbf" "\xf3\x33\x48\x5f\x13\xf9\xb2\xda\x34\xc5\xa8\xa3" "\x40\x52\x66\x97\xa9\xab\x2e\x0b\x39\x4d\x8d\x04" @@ -166,12 +185,23 @@ int usbhid_recv(uint8_t * msg) // Send 64 byte USB HID message void usbhid_send(uint8_t * msg) { - udp_send(serverfd, msg, HID_MESSAGE_SIZE); + if (use_udp) + { + udp_send(fd, msg, HID_MESSAGE_SIZE); + } + else + { + if (write(fd, msg, HID_MESSAGE_SIZE) < 0) + { + perror("hidg write"); + exit(1); + } + } } void usbhid_close() { - udp_close(serverfd); + close(fd); } void int_handler(int i) @@ -185,6 +215,7 @@ void device_init() { signal(SIGINT, int_handler); + printf1(TAG_GREEN, "Using %s backing\n", use_udp ? "UDP" : "hidg"); usbhid_init(); authenticator_initialize(); diff --git a/tools/gadgetfs/Makefile b/tools/gadgetfs/Makefile new file mode 100644 index 0000000..a9beca3 --- /dev/null +++ b/tools/gadgetfs/Makefile @@ -0,0 +1,65 @@ +TOP := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +KERNEL_FULL_VERSION := $(shell uname -r) +KERNEL_VERSION := $(shell uname -r | grep -o "^[^-]*") +KERNEL_MAJOR := $(shell uname -r | cut -d. -f1) +KERNEL_MINOR := $(shell uname -r | cut -d. -f2) + +MANUFACTURER = "Solo" +SERIAL = "1234567890" +IDVENDOR = "0x0483" +IDPRODUCT = "0xa2ca" +PRODUCT = "Solo Software Authenticator" +CONFIGFS = /sys/kernel/config +CONFIGFS_FIDO2 = $(CONFIGFS)/usb_gadget/fido2 + +obj-m := dummy_hcd.o +KVERSION := $(shell uname -r) +SHELL := /bin/bash + +all: dummy_hcd.ko + +install: dummy_hcd.ko + modprobe libcomposite + insmod dummy_hcd.ko + mkdir -p $(CONFIGFS_FIDO2) + mkdir -p $(CONFIGFS_FIDO2)/configs/c.1 + mkdir -p $(CONFIGFS_FIDO2)/functions/hid.usb0 + echo 0 > $(CONFIGFS_FIDO2)/functions/hid.usb0/protocol + echo 0 > $(CONFIGFS_FIDO2)/functions/hid.usb0/subclass + echo 64 > $(CONFIGFS_FIDO2)/functions/hid.usb0/report_length + echo -ne "\x06\xd0\xf1\x09\x01\xa1\x01\x09\x20\x15\x00\x26\xff\x00\x75\x08\x95\x40\x81\x02\x09\x21\x15\x00\x26\xff\x00\x75\x08\x95\x40\x91\x02\xc0" > $(CONFIGFS_FIDO2)/functions/hid.usb0/report_desc + mkdir $(CONFIGFS_FIDO2)/strings/0x409 + mkdir $(CONFIGFS_FIDO2)/configs/c.1/strings/0x409 + echo $(IDPRODUCT) > $(CONFIGFS_FIDO2)/idProduct + echo $(IDVENDOR) > $(CONFIGFS_FIDO2)/idVendor + echo $(SERIAL) > $(CONFIGFS_FIDO2)/strings/0x409/serialnumber + echo $(MANUFACTURER) > $(CONFIGFS_FIDO2)/strings/0x409/manufacturer + echo $(PRODUCT) > $(CONFIGFS_FIDO2)/strings/0x409/product + echo "Configuration 1" > $(CONFIGFS_FIDO2)/configs/c.1/strings/0x409/configuration + echo 120 > $(CONFIGFS_FIDO2)/configs/c.1/MaxPower + ln -s $(CONFIGFS_FIDO2)/functions/hid.usb0 $(CONFIGFS_FIDO2)/configs/c.1 + echo "dummy_udc.0" > $(CONFIGFS_FIDO2)/UDC + +uninstall: + echo "" > $(CONFIGFS_FIDO2)/UDC + rm $(CONFIGFS_FIDO2)/configs/c.1/hid.usb0 + rmdir $(CONFIGFS_FIDO2)/configs/c.1/strings/0x409 + rmdir $(CONFIGFS_FIDO2)/configs/c.1 + rmdir $(CONFIGFS_FIDO2)/functions/hid.usb0 + rmdir $(CONFIGFS_FIDO2)/strings/0x409 + rmdir $(CONFIGFS_FIDO2) + rmmod dummy_hcd.ko + +dummy_hcd.ko: dummy_hcd.c + $(MAKE) -C /lib/modules/$(KERNEL_FULL_VERSION)/build M=$(TOP) modules + +dummy_hcd.c: /usr/src/linux-source-$(KERNEL_VERSION).tar.bz2 + tar -xvf $^ linux-source-$(KERNEL_VERSION)/drivers/usb/gadget/udc/dummy_hcd.c + cp linux-source-$(KERNEL_VERSION)/drivers/usb/gadget/udc/dummy_hcd.c $@ + +clean: + $(MAKE) -C /lib/modules/$(KERNEL_FULL_VERSION)/build M=$(TOP) clean + rm -rf linux-source-$(KERNEL_VERSION) + rm -f dummy_hcd.c + +