diff --git a/embed/trezorhal/usb.c b/embed/trezorhal/usb.c index be65cbc163..750dee55ce 100644 --- a/embed/trezorhal/usb.c +++ b/embed/trezorhal/usb.c @@ -356,6 +356,22 @@ static uint8_t *usb_class_get_cfg_desc(uint16_t *length) { return usb_config_buf; } +static uint8_t *usb_class_get_usrstr_desc(USBD_HandleTypeDef *dev, uint8_t index, uint16_t *length) { +#if USE_WINUSB + static const uint8_t winusb_string_descriptor[] = { + 0x14, // bLength + USB_DESC_TYPE_STRING, // bDescriptorType + USB_WINUSB_EXTRA_STRING // wData + }; + if (index == USB_WINUSB_EXTRA_STRING_INDEX) { + *length = sizeof(winusb_string_descriptor); + return UNCONST(winusb_string_descriptor); + } +#endif + *length = 0; + return 0; +} + static const USBD_ClassTypeDef usb_class = { .Init = usb_class_init, .DeInit = usb_class_deinit, @@ -371,4 +387,5 @@ static const USBD_ClassTypeDef usb_class = { .GetFSConfigDescriptor = usb_class_get_cfg_desc, .GetOtherSpeedConfigDescriptor = usb_class_get_cfg_desc, .GetDeviceQualifierDescriptor = NULL, + .GetUsrStrDescriptor = usb_class_get_usrstr_desc, }; diff --git a/embed/trezorhal/usb_webusb-defs.h b/embed/trezorhal/usb_webusb-defs.h index 76883fbe14..910c9206af 100644 --- a/embed/trezorhal/usb_webusb-defs.h +++ b/embed/trezorhal/usb_webusb-defs.h @@ -8,6 +8,14 @@ #define USB_WEBUSB_VENDOR_CODE 0x01 // arbitrary #define USB_WEBUSB_LANDING_PAGE 0x01 // arbitrary +#define USE_WINUSB 1 + +#if USE_WINUSB +#define USB_WINUSB_VENDOR_CODE '!' // arbitrary, but must be equivalent to the last character in extra string +#define USB_WINUSB_EXTRA_STRING 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, USB_WINUSB_VENDOR_CODE , 0x00, 0x00, 0x00 // MSFT100! +#define USB_WINUSB_EXTRA_STRING_INDEX 0xEE +#endif + typedef struct __attribute__((packed)) { usb_interface_descriptor_t iface; usb_endpoint_descriptor_t ep_in; diff --git a/embed/trezorhal/usb_webusb-impl.h b/embed/trezorhal/usb_webusb-impl.h index 7134303509..9374390645 100644 --- a/embed/trezorhal/usb_webusb-impl.h +++ b/embed/trezorhal/usb_webusb-impl.h @@ -227,13 +227,44 @@ static void usb_webusb_class_deinit(USBD_HandleTypeDef *dev, usb_webusb_state_t static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, USBD_SetupReqTypedef *req) { - static const char url[] = { + static const char webusb_url[] = { 3 + 15, // uint8_t bLength USB_WEBUSB_DESCRIPTOR_TYPE_URL, // uint8_t bDescriptorType USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme 't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[] }; +#if USE_WINUSB + static uint8_t winusb_wcid[] = { + // header + 0x28, 0x00, 0x00, 0x00, // dwLength + 0x00, 0x01, // bcdVersion + 0x04, 0x00, // wIndex + 0x01, // bNumSections + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved + // functions + 0x00, // bInterfaceNumber - will get overriden below + 0x01, // reserved + 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleId + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved + }; + static const uint8_t winusb_guid[] = { + // header + 0x92, 0x00, 0x00, 0x00, // dwLength + 0x00, 0x01, // bcdVersion + 0x05, 0x00, // wIndex + 0x01, 0x00, // wNumFeatures + // features + 0x88, 0x00, 0x00, 0x00, // dwLength + 0x07, 0x00, 0x00, 0x00, // dwPropertyDataType + 0x2A, 0x00, // wNameLength + 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, // .name + 0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength + '{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData + }; +#endif + switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_VENDOR: // Vendor request @@ -244,13 +275,26 @@ static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *s case USB_WEBUSB_REQ_GET_URL: // we should check whether req->wValue == USB_WEBUSB_LANDING_PAGE, // but let's return always the same url for all indexes - USBD_CtlSendData(dev, UNCONST(url), sizeof(url)); + USBD_CtlSendData(dev, UNCONST(webusb_url), sizeof(webusb_url)); break; default: USBD_CtlError(dev, req); return USBD_FAIL; } break; +#if USE_WINUSB + case USB_WINUSB_VENDOR_CODE: + switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) { + case USB_REQ_RECIPIENT_DEVICE: + winusb_wcid[16] = state->desc_block->iface.bInterfaceNumber; + USBD_CtlSendData(dev, UNCONST(winusb_wcid), sizeof(winusb_wcid)); + break; + case USB_REQ_RECIPIENT_INTERFACE: + USBD_CtlSendData(dev, UNCONST(winusb_guid), sizeof(winusb_guid)); + break; + } + break; +#endif default: USBD_CtlError(dev, req); return USBD_FAIL; diff --git a/embed/trezorhal/usbd_conf.h b/embed/trezorhal/usbd_conf.h index 6cc722ad14..cf00d92baf 100644 --- a/embed/trezorhal/usbd_conf.h +++ b/embed/trezorhal/usbd_conf.h @@ -65,7 +65,7 @@ #define USB_PHY_HS_ID 1 #define USBD_MAX_NUM_INTERFACES 8 #define USBD_MAX_NUM_CONFIGURATION 1 -#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SUPPORT_USER_STRING 1 #define USBD_SELF_POWERED 0 #define USBD_DEBUG_LEVEL 0 #define USBD_LPM_ENABLED 1 diff --git a/embed/trezorhal/usbd_def.h b/embed/trezorhal/usbd_def.h index 615ad316af..d3c3e5b991 100644 --- a/embed/trezorhal/usbd_def.h +++ b/embed/trezorhal/usbd_def.h @@ -78,7 +78,7 @@ #define USB_REQ_RECIPIENT_DEVICE 0x00 #define USB_REQ_RECIPIENT_INTERFACE 0x01 #define USB_REQ_RECIPIENT_ENDPOINT 0x02 -#define USB_REQ_RECIPIENT_MASK 0x03 +#define USB_REQ_RECIPIENT_MASK 0x1F #define USB_REQ_GET_STATUS 0x00 #define USB_REQ_CLEAR_FEATURE 0x01