From a22abfe90b846a7884bd365e2d8de99124ad000b Mon Sep 17 00:00:00 2001 From: Karel Bilek Date: Sun, 17 Dec 2017 04:36:47 +0100 Subject: [PATCH] Bootloader - Switch from HID to WebUSB --- bootloader/usb.c | 133 ++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 83 deletions(-) diff --git a/bootloader/usb.c b/bootloader/usb.c index 6442ab229d..8b64769969 100644 --- a/bootloader/usb.c +++ b/bootloader/usb.c @@ -18,7 +18,6 @@ */ #include -#include #include #include @@ -37,8 +36,16 @@ #include "secp256k1.h" #include "memzero.h" +#include "debug.h" + +#include "usb21_standard.h" +#include "webusb.h" +#include "winusb.h" + #define FIRMWARE_MAGIC "TRZR" +#define USB_INTERFACE_INDEX_MAIN 0 + #define ENDPOINT_ADDRESS_IN (0x81) #define ENDPOINT_ADDRESS_OUT (0x01) @@ -48,93 +55,54 @@ static bool old_was_unsigned; static const struct usb_device_descriptor dev_descr = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = 0x0200, + .bcdUSB = 0x0210, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = 64, .idVendor = 0x534c, .idProduct = 0x0001, - .bcdDevice = 0x0100, + .bcdDevice = 0x0300, .iManufacturer = 1, .iProduct = 2, .iSerialNumber = 3, .bNumConfigurations = 1, }; -static const uint8_t hid_report_descriptor[] = { - 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) - 0x09, 0x01, // USAGE (1) - 0xa1, 0x01, // COLLECTION (Application) - 0x09, 0x20, // USAGE (Input Report Data) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x40, // REPORT_COUNT (64) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x09, 0x21, // USAGE (Output Report Data) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x40, // REPORT_COUNT (64) - 0x91, 0x02, // OUTPUT (Data,Var,Abs) - 0xc0 // END_COLLECTION -}; - -static const struct { - struct usb_hid_descriptor hid_descriptor; - struct { - uint8_t bReportDescriptorType; - uint16_t wDescriptorLength; - } __attribute__((packed)) hid_report; -} __attribute__((packed)) hid_function = { - .hid_descriptor = { - .bLength = sizeof(hid_function), - .bDescriptorType = USB_DT_HID, - .bcdHID = 0x0111, - .bCountryCode = 0, - .bNumDescriptors = 1, - }, - .hid_report = { - .bReportDescriptorType = USB_DT_REPORT, - .wDescriptorLength = sizeof(hid_report_descriptor), - } -}; - -static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ +static const struct usb_endpoint_descriptor endpoints[2] = {{ .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = ENDPOINT_ADDRESS_IN, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, - .bInterval = 1, + .bInterval = 2, }, { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = ENDPOINT_ADDRESS_OUT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .wMaxPacketSize = 64, - .bInterval = 1, + .bInterval = 2, }}; -static const struct usb_interface_descriptor hid_iface[] = {{ +static const struct usb_interface_descriptor iface[] = {{ .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, + .bInterfaceNumber = USB_INTERFACE_INDEX_MAIN, .bAlternateSetting = 0, .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_HID, + .bInterfaceClass = USB_CLASS_VENDOR, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, .iInterface = 0, - .endpoint = hid_endpoints, - .extra = &hid_function, - .extralen = sizeof(hid_function), + .endpoint = endpoints, + .extra = NULL, + .extralen = 0, }}; static const struct usb_interface ifaces[] = {{ .num_altsetting = 1, - .altsetting = hid_iface, + .altsetting = iface, }}; static const struct usb_config_descriptor config = { @@ -155,23 +123,6 @@ static const char *usb_strings[] = { "", // empty serial }; -static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) -{ - (void)complete; - (void)dev; - - if ((req->bmRequestType != 0x81) || - (req->bRequest != USB_REQ_GET_DESCRIPTOR) || - (req->wValue != 0x2200)) - return 0; - - /* Handle the HID report descriptor. */ - *buf = (uint8_t *)hid_report_descriptor; - *len = sizeof(hid_report_descriptor); - - return 1; -} - enum { STATE_READY, STATE_OPEN, @@ -315,8 +266,9 @@ static void restore_metadata(const uint8_t *backup) flash_lock(); } -static void hid_rx_callback(usbd_device *dev, uint8_t ep) +static void rx_callback(usbd_device *dev, uint8_t ep) { + debugLog(0, "", "rx_callback start"); (void)ep; static uint8_t buf[64] __attribute__((aligned(4))); static uint8_t towrite[4] __attribute__((aligned(4))); @@ -628,23 +580,39 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep) } -static void hid_set_config(usbd_device *dev, uint16_t wValue) +static void set_config(usbd_device *dev, uint16_t wValue) { (void)wValue; - usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); - usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback); - - usbd_register_control_callback( - dev, - USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, - USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, - hid_control_request - ); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); + usbd_ep_setup(dev, ENDPOINT_ADDRESS_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, rx_callback); + debugLog(0, "", "set_config done"); } static usbd_device *usbd_dev; -static uint8_t usbd_control_buffer[128]; +static uint8_t usbd_control_buffer[256] __attribute__ ((aligned (2))); + +static const struct usb_device_capability_descriptor* capabilities[] = { + (const struct usb_device_capability_descriptor*)&webusb_platform_capability_descriptor, +}; + +static const struct usb_bos_descriptor bos_descriptor = { + .bLength = USB_DT_BOS_SIZE, + .bDescriptorType = USB_DT_BOS, + .bNumDeviceCaps = sizeof(capabilities)/sizeof(capabilities[0]), + .capabilities = capabilities +}; + +void usbInit(void) +{ + debugLog(0, "", "usb_init"); + usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, sizeof(usb_strings)/sizeof(const char *), usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, set_config); + usb21_setup(usbd_dev, &bos_descriptor); + static const char* origin_url = "trezor.io/start"; + webusb_setup(usbd_dev, origin_url); + winusb_setup(usbd_dev, USB_INTERFACE_INDEX_MAIN); +} void checkButtons(void) { @@ -678,8 +646,7 @@ void checkButtons(void) void usbLoop(bool firmware_present) { brand_new_firmware = !firmware_present; - usbd_dev = usbd_init(&otgfs_usb_driver, &dev_descr, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); - usbd_register_set_config_callback(usbd_dev, hid_set_config); + usbInit(); for (;;) { usbd_poll(usbd_dev); if (brand_new_firmware && (flash_state == STATE_READY || flash_state == STATE_OPEN)) {