mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-16 01:22:02 +00:00
Merge branch 'origin/master' into u2f
This commit is contained in:
commit
8e7896456a
2
Makefile
2
Makefile
@ -10,7 +10,7 @@ OBJS += gen/bitmaps.o
|
||||
OBJS += gen/fonts.o
|
||||
|
||||
libtrezor.a: $(OBJS)
|
||||
ar rcs libtrezor.a $(OBJS)
|
||||
$(AR) rcs libtrezor.a $(OBJS)
|
||||
|
||||
include Makefile.include
|
||||
|
||||
|
@ -6,6 +6,7 @@ CC = $(PREFIX)gcc
|
||||
LD = $(PREFIX)gcc
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
OBJDUMP = $(PREFIX)objdump
|
||||
AR = $(PREFIX)ar
|
||||
FLASH = st-flash
|
||||
OPENOCD = openocd
|
||||
|
||||
|
@ -22,14 +22,14 @@
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 6
|
||||
#define VERSION_PATCH 7
|
||||
|
||||
#define STR(X) #X
|
||||
#define VERSTR(X) STR(X)
|
||||
|
||||
#define VERSION_MAJOR_CHAR "\x01"
|
||||
#define VERSION_MINOR_CHAR "\x02"
|
||||
#define VERSION_PATCH_CHAR "\x06"
|
||||
#define VERSION_PATCH_CHAR "\x07"
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python2
|
||||
bl = open('bl.bin').read()
|
||||
fw = open('fw.bin').read()
|
||||
combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:]
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python2
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python2
|
||||
import argparse
|
||||
import hashlib
|
||||
import struct
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#!/usr/bin/env python2
|
||||
import hashlib
|
||||
import os
|
||||
import subprocess
|
||||
|
106
bootloader/usb.c
106
bootloader/usb.c
@ -34,6 +34,9 @@
|
||||
#include "signatures.h"
|
||||
#include "sha2.h"
|
||||
|
||||
#define ENDPOINT_ADDRESS_IN (0x81)
|
||||
#define ENDPOINT_ADDRESS_OUT (0x01)
|
||||
|
||||
static const struct usb_device_descriptor dev_descr = {
|
||||
.bLength = USB_DT_DEVICE_SIZE,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
@ -51,66 +54,20 @@ static const struct usb_device_descriptor dev_descr = {
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
/* got via usbhid-dump from CP2110 */
|
||||
static const uint8_t hid_report_descriptor[] = {
|
||||
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x01, 0x75, 0x08, 0x95, 0x40, 0x26, 0xFF, 0x00,
|
||||
0x15, 0x00, 0x85, 0x01, 0x95, 0x01, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x02,
|
||||
0x95, 0x02, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x03, 0x95, 0x03, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x04, 0x95, 0x04, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x05, 0x95, 0x05, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x06,
|
||||
0x95, 0x06, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x07, 0x95, 0x07, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x08, 0x95, 0x08, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x09, 0x95, 0x09, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0A,
|
||||
0x95, 0x0A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0B, 0x95, 0x0B, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0C, 0x95, 0x0C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x0D, 0x95, 0x0D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0E,
|
||||
0x95, 0x0E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0F, 0x95, 0x0F, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x10, 0x95, 0x10, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x11, 0x95, 0x11, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x12,
|
||||
0x95, 0x12, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x13, 0x95, 0x13, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x14, 0x95, 0x14, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x15, 0x95, 0x15, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x16,
|
||||
0x95, 0x16, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x17, 0x95, 0x17, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x18, 0x95, 0x18, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x19, 0x95, 0x19, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1A,
|
||||
0x95, 0x1A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1B, 0x95, 0x1B, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1C, 0x95, 0x1C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x1D, 0x95, 0x1D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1E,
|
||||
0x95, 0x1E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x1F, 0x95, 0x1F, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x20, 0x95, 0x20, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x21, 0x95, 0x21, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x22,
|
||||
0x95, 0x22, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x23, 0x95, 0x23, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x24, 0x95, 0x24, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x25, 0x95, 0x25, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x26,
|
||||
0x95, 0x26, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x27, 0x95, 0x27, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x28, 0x95, 0x28, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x29, 0x95, 0x29, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2A,
|
||||
0x95, 0x2A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2B, 0x95, 0x2B, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2C, 0x95, 0x2C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x2D, 0x95, 0x2D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2E,
|
||||
0x95, 0x2E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x2F, 0x95, 0x2F, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x30, 0x95, 0x30, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x31, 0x95, 0x31, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x32,
|
||||
0x95, 0x32, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x33, 0x95, 0x33, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x34, 0x95, 0x34, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x35, 0x95, 0x35, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x36,
|
||||
0x95, 0x36, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x37, 0x95, 0x37, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x38, 0x95, 0x38, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x39, 0x95, 0x39, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3A,
|
||||
0x95, 0x3A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3B, 0x95, 0x3B, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3C, 0x95, 0x3C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01,
|
||||
0x91, 0x02, 0x85, 0x3D, 0x95, 0x3D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3E,
|
||||
0x95, 0x3E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x3F, 0x95, 0x3F, 0x09, 0x01,
|
||||
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x40, 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x41,
|
||||
0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x42, 0x95, 0x06, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x43,
|
||||
0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x44, 0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x45,
|
||||
0x95, 0x04, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x46, 0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x47,
|
||||
0x95, 0x02, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x50, 0x95, 0x08, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x51,
|
||||
0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x52, 0x95, 0x01, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x60,
|
||||
0x95, 0x0A, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x61, 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x62,
|
||||
0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x63, 0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x64,
|
||||
0x95, 0x3F, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x65, 0x95, 0x3E, 0x09, 0x01, 0xB1, 0x02, 0x85, 0x66,
|
||||
0x95, 0x13, 0x09, 0x01, 0xB1, 0x02, 0xC0,
|
||||
0x06, 0x00, 0xff, // USAGE_PAGE (Reserved)
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x85, 0x3f, // REPORT_ID (63)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x3f, // REPORT_COUNT (63)
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
static const struct {
|
||||
@ -136,14 +93,14 @@ static const struct {
|
||||
static const struct usb_endpoint_descriptor hid_endpoints[2] = {{
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bEndpointAddress = ENDPOINT_ADDRESS_IN,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 1,
|
||||
}, {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x02,
|
||||
.bEndpointAddress = ENDPOINT_ADDRESS_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 1,
|
||||
@ -194,8 +151,10 @@ static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uin
|
||||
|
||||
if ((req->bmRequestType != 0x81) ||
|
||||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
|
||||
(req->wValue != 0x2200)) return 0;
|
||||
(req->wValue != 0x2200))
|
||||
return 0;
|
||||
|
||||
/* Handle the HID report descriptor. */
|
||||
*buf = (uint8_t *)hid_report_descriptor;
|
||||
*len = sizeof(hid_report_descriptor);
|
||||
|
||||
@ -222,7 +181,7 @@ static uint8_t meta_backup[FLASH_META_LEN];
|
||||
static void send_msg_success(usbd_device *dev)
|
||||
{
|
||||
// send response: Success message (id 2), payload len 0
|
||||
while ( usbd_ep_write_packet(dev, 0x81,
|
||||
while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
|
||||
"?##" // header
|
||||
"\x00\x02" // msg_id
|
||||
"\x00\x00\x00\x00" // payload_len
|
||||
@ -234,7 +193,7 @@ static void send_msg_failure(usbd_device *dev)
|
||||
{
|
||||
// send response: Failure message (id 3), payload len 2
|
||||
// code = 99 (Failure_FirmwareError)
|
||||
while ( usbd_ep_write_packet(dev, 0x81,
|
||||
while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
|
||||
"?##" // header
|
||||
"\x00\x03" // msg_id
|
||||
"\x00\x00\x00\x02" // payload_len
|
||||
@ -251,7 +210,7 @@ static void send_msg_features(usbd_device *dev)
|
||||
// minor_version = VERSION_MINOR
|
||||
// patch_version = VERSION_PATCH
|
||||
// bootloader_mode = True
|
||||
while ( usbd_ep_write_packet(dev, 0x81,
|
||||
while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
|
||||
"?##" // header
|
||||
"\x00\x11" // msg_id
|
||||
"\x00\x00\x00\x1b" // payload_len
|
||||
@ -264,7 +223,7 @@ static void send_msg_buttonrequest_firmwarecheck(usbd_device *dev)
|
||||
{
|
||||
// send response: ButtonRequest message (id 26), payload len 2
|
||||
// code = ButtonRequest_FirmwareCheck (9)
|
||||
while ( usbd_ep_write_packet(dev, 0x81,
|
||||
while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
|
||||
"?##" // header
|
||||
"\x00\x1a" // msg_id
|
||||
"\x00\x00\x00\x02" // payload_len
|
||||
@ -284,7 +243,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
|
||||
uint32_t *w;
|
||||
static SHA256_CTX ctx;
|
||||
|
||||
if ( usbd_ep_read_packet(dev, 0x02, buf, 64) != 64) return;
|
||||
if ( usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_OUT, buf, 64) != 64) return;
|
||||
|
||||
if (flash_state == STATE_END) {
|
||||
return;
|
||||
@ -319,18 +278,20 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
|
||||
buttonUpdate();
|
||||
} while (!button.YesUp && !button.NoUp);
|
||||
if (button.YesUp) {
|
||||
layoutProgress("INSTALLING ... Please wait", 0);
|
||||
// backup metadata
|
||||
memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN);
|
||||
flash_unlock();
|
||||
// erase metadata area
|
||||
for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) {
|
||||
layoutProgress("ERASING ... Please wait", 1000*(i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST));
|
||||
flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
|
||||
}
|
||||
// erase code area
|
||||
for (i = FLASH_CODE_SECTOR_FIRST; i <= FLASH_CODE_SECTOR_LAST; i++) {
|
||||
layoutProgress("ERASING ... Please wait", 1000*(i - FLASH_META_SECTOR_FIRST) / (FLASH_CODE_SECTOR_LAST - FLASH_META_SECTOR_FIRST));
|
||||
flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
|
||||
}
|
||||
layoutProgress("INSTALLING ... Please wait", 0);
|
||||
flash_lock();
|
||||
send_msg_success(dev);
|
||||
flash_state = STATE_FLASHSTART;
|
||||
@ -391,7 +352,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
|
||||
return;
|
||||
}
|
||||
p = buf + 1;
|
||||
if (flash_anim % 8 == 4) {
|
||||
if (flash_anim % 32 == 4) {
|
||||
layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len);
|
||||
}
|
||||
flash_anim++;
|
||||
@ -405,7 +366,6 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
|
||||
flash_program_word(FLASH_META_START + flash_pos, *w); // the first 256 bytes of firmware is metadata descriptor
|
||||
} else {
|
||||
flash_program_word(FLASH_APP_START + (flash_pos - FLASH_META_DESC_LEN), *w); // the rest is code
|
||||
sha256_Update(&ctx, towrite, 4);
|
||||
}
|
||||
flash_pos += 4;
|
||||
wi = 0;
|
||||
@ -415,6 +375,8 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
|
||||
flash_lock();
|
||||
// flashing done
|
||||
if (flash_pos == flash_len) {
|
||||
sha256_Update(&ctx, (unsigned char*) FLASH_APP_START,
|
||||
flash_len - FLASH_META_DESC_LEN);
|
||||
flash_state = STATE_CHECK;
|
||||
send_msg_buttonrequest_firmwarecheck(dev);
|
||||
}
|
||||
@ -485,8 +447,8 @@ static void hid_set_config(usbd_device *dev, uint16_t wValue)
|
||||
{
|
||||
(void)wValue;
|
||||
|
||||
usbd_ep_setup(dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0);
|
||||
usbd_ep_setup(dev, 0x02, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback);
|
||||
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,
|
||||
|
@ -21,12 +21,12 @@
|
||||
#include "coins.h"
|
||||
|
||||
const CoinType coins[COINS_COUNT] = {
|
||||
{true, "Bitcoin", true, "BTC", true, 0, true, 100000, true, 5, true, 6, true, 10},
|
||||
{true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40},
|
||||
{true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0},
|
||||
{true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0},
|
||||
{true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0},
|
||||
{true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0},
|
||||
{true, "Bitcoin", true, "BTC", true, 0, true, 100000, true, 5, true, 6, true, 10, true, "\x18" "Bitcoin Signed Message:\n"},
|
||||
{true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40, true, "\x18" "Bitcoin Signed Message:\n"},
|
||||
{true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0, true, "\x19" "Namecoin Signed Message:\n"},
|
||||
{true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0, true, "\x19" "Litecoin Signed Message:\n"},
|
||||
{true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0, true, "\x19" "Dogecoin Signed Message:\n"},
|
||||
{true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0, true, "\x19" "DarkCoin Signed Message:\n"},
|
||||
};
|
||||
|
||||
const CoinType *coinByShortcut(const char *shortcut)
|
||||
|
@ -100,11 +100,11 @@ int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_le
|
||||
return hdnode_sign_digest(node, message, signature + 1, NULL);
|
||||
}
|
||||
|
||||
int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
sha256_Init(&ctx);
|
||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||
sha256_Update(&ctx, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
||||
uint8_t varint[5];
|
||||
uint32_t l = ser_length(message_len, varint);
|
||||
sha256_Update(&ctx, varint, l);
|
||||
@ -120,14 +120,14 @@ int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message
|
||||
return result;
|
||||
}
|
||||
|
||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
||||
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
uint8_t pubkey[65], addr_raw[21], hash[32];
|
||||
|
||||
// calculate hash
|
||||
sha256_Init(&ctx);
|
||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||
sha256_Update(&ctx, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
||||
uint8_t varint[5];
|
||||
uint32_t l = ser_length(message_len, varint);
|
||||
sha256_Update(&ctx, varint, l);
|
||||
|
@ -37,9 +37,9 @@ int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_le
|
||||
|
||||
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
|
||||
/* ECIES disabled
|
||||
int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_size, bool display_only, uint8_t *nonce, size_t *nonce_len, uint8_t *payload, size_t *payload_len, uint8_t *hmac, size_t *hmac_len, const uint8_t *privkey, const uint8_t *address_raw);
|
||||
|
@ -241,6 +241,7 @@ void fsm_msgWipeDevice(WipeDevice *msg)
|
||||
storage_reset();
|
||||
storage_reset_uuid();
|
||||
storage_commit();
|
||||
storage_clearPinArea();
|
||||
// the following does not work on Mac anyway :-/ Linux/Windows are fine, so it is not needed
|
||||
// usbReconnect(); // force re-enumeration because of the serial number change
|
||||
fsm_sendSuccess("Device wiped");
|
||||
@ -643,7 +644,7 @@ void fsm_msgSignMessage(SignMessage *msg)
|
||||
if (!node) return;
|
||||
|
||||
layoutProgressSwipe("Signing", 0);
|
||||
if (cryptoMessageSign(node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
|
||||
if (cryptoMessageSign(coin, node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw);
|
||||
@ -667,12 +668,14 @@ void fsm_msgVerifyMessage(VerifyMessage *msg)
|
||||
fsm_sendFailure(FailureType_Failure_Other, "No message provided");
|
||||
return;
|
||||
}
|
||||
const CoinType *coin = fsm_getCoin(msg->coin_name);
|
||||
if (!coin) return;
|
||||
layoutProgressSwipe("Verifying", 0);
|
||||
uint8_t addr_raw[21];
|
||||
if (!ecdsa_address_decode(msg->address, addr_raw)) {
|
||||
fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address");
|
||||
}
|
||||
if (msg->signature.size == 65 && cryptoMessageVerify(msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) {
|
||||
if (msg->signature.size == 65 && cryptoMessageVerify(coin, msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) {
|
||||
layoutVerifyAddress(msg->address);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Message verification cancelled");
|
||||
@ -747,7 +750,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
uint8_t digest[64];
|
||||
sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest);
|
||||
sha256_Raw((const uint8_t *)msg->challenge_visual, strlen(msg->challenge_visual), digest + 32);
|
||||
result = cryptoMessageSign(node, digest, 64, resp->signature.bytes);
|
||||
result = cryptoMessageSign(&(coins[0]), node, digest, 64, resp->signature.bytes);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
|
@ -56,6 +56,7 @@ SignMessage.coin_name max_size:17
|
||||
VerifyMessage.address max_size:36
|
||||
VerifyMessage.signature max_size:65
|
||||
VerifyMessage.message max_size:1024
|
||||
VerifyMessage.coin_name max_size:17
|
||||
|
||||
MessageSignature.address max_size:36
|
||||
MessageSignature.signature max_size:65
|
||||
|
@ -9,6 +9,7 @@ const uint32_t ResetDevice_strength_default = 256u;
|
||||
const char ResetDevice_language_default[17] = "english";
|
||||
const char RecoveryDevice_language_default[17] = "english";
|
||||
const char SignMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char VerifyMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char EncryptMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char EstimateTxSize_coin_name_default[17] = "Bitcoin";
|
||||
const char SignTx_coin_name_default[17] = "Bitcoin";
|
||||
@ -213,10 +214,11 @@ const pb_field_t SignMessage_fields[4] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t VerifyMessage_fields[4] = {
|
||||
const pb_field_t VerifyMessage_fields[5] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, VerifyMessage, address, address, 0),
|
||||
PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, signature, address, 0),
|
||||
PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, message, signature, 0),
|
||||
PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, VerifyMessage, coin_name, message, &VerifyMessage_coin_name_default),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -634,6 +634,8 @@ typedef struct _VerifyMessage {
|
||||
VerifyMessage_signature_t signature;
|
||||
bool has_message;
|
||||
VerifyMessage_message_t message;
|
||||
bool has_coin_name;
|
||||
char coin_name[17];
|
||||
} VerifyMessage;
|
||||
|
||||
typedef struct _WordAck {
|
||||
@ -647,6 +649,7 @@ extern const uint32_t ResetDevice_strength_default;
|
||||
extern const char ResetDevice_language_default[17];
|
||||
extern const char RecoveryDevice_language_default[17];
|
||||
extern const char SignMessage_coin_name_default[17];
|
||||
extern const char VerifyMessage_coin_name_default[17];
|
||||
extern const char EncryptMessage_coin_name_default[17];
|
||||
extern const char EstimateTxSize_coin_name_default[17];
|
||||
extern const char SignTx_coin_name_default[17];
|
||||
@ -688,7 +691,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define WordRequest_init_default {0}
|
||||
#define WordAck_init_default {""}
|
||||
#define SignMessage_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, "Bitcoin"}
|
||||
#define VerifyMessage_init_default {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define VerifyMessage_init_default {false, "", false, {0, {0}}, false, {0, {0}}, false, "Bitcoin"}
|
||||
#define MessageSignature_init_default {false, "", false, {0, {0}}}
|
||||
#define EncryptMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin"}
|
||||
#define EncryptedMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
@ -742,7 +745,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define WordRequest_init_zero {0}
|
||||
#define WordAck_init_zero {""}
|
||||
#define SignMessage_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, ""}
|
||||
#define VerifyMessage_init_zero {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define VerifyMessage_init_zero {false, "", false, {0, {0}}, false, {0, {0}}, false, ""}
|
||||
#define MessageSignature_init_zero {false, "", false, {0, {0}}}
|
||||
#define EncryptMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, ""}
|
||||
#define EncryptedMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
@ -904,6 +907,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define VerifyMessage_address_tag 1
|
||||
#define VerifyMessage_signature_tag 2
|
||||
#define VerifyMessage_message_tag 3
|
||||
#define VerifyMessage_coin_name_tag 4
|
||||
#define WordAck_word_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
@ -938,7 +942,7 @@ extern const pb_field_t RecoveryDevice_fields[7];
|
||||
extern const pb_field_t WordRequest_fields[1];
|
||||
extern const pb_field_t WordAck_fields[2];
|
||||
extern const pb_field_t SignMessage_fields[4];
|
||||
extern const pb_field_t VerifyMessage_fields[4];
|
||||
extern const pb_field_t VerifyMessage_fields[5];
|
||||
extern const pb_field_t MessageSignature_fields[3];
|
||||
extern const pb_field_t EncryptMessage_fields[6];
|
||||
extern const pb_field_t EncryptedMessage_fields[4];
|
||||
@ -994,7 +998,7 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define WordRequest_size 0
|
||||
#define WordAck_size 14
|
||||
#define SignMessage_size 1094
|
||||
#define VerifyMessage_size 1132
|
||||
#define VerifyMessage_size 1151
|
||||
#define MessageSignature_size 105
|
||||
#define EncryptMessage_size 1131
|
||||
#define EncryptedMessage_size 1168
|
||||
|
@ -6,6 +6,7 @@ HDNodePathType.address_n max_count:8
|
||||
|
||||
CoinType.coin_name max_size:17
|
||||
CoinType.coin_shortcut max_size:9
|
||||
CoinType.signed_message_header max_size:32
|
||||
|
||||
TxInputType.address_n max_count:8
|
||||
TxInputType.prev_hash max_size:32
|
||||
|
@ -28,7 +28,7 @@ const pb_field_t HDNodePathType_fields[3] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t CoinType_fields[8] = {
|
||||
const pb_field_t CoinType_fields[9] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0),
|
||||
PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0),
|
||||
PB_FIELD2( 3, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type, coin_shortcut, &CoinType_address_type_default),
|
||||
@ -36,6 +36,7 @@ const pb_field_t CoinType_fields[8] = {
|
||||
PB_FIELD2( 5, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2sh, maxfee_kb, &CoinType_address_type_p2sh_default),
|
||||
PB_FIELD2( 6, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2wpkh, address_type_p2sh, &CoinType_address_type_p2wpkh_default),
|
||||
PB_FIELD2( 7, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2wsh, address_type_p2wpkh, &CoinType_address_type_p2wsh_default),
|
||||
PB_FIELD2( 8, STRING , OPTIONAL, STATIC , OTHER, CoinType, signed_message_header, address_type_p2wsh, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,8 @@ typedef struct _CoinType {
|
||||
uint32_t address_type_p2wpkh;
|
||||
bool has_address_type_p2wsh;
|
||||
uint32_t address_type_p2wsh;
|
||||
bool has_signed_message_header;
|
||||
char signed_message_header[32];
|
||||
} CoinType;
|
||||
|
||||
typedef struct {
|
||||
@ -261,7 +263,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
/* Initializer values for message structs */
|
||||
#define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
#define HDNodePathType_init_default {HDNodeType_init_default, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define CoinType_init_default {false, "", false, "", false, 0u, false, 0, false, 5u, false, 6u, false, 10u}
|
||||
#define CoinType_init_default {false, "", false, "", false, 0u, false, 0, false, 5u, false, 6u, false, 10u, false, ""}
|
||||
#define MultisigRedeemScriptType_init_default {0, {HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
|
||||
#define TxInputType_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 4294967295u, false, InputScriptType_SPENDADDRESS, false, MultisigRedeemScriptType_init_default}
|
||||
#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_default, false, {0, {0}}}
|
||||
@ -272,7 +274,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
#define IdentityType_init_default {false, "", false, "", false, "", false, "", false, "", false, 0u}
|
||||
#define HDNodeType_init_zero {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
#define HDNodePathType_init_zero {HDNodeType_init_zero, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define CoinType_init_zero {false, "", false, "", false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define CoinType_init_zero {false, "", false, "", false, 0, false, 0, false, 0, false, 0, false, 0, false, ""}
|
||||
#define MultisigRedeemScriptType_init_zero {0, {HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
|
||||
#define TxInputType_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 0, false, (InputScriptType)0, false, MultisigRedeemScriptType_init_zero}
|
||||
#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_zero, false, {0, {0}}}
|
||||
@ -290,6 +292,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
#define CoinType_address_type_p2sh_tag 5
|
||||
#define CoinType_address_type_p2wpkh_tag 6
|
||||
#define CoinType_address_type_p2wsh_tag 7
|
||||
#define CoinType_signed_message_header_tag 8
|
||||
#define HDNodeType_depth_tag 1
|
||||
#define HDNodeType_fingerprint_tag 2
|
||||
#define HDNodeType_child_num_tag 3
|
||||
@ -342,7 +345,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t HDNodeType_fields[7];
|
||||
extern const pb_field_t HDNodePathType_fields[3];
|
||||
extern const pb_field_t CoinType_fields[8];
|
||||
extern const pb_field_t CoinType_fields[9];
|
||||
extern const pb_field_t MultisigRedeemScriptType_fields[4];
|
||||
extern const pb_field_t TxInputType_fields[8];
|
||||
extern const pb_field_t TxOutputType_fields[7];
|
||||
@ -355,7 +358,7 @@ extern const pb_field_t IdentityType_fields[7];
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define HDNodeType_size 121
|
||||
#define HDNodePathType_size 171
|
||||
#define CoinType_size 65
|
||||
#define CoinType_size 99
|
||||
#define MultisigRedeemScriptType_size 3741
|
||||
#define TxInputType_size 5497
|
||||
#define TxOutputType_size 3929
|
||||
|
@ -92,14 +92,29 @@ void storage_check_flash_errors(void)
|
||||
}
|
||||
}
|
||||
|
||||
void storage_from_flash(uint32_t version)
|
||||
bool storage_from_flash(void)
|
||||
{
|
||||
if (memcmp((void *)FLASH_STORAGE_START, "stor", 4) != 0) {
|
||||
// wrong magic
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t version = ((Storage *)(FLASH_STORAGE_START + 4 + sizeof(storage_uuid)))->version;
|
||||
// version 1: since 1.0.0
|
||||
// version 2: since 1.2.1
|
||||
// version 3: since 1.3.1
|
||||
// version 4: since 1.3.2
|
||||
// version 5: since 1.3.3
|
||||
// version 6: since 1.3.6
|
||||
if (version > STORAGE_VERSION) {
|
||||
// downgrade -> clear storage
|
||||
return false;
|
||||
}
|
||||
|
||||
// load uuid
|
||||
memcpy(storage_uuid, (void *)(FLASH_STORAGE_START + 4), sizeof(storage_uuid));
|
||||
data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str);
|
||||
// copy storage
|
||||
memcpy(&storage, (void *)(FLASH_STORAGE_START + 4 + sizeof(storage_uuid)), sizeof(Storage));
|
||||
if (version <= 5) {
|
||||
// convert PIN failure counter from version 5 format
|
||||
@ -117,28 +132,21 @@ void storage_from_flash(uint32_t version)
|
||||
storage.has_pin_failed_attempts = false;
|
||||
storage.pin_failed_attempts = 0;
|
||||
}
|
||||
storage.version = STORAGE_VERSION;
|
||||
// upgrade storage version
|
||||
if (version != STORAGE_VERSION) {
|
||||
storage.version = STORAGE_VERSION;
|
||||
storage_commit();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void storage_init(void)
|
||||
{
|
||||
storage_reset();
|
||||
// if magic is ok
|
||||
if (memcmp((void *)FLASH_STORAGE_START, "stor", 4) == 0) {
|
||||
// load uuid
|
||||
memcpy(storage_uuid, (void *)(FLASH_STORAGE_START + 4), sizeof(storage_uuid));
|
||||
data2hex(storage_uuid, sizeof(storage_uuid), storage_uuid_str);
|
||||
// load storage struct
|
||||
uint32_t version = ((Storage *)(FLASH_STORAGE_START + 4 + sizeof(storage_uuid)))->version;
|
||||
if (version && version <= STORAGE_VERSION) {
|
||||
storage_from_flash(version);
|
||||
}
|
||||
if (version != STORAGE_VERSION) {
|
||||
storage_commit();
|
||||
}
|
||||
} else {
|
||||
if (!storage_from_flash()) {
|
||||
storage_reset();
|
||||
storage_reset_uuid();
|
||||
storage_commit();
|
||||
storage_clearPinArea();
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,6 +429,15 @@ bool session_isPinCached(void)
|
||||
return sessionPinCached;
|
||||
}
|
||||
|
||||
void storage_clearPinArea()
|
||||
{
|
||||
flash_clear_status_flags();
|
||||
flash_unlock();
|
||||
flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32);
|
||||
flash_lock();
|
||||
storage_check_flash_errors();
|
||||
}
|
||||
|
||||
void storage_resetPinFails(uint32_t *pinfailsptr)
|
||||
{
|
||||
flash_clear_status_flags();
|
||||
|
@ -56,6 +56,7 @@ bool storage_hasPin(void);
|
||||
void storage_setPin(const char *pin);
|
||||
void session_cachePin(void);
|
||||
bool session_isPinCached(void);
|
||||
void storage_clearPinArea(void);
|
||||
void storage_resetPinFails(uint32_t *pinfailptr);
|
||||
bool storage_increasePinFails(uint32_t *pinfailptr);
|
||||
uint32_t *storage_getPinFailsPtr(void);
|
||||
|
@ -50,6 +50,7 @@ int main(void)
|
||||
storage_reset(); // wipe storage if debug link
|
||||
storage_reset_uuid();
|
||||
storage_commit();
|
||||
storage_clearPinArea(); // reset PIN failures if debug link
|
||||
#endif
|
||||
|
||||
oledDrawBitmap(40, 0, &bmp_logo64);
|
||||
|
@ -53,17 +53,20 @@ static const struct usb_device_descriptor dev_descr = {
|
||||
};
|
||||
|
||||
static const uint8_t hid_report_descriptor[] = {
|
||||
0x06, 0x00, 0xff, // USAGE_PAGE (Reserved)
|
||||
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)
|
||||
0x85, 0x3f, // REPORT_ID (63)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x3f, // REPORT_COUNT (63)
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x95, 0x40, // REPORT_COUNT (64)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x09, 0x01, // USAGE (1)
|
||||
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
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#!/usr/bin/env python2
|
||||
import glob
|
||||
import os
|
||||
from PIL import Image
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python2
|
||||
from PIL import Image
|
||||
|
||||
class Img(object):
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#!/usr/bin/env python2
|
||||
handlers = [
|
||||
'hard_fault_handler',
|
||||
'mem_manage_handler',
|
||||
|
2
vendor/trezor-common
vendored
2
vendor/trezor-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 8c6401bdef92ebef7375a0e58a06af117618519d
|
||||
Subproject commit 36a574056deacad8943f1412c3db149750f8b163
|
Loading…
Reference in New Issue
Block a user