1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-19 11:02:02 +00:00

Merge branch 'origin/master' into u2f

This commit is contained in:
Jochen Hoenicke 2016-05-26 20:58:31 +02:00
commit 8e7896456a
26 changed files with 130 additions and 133 deletions

View File

@ -10,7 +10,7 @@ OBJS += gen/bitmaps.o
OBJS += gen/fonts.o OBJS += gen/fonts.o
libtrezor.a: $(OBJS) libtrezor.a: $(OBJS)
ar rcs libtrezor.a $(OBJS) $(AR) rcs libtrezor.a $(OBJS)
include Makefile.include include Makefile.include

View File

@ -6,6 +6,7 @@ CC = $(PREFIX)gcc
LD = $(PREFIX)gcc LD = $(PREFIX)gcc
OBJCOPY = $(PREFIX)objcopy OBJCOPY = $(PREFIX)objcopy
OBJDUMP = $(PREFIX)objdump OBJDUMP = $(PREFIX)objdump
AR = $(PREFIX)ar
FLASH = st-flash FLASH = st-flash
OPENOCD = openocd OPENOCD = openocd

View File

@ -22,14 +22,14 @@
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 6 #define VERSION_PATCH 7
#define STR(X) #X #define STR(X) #X
#define VERSTR(X) STR(X) #define VERSTR(X) STR(X)
#define VERSION_MAJOR_CHAR "\x01" #define VERSION_MAJOR_CHAR "\x01"
#define VERSION_MINOR_CHAR "\x02" #define VERSION_MINOR_CHAR "\x02"
#define VERSION_PATCH_CHAR "\x06" #define VERSION_PATCH_CHAR "\x07"
#include "memory.h" #include "memory.h"

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
bl = open('bl.bin').read() bl = open('bl.bin').read()
fw = open('fw.bin').read() fw = open('fw.bin').read()
combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:] combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:]

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
import sys import sys
import os import os

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
import argparse import argparse
import hashlib import hashlib
import struct import struct

View File

@ -1,5 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
import hashlib import hashlib
import os import os
import subprocess import subprocess

View File

@ -34,6 +34,9 @@
#include "signatures.h" #include "signatures.h"
#include "sha2.h" #include "sha2.h"
#define ENDPOINT_ADDRESS_IN (0x81)
#define ENDPOINT_ADDRESS_OUT (0x01)
static const struct usb_device_descriptor dev_descr = { static const struct usb_device_descriptor dev_descr = {
.bLength = USB_DT_DEVICE_SIZE, .bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE, .bDescriptorType = USB_DT_DEVICE,
@ -51,66 +54,20 @@ static const struct usb_device_descriptor dev_descr = {
.bNumConfigurations = 1, .bNumConfigurations = 1,
}; };
/* got via usbhid-dump from CP2110 */
static const uint8_t hid_report_descriptor[] = { static const uint8_t hid_report_descriptor[] = {
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x09, 0x01, 0x75, 0x08, 0x95, 0x40, 0x26, 0xFF, 0x00, 0x06, 0x00, 0xff, // USAGE_PAGE (Reserved)
0x15, 0x00, 0x85, 0x01, 0x95, 0x01, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x02, 0x09, 0x01, // USAGE (1)
0x95, 0x02, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x03, 0x95, 0x03, 0x09, 0x01, 0xa1, 0x01, // COLLECTION (Application)
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x04, 0x95, 0x04, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x15, 0x00, // LOGICAL_MINIMUM (0)
0x91, 0x02, 0x85, 0x05, 0x95, 0x05, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x06, 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x95, 0x06, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x07, 0x95, 0x07, 0x09, 0x01, 0x85, 0x3f, // REPORT_ID (63)
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x08, 0x95, 0x08, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x75, 0x08, // REPORT_SIZE (8)
0x91, 0x02, 0x85, 0x09, 0x95, 0x09, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0A, 0x95, 0x3f, // REPORT_COUNT (63)
0x95, 0x0A, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0B, 0x95, 0x0B, 0x09, 0x01, 0x09, 0x01, // USAGE (1)
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0C, 0x95, 0x0C, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x81, 0x02, // INPUT (Data,Var,Abs)
0x91, 0x02, 0x85, 0x0D, 0x95, 0x0D, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0E, 0x09, 0x01, // USAGE (1)
0x95, 0x0E, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x0F, 0x95, 0x0F, 0x09, 0x01, 0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x81, 0x02, 0x09, 0x01, 0x91, 0x02, 0x85, 0x10, 0x95, 0x10, 0x09, 0x01, 0x81, 0x02, 0x09, 0x01, 0xc0 // END_COLLECTION
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,
}; };
static const struct { static const struct {
@ -136,14 +93,14 @@ static const struct {
static const struct usb_endpoint_descriptor hid_endpoints[2] = {{ static const struct usb_endpoint_descriptor hid_endpoints[2] = {{
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x81, .bEndpointAddress = ENDPOINT_ADDRESS_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64, .wMaxPacketSize = 64,
.bInterval = 1, .bInterval = 1,
}, { }, {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x02, .bEndpointAddress = ENDPOINT_ADDRESS_OUT,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 64, .wMaxPacketSize = 64,
.bInterval = 1, .bInterval = 1,
@ -194,8 +151,10 @@ static int hid_control_request(usbd_device *dev, struct usb_setup_data *req, uin
if ((req->bmRequestType != 0x81) || if ((req->bmRequestType != 0x81) ||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) || (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; *buf = (uint8_t *)hid_report_descriptor;
*len = sizeof(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) static void send_msg_success(usbd_device *dev)
{ {
// send response: Success message (id 2), payload len 0 // 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 "?##" // header
"\x00\x02" // msg_id "\x00\x02" // msg_id
"\x00\x00\x00\x00" // payload_len "\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 // send response: Failure message (id 3), payload len 2
// code = 99 (Failure_FirmwareError) // code = 99 (Failure_FirmwareError)
while ( usbd_ep_write_packet(dev, 0x81, while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
"?##" // header "?##" // header
"\x00\x03" // msg_id "\x00\x03" // msg_id
"\x00\x00\x00\x02" // payload_len "\x00\x00\x00\x02" // payload_len
@ -251,7 +210,7 @@ static void send_msg_features(usbd_device *dev)
// minor_version = VERSION_MINOR // minor_version = VERSION_MINOR
// patch_version = VERSION_PATCH // patch_version = VERSION_PATCH
// bootloader_mode = True // bootloader_mode = True
while ( usbd_ep_write_packet(dev, 0x81, while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
"?##" // header "?##" // header
"\x00\x11" // msg_id "\x00\x11" // msg_id
"\x00\x00\x00\x1b" // payload_len "\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 // send response: ButtonRequest message (id 26), payload len 2
// code = ButtonRequest_FirmwareCheck (9) // code = ButtonRequest_FirmwareCheck (9)
while ( usbd_ep_write_packet(dev, 0x81, while ( usbd_ep_write_packet(dev, ENDPOINT_ADDRESS_IN,
"?##" // header "?##" // header
"\x00\x1a" // msg_id "\x00\x1a" // msg_id
"\x00\x00\x00\x02" // payload_len "\x00\x00\x00\x02" // payload_len
@ -284,7 +243,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
uint32_t *w; uint32_t *w;
static SHA256_CTX ctx; 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) { if (flash_state == STATE_END) {
return; return;
@ -319,18 +278,20 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
buttonUpdate(); buttonUpdate();
} while (!button.YesUp && !button.NoUp); } while (!button.YesUp && !button.NoUp);
if (button.YesUp) { if (button.YesUp) {
layoutProgress("INSTALLING ... Please wait", 0);
// backup metadata // backup metadata
memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN); memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN);
flash_unlock(); flash_unlock();
// erase metadata area // erase metadata area
for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { 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); flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
} }
// erase code area // erase code area
for (i = FLASH_CODE_SECTOR_FIRST; i <= FLASH_CODE_SECTOR_LAST; i++) { 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); flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
} }
layoutProgress("INSTALLING ... Please wait", 0);
flash_lock(); flash_lock();
send_msg_success(dev); send_msg_success(dev);
flash_state = STATE_FLASHSTART; flash_state = STATE_FLASHSTART;
@ -391,7 +352,7 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
return; return;
} }
p = buf + 1; p = buf + 1;
if (flash_anim % 8 == 4) { if (flash_anim % 32 == 4) {
layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len); layoutProgress("INSTALLING ... Please wait", 1000 * flash_pos / flash_len);
} }
flash_anim++; 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 flash_program_word(FLASH_META_START + flash_pos, *w); // the first 256 bytes of firmware is metadata descriptor
} else { } else {
flash_program_word(FLASH_APP_START + (flash_pos - FLASH_META_DESC_LEN), *w); // the rest is code 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; flash_pos += 4;
wi = 0; wi = 0;
@ -415,6 +375,8 @@ static void hid_rx_callback(usbd_device *dev, uint8_t ep)
flash_lock(); flash_lock();
// flashing done // flashing done
if (flash_pos == flash_len) { if (flash_pos == flash_len) {
sha256_Update(&ctx, (unsigned char*) FLASH_APP_START,
flash_len - FLASH_META_DESC_LEN);
flash_state = STATE_CHECK; flash_state = STATE_CHECK;
send_msg_buttonrequest_firmwarecheck(dev); send_msg_buttonrequest_firmwarecheck(dev);
} }
@ -485,8 +447,8 @@ static void hid_set_config(usbd_device *dev, uint16_t wValue)
{ {
(void)wValue; (void)wValue;
usbd_ep_setup(dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); usbd_ep_setup(dev, ENDPOINT_ADDRESS_IN, 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_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, hid_rx_callback);
usbd_register_control_callback( usbd_register_control_callback(
dev, dev,

View File

@ -21,12 +21,12 @@
#include "coins.h" #include "coins.h"
const CoinType coins[COINS_COUNT] = { const CoinType coins[COINS_COUNT] = {
{true, "Bitcoin", true, "BTC", true, 0, true, 100000, true, 5, true, 6, true, 10}, {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, "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, "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, "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, "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, "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) const CoinType *coinByShortcut(const char *shortcut)

View File

@ -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); 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_CTX ctx;
sha256_Init(&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]; uint8_t varint[5];
uint32_t l = ser_length(message_len, varint); uint32_t l = ser_length(message_len, varint);
sha256_Update(&ctx, varint, l); sha256_Update(&ctx, varint, l);
@ -120,14 +120,14 @@ int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message
return result; 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; SHA256_CTX ctx;
uint8_t pubkey[65], addr_raw[21], hash[32]; uint8_t pubkey[65], addr_raw[21], hash[32];
// calculate hash // calculate hash
sha256_Init(&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]; uint8_t varint[5];
uint32_t l = ser_length(message_len, varint); uint32_t l = ser_length(message_len, varint);
sha256_Update(&ctx, varint, l); sha256_Update(&ctx, varint, l);

View File

@ -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 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 /* 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); 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);

View File

@ -241,6 +241,7 @@ void fsm_msgWipeDevice(WipeDevice *msg)
storage_reset(); storage_reset();
storage_reset_uuid(); storage_reset_uuid();
storage_commit(); storage_commit();
storage_clearPinArea();
// the following does not work on Mac anyway :-/ Linux/Windows are fine, so it is not needed // 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 // usbReconnect(); // force re-enumeration because of the serial number change
fsm_sendSuccess("Device wiped"); fsm_sendSuccess("Device wiped");
@ -643,7 +644,7 @@ void fsm_msgSignMessage(SignMessage *msg)
if (!node) return; if (!node) return;
layoutProgressSwipe("Signing", 0); 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; resp->has_address = true;
uint8_t addr_raw[21]; uint8_t addr_raw[21];
ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw); 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"); fsm_sendFailure(FailureType_Failure_Other, "No message provided");
return; return;
} }
const CoinType *coin = fsm_getCoin(msg->coin_name);
if (!coin) return;
layoutProgressSwipe("Verifying", 0); layoutProgressSwipe("Verifying", 0);
uint8_t addr_raw[21]; uint8_t addr_raw[21];
if (!ecdsa_address_decode(msg->address, addr_raw)) { if (!ecdsa_address_decode(msg->address, addr_raw)) {
fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address"); 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); layoutVerifyAddress(msg->address);
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) { if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Message verification cancelled"); fsm_sendFailure(FailureType_Failure_ActionCancelled, "Message verification cancelled");
@ -747,7 +750,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
uint8_t digest[64]; uint8_t digest[64];
sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest); 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); 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) { if (result == 0) {

View File

@ -56,6 +56,7 @@ SignMessage.coin_name max_size:17
VerifyMessage.address max_size:36 VerifyMessage.address max_size:36
VerifyMessage.signature max_size:65 VerifyMessage.signature max_size:65
VerifyMessage.message max_size:1024 VerifyMessage.message max_size:1024
VerifyMessage.coin_name max_size:17
MessageSignature.address max_size:36 MessageSignature.address max_size:36
MessageSignature.signature max_size:65 MessageSignature.signature max_size:65

View File

@ -9,6 +9,7 @@ const uint32_t ResetDevice_strength_default = 256u;
const char ResetDevice_language_default[17] = "english"; const char ResetDevice_language_default[17] = "english";
const char RecoveryDevice_language_default[17] = "english"; const char RecoveryDevice_language_default[17] = "english";
const char SignMessage_coin_name_default[17] = "Bitcoin"; 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 EncryptMessage_coin_name_default[17] = "Bitcoin";
const char EstimateTxSize_coin_name_default[17] = "Bitcoin"; const char EstimateTxSize_coin_name_default[17] = "Bitcoin";
const char SignTx_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 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( 1, STRING , OPTIONAL, STATIC , FIRST, VerifyMessage, address, address, 0),
PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, signature, 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( 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 PB_LAST_FIELD
}; };

View File

@ -634,6 +634,8 @@ typedef struct _VerifyMessage {
VerifyMessage_signature_t signature; VerifyMessage_signature_t signature;
bool has_message; bool has_message;
VerifyMessage_message_t message; VerifyMessage_message_t message;
bool has_coin_name;
char coin_name[17];
} VerifyMessage; } VerifyMessage;
typedef struct _WordAck { typedef struct _WordAck {
@ -647,6 +649,7 @@ extern const uint32_t ResetDevice_strength_default;
extern const char ResetDevice_language_default[17]; extern const char ResetDevice_language_default[17];
extern const char RecoveryDevice_language_default[17]; extern const char RecoveryDevice_language_default[17];
extern const char SignMessage_coin_name_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 EncryptMessage_coin_name_default[17];
extern const char EstimateTxSize_coin_name_default[17]; extern const char EstimateTxSize_coin_name_default[17];
extern const char SignTx_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 WordRequest_init_default {0}
#define WordAck_init_default {""} #define WordAck_init_default {""}
#define SignMessage_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, "Bitcoin"} #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 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 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}}} #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 WordRequest_init_zero {0}
#define WordAck_init_zero {""} #define WordAck_init_zero {""}
#define SignMessage_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, ""} #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 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 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}}} #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_address_tag 1
#define VerifyMessage_signature_tag 2 #define VerifyMessage_signature_tag 2
#define VerifyMessage_message_tag 3 #define VerifyMessage_message_tag 3
#define VerifyMessage_coin_name_tag 4
#define WordAck_word_tag 1 #define WordAck_word_tag 1
/* Struct field encoding specification for nanopb */ /* 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 WordRequest_fields[1];
extern const pb_field_t WordAck_fields[2]; extern const pb_field_t WordAck_fields[2];
extern const pb_field_t SignMessage_fields[4]; 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 MessageSignature_fields[3];
extern const pb_field_t EncryptMessage_fields[6]; extern const pb_field_t EncryptMessage_fields[6];
extern const pb_field_t EncryptedMessage_fields[4]; 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 WordRequest_size 0
#define WordAck_size 14 #define WordAck_size 14
#define SignMessage_size 1094 #define SignMessage_size 1094
#define VerifyMessage_size 1132 #define VerifyMessage_size 1151
#define MessageSignature_size 105 #define MessageSignature_size 105
#define EncryptMessage_size 1131 #define EncryptMessage_size 1131
#define EncryptedMessage_size 1168 #define EncryptedMessage_size 1168

View File

@ -6,6 +6,7 @@ HDNodePathType.address_n max_count:8
CoinType.coin_name max_size:17 CoinType.coin_name max_size:17
CoinType.coin_shortcut max_size:9 CoinType.coin_shortcut max_size:9
CoinType.signed_message_header max_size:32
TxInputType.address_n max_count:8 TxInputType.address_n max_count:8
TxInputType.prev_hash max_size:32 TxInputType.prev_hash max_size:32

View File

@ -28,7 +28,7 @@ const pb_field_t HDNodePathType_fields[3] = {
PB_LAST_FIELD 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( 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( 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), 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( 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( 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( 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 PB_LAST_FIELD
}; };

View File

@ -79,6 +79,8 @@ typedef struct _CoinType {
uint32_t address_type_p2wpkh; uint32_t address_type_p2wpkh;
bool has_address_type_p2wsh; bool has_address_type_p2wsh;
uint32_t address_type_p2wsh; uint32_t address_type_p2wsh;
bool has_signed_message_header;
char signed_message_header[32];
} CoinType; } CoinType;
typedef struct { typedef struct {
@ -261,7 +263,7 @@ extern const uint32_t IdentityType_index_default;
/* Initializer values for message structs */ /* Initializer values for message structs */
#define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}} #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 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 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 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}}} #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 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 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 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 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 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}}} #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_p2sh_tag 5
#define CoinType_address_type_p2wpkh_tag 6 #define CoinType_address_type_p2wpkh_tag 6
#define CoinType_address_type_p2wsh_tag 7 #define CoinType_address_type_p2wsh_tag 7
#define CoinType_signed_message_header_tag 8
#define HDNodeType_depth_tag 1 #define HDNodeType_depth_tag 1
#define HDNodeType_fingerprint_tag 2 #define HDNodeType_fingerprint_tag 2
#define HDNodeType_child_num_tag 3 #define HDNodeType_child_num_tag 3
@ -342,7 +345,7 @@ extern const uint32_t IdentityType_index_default;
/* Struct field encoding specification for nanopb */ /* Struct field encoding specification for nanopb */
extern const pb_field_t HDNodeType_fields[7]; extern const pb_field_t HDNodeType_fields[7];
extern const pb_field_t HDNodePathType_fields[3]; 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 MultisigRedeemScriptType_fields[4];
extern const pb_field_t TxInputType_fields[8]; extern const pb_field_t TxInputType_fields[8];
extern const pb_field_t TxOutputType_fields[7]; 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) */ /* Maximum encoded size of messages (where known) */
#define HDNodeType_size 121 #define HDNodeType_size 121
#define HDNodePathType_size 171 #define HDNodePathType_size 171
#define CoinType_size 65 #define CoinType_size 99
#define MultisigRedeemScriptType_size 3741 #define MultisigRedeemScriptType_size 3741
#define TxInputType_size 5497 #define TxInputType_size 5497
#define TxOutputType_size 3929 #define TxOutputType_size 3929

View File

@ -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 1: since 1.0.0
// version 2: since 1.2.1 // version 2: since 1.2.1
// version 3: since 1.3.1 // version 3: since 1.3.1
// version 4: since 1.3.2 // version 4: since 1.3.2
// version 5: since 1.3.3 // version 5: since 1.3.3
// version 6: since 1.3.6 // 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)); memcpy(&storage, (void *)(FLASH_STORAGE_START + 4 + sizeof(storage_uuid)), sizeof(Storage));
if (version <= 5) { if (version <= 5) {
// convert PIN failure counter from version 5 format // 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.has_pin_failed_attempts = false;
storage.pin_failed_attempts = 0; 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) void storage_init(void)
{ {
storage_reset(); if (!storage_from_flash()) {
// if magic is ok storage_reset();
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 {
storage_reset_uuid(); storage_reset_uuid();
storage_commit(); storage_commit();
storage_clearPinArea();
} }
} }
@ -421,6 +429,15 @@ bool session_isPinCached(void)
return sessionPinCached; 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) void storage_resetPinFails(uint32_t *pinfailsptr)
{ {
flash_clear_status_flags(); flash_clear_status_flags();

View File

@ -56,6 +56,7 @@ bool storage_hasPin(void);
void storage_setPin(const char *pin); void storage_setPin(const char *pin);
void session_cachePin(void); void session_cachePin(void);
bool session_isPinCached(void); bool session_isPinCached(void);
void storage_clearPinArea(void);
void storage_resetPinFails(uint32_t *pinfailptr); void storage_resetPinFails(uint32_t *pinfailptr);
bool storage_increasePinFails(uint32_t *pinfailptr); bool storage_increasePinFails(uint32_t *pinfailptr);
uint32_t *storage_getPinFailsPtr(void); uint32_t *storage_getPinFailsPtr(void);

View File

@ -50,6 +50,7 @@ int main(void)
storage_reset(); // wipe storage if debug link storage_reset(); // wipe storage if debug link
storage_reset_uuid(); storage_reset_uuid();
storage_commit(); storage_commit();
storage_clearPinArea(); // reset PIN failures if debug link
#endif #endif
oledDrawBitmap(40, 0, &bmp_logo64); oledDrawBitmap(40, 0, &bmp_logo64);

View File

@ -53,17 +53,20 @@ static const struct usb_device_descriptor dev_descr = {
}; };
static const uint8_t hid_report_descriptor[] = { static const uint8_t hid_report_descriptor[] = {
0x06, 0x00, 0xff, // USAGE_PAGE (Reserved) 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined)
0x09, 0x01, // USAGE (1) 0x09, 0x01, // USAGE (1)
0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x01, // COLLECTION (Application)
0x09, 0x20, // USAGE (Input Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0) 0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x85, 0x3f, // REPORT_ID (63)
0x75, 0x08, // REPORT_SIZE (8) 0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x3f, // REPORT_COUNT (63) 0x95, 0x40, // REPORT_COUNT (64)
0x09, 0x01, // USAGE (1)
0x81, 0x02, // INPUT (Data,Var,Abs) 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) 0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0 // END_COLLECTION 0xc0 // END_COLLECTION
}; };

View File

@ -1,5 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
import glob import glob
import os import os
from PIL import Image from PIL import Image

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
from PIL import Image from PIL import Image
class Img(object): class Img(object):

View File

@ -1,5 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2
handlers = [ handlers = [
'hard_fault_handler', 'hard_fault_handler',
'mem_manage_handler', 'mem_manage_handler',

@ -1 +1 @@
Subproject commit 8c6401bdef92ebef7375a0e58a06af117618519d Subproject commit 36a574056deacad8943f1412c3db149750f8b163