1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-13 19:18:56 +00:00

trezorhal: rework winusb

This commit is contained in:
Pavol Rusnak 2018-01-23 19:32:01 +01:00
parent 00c193f5cc
commit ca0918dbce
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
3 changed files with 81 additions and 84 deletions

View File

@ -11,7 +11,7 @@
#include "usb.h"
#include "usbd_core.h"
#define UNCONST(X) ((uint8_t *)(X))
#define USE_WINUSB 1
#define USB_MAX_CONFIG_DESC_SIZE 256
#define USB_MAX_STR_SIZE 62
@ -25,6 +25,16 @@
#error Unable to determine proper USB_PHY_ID to use
#endif
#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, '1', 0x00, '0', 0x00, '0', 0x00, USB_WINUSB_VENDOR_CODE , 0x00 // MSFT100!
#define USB_WINUSB_EXTRA_STRING_INDEX 0xEE
#define USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR 0x04
#define USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR 0x05
#endif
#define UNCONST(X) ((uint8_t *)(X))
static usb_device_descriptor_t usb_dev_desc;
// Config descriptor
@ -279,6 +289,11 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
return USBD_OK;
}
#define USB_WEBUSB_REQ_GET_URL 0x02
#define USB_WEBUSB_DESCRIPTOR_TYPE_URL 0x03
#define USB_WEBUSB_URL_SCHEME_HTTP 0
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
@ -286,19 +301,69 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
return USBD_OK;
}
if ((req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_VENDOR) {
if (req->bRequest == USB_WEBUSB_VENDOR_CODE) {
if (req->wIndex == USB_WEBUSB_REQ_GET_URL && req->wValue == USB_WEBUSB_LANDING_PAGE) {
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[]
};
USBD_CtlSendData(dev, UNCONST(webusb_url), sizeof(webusb_url));
} else {
return USBD_FAIL;
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) {
if (req->bRequest == USB_WEBUSB_VENDOR_CODE) {
if (req->wIndex == USB_WEBUSB_REQ_GET_URL && req->wValue == USB_WEBUSB_LANDING_PAGE) {
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[]
};
USBD_CtlSendData(dev, UNCONST(webusb_url), sizeof(webusb_url));
} else {
return USBD_FAIL;
}
}
#if USE_WINUSB
if (req->bRequest == USB_WINUSB_VENDOR_CODE) {
if (req->wIndex == USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR) {
static const 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 - HACK: we present only interface 0 as WinUSB
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
};
USBD_CtlSendData(dev, UNCONST(winusb_wcid), sizeof(winusb_wcid));
} else {
return USBD_FAIL;
}
}
#endif
}
#if USE_WINUSB
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE) {
if (req->bRequest == USB_WINUSB_VENDOR_CODE) {
if (req->wIndex == USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR) {
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
};
USBD_CtlSendData(dev, UNCONST(winusb_guid), sizeof(winusb_guid));
} else {
return USBD_FAIL;
}
}
}
#endif
}
if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
return USBD_FAIL;
@ -374,7 +439,7 @@ static uint8_t *usb_class_get_cfg_desc(uint16_t *length) {
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
0x12, // bLength
USB_DESC_TYPE_STRING, // bDescriptorType
USB_WINUSB_EXTRA_STRING // wData
};

View File

@ -8,14 +8,6 @@
#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;

View File

@ -7,16 +7,6 @@
#define USB_CLASS_WEBUSB 0xFF
#define USB_WEBUSB_REQ_SET_PROTOCOL 0x0B
#define USB_WEBUSB_REQ_GET_PROTOCOL 0x03
#define USB_WEBUSB_REQ_SET_IDLE 0x0A
#define USB_WEBUSB_REQ_GET_IDLE 0x02
#define USB_WEBUSB_REQ_GET_URL 0x02
#define USB_WEBUSB_DESCRIPTOR_TYPE_URL 0x03
#define USB_WEBUSB_URL_SCHEME_HTTP 0
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
/* usb_webusb_add adds and configures new USB WebUSB interface according to
* configuration options passed in `info`. */
secbool usb_webusb_add(const usb_webusb_info_t *info) {
@ -227,66 +217,16 @@ 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) {
#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) {
#if USE_WINUSB
case USB_REQ_TYPE_VENDOR: // Vendor request
// Interface & Endpoint request
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
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;
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
}
break;
#endif
case USB_REQ_TYPE_STANDARD: // Interface & Endpoint request
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
state->alt_setting = req->wValue;
break;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
break;