mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-03 20:11:00 +00:00
Bootloader - Switch from HID to WebUSB
This commit is contained in:
parent
cb067bd14c
commit
a22abfe90b
131
bootloader/usb.c
131
bootloader/usb.c
@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#include <libopencm3/usb/usbd.h>
|
||||
#include <libopencm3/usb/hid.h>
|
||||
#include <libopencm3/stm32/flash.h>
|
||||
|
||||
#include <string.h>
|
||||
@ -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_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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user