Merge branch 'origin/master' into u2f

pull/25/head
Jochen Hoenicke 8 years ago
commit 8e7896456a

@ -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

@ -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',

@ -1 +1 @@
Subproject commit 8c6401bdef92ebef7375a0e58a06af117618519d
Subproject commit 36a574056deacad8943f1412c3db149750f8b163
Loading…
Cancel
Save