From 236ca1ae830d3c0b7fd9755a1286141484e0b567 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sat, 27 Apr 2019 16:15:35 +0200 Subject: [PATCH] legacy: enable Bitcoin only firmware --- .gitlab-ci.yml | 10 +++++++ common/defs/support.json | 4 +-- common/tools/cointool.py | 19 ++++++++++-- legacy/Makefile.include | 8 +++++ legacy/firmware/Makefile | 27 +++++++++++++---- legacy/firmware/fsm.c | 18 ++++++++---- legacy/firmware/fsm_msg_common.h | 2 ++ legacy/firmware/layout2.c | 8 +++++ legacy/firmware/protob/Makefile | 8 ++++- legacy/firmware/usb.c | 50 +++++++++++++++++++++++++------- 10 files changed, 127 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 87cc868ee..793a997aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -100,6 +100,16 @@ build legacy firmware debug: - pipenv run make -C bootloader - pipenv run make -C demo +build legacy firmware bitcoinonly: + stage: build + variables: + BITCOIN_ONLY: "1" + script: + - cd legacy + - pipenv run script/cibuild + - pipenv run make -C bootloader + - pipenv run make -C demo + build legacy emu: stage: build variables: diff --git a/common/defs/support.json b/common/defs/support.json index ec5beba31..65de9178b 100644 --- a/common/defs/support.json +++ b/common/defs/support.json @@ -127,7 +127,7 @@ "bitcoin:POLIS": "soon", "bitcoin:PTC": "1.7.1", "bitcoin:QTUM": "1.8.1", - "bitcoin:REGTEST": "soon", + "bitcoin:REGTEST": "1.8.2", "bitcoin:RVN": "1.7.2", "bitcoin:SMART": "1.7.1", "bitcoin:TAZ": "1.6.2", @@ -1474,7 +1474,7 @@ "bitcoin:POLIS": "soon", "bitcoin:PTC": "2.0.8", "bitcoin:QTUM": "2.1.1", - "bitcoin:REGTEST": "soon", + "bitcoin:REGTEST": "2.1.2", "bitcoin:RVN": "2.0.10", "bitcoin:SMART": "2.0.8", "bitcoin:TAZ": "2.0.7", diff --git a/common/tools/cointool.py b/common/tools/cointool.py index 98ba22076..706d1bf72 100755 --- a/common/tools/cointool.py +++ b/common/tools/cointool.py @@ -209,7 +209,7 @@ def check_btc(coins): for coin in bucket: name = coin["name"] prefix = "" - if name.endswith("Testnet"): + if name.endswith("Testnet") or name.endswith("Regtest"): color = "green" elif name == "Bitcoin": color = "red" @@ -232,7 +232,12 @@ def check_btc(coins): """ failed = False for key, bucket in buckets.items(): - mainnets = [c for c in bucket if not c["name"].endswith("Testnet")] + mainnets = [ + c + for c in bucket + if not c["name"].endswith("Testnet") + and not c["name"].endswith("Regtest") + ] have_bitcoin = False for coin in mainnets: @@ -778,8 +783,9 @@ def coindefs(outfile): @click.argument("paths", metavar="[path]...", nargs=-1) @click.option("-o", "--outfile", type=click.File("w"), help="Alternate output file") @click.option("-v", "--verbose", is_flag=True, help="Print rendered file names") +@click.option("-b", "--bitcoin-only", is_flag=True, help="Accept only Bitcoin coins") # fmt: on -def render(paths, outfile, verbose): +def render(paths, outfile, verbose, bitcoin_only): """Generate source code from Mako templates. For every "foo.bar.mako" filename passed, runs the template and @@ -800,6 +806,13 @@ def render(paths, outfile, verbose): defs = coin_info.coin_info() support_info = coin_info.support_info(defs) + if bitcoin_only: + defs["bitcoin"] = [ + x + for x in defs["bitcoin"] + if x["coin_name"] in ("Bitcoin", "Testnet", "Regtest") + ] + # munch dicts - make them attribute-accessible for key, value in defs.items(): defs[key] = [Munch(coin) for coin in value] diff --git a/legacy/Makefile.include b/legacy/Makefile.include index 029dddae7..c2a96e254 100644 --- a/legacy/Makefile.include +++ b/legacy/Makefile.include @@ -132,6 +132,14 @@ LDLIBS += -lopencm3_stm32f2 LIBDEPS += $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a endif +ifeq ($(BITCOIN_ONLY), 1) +CFLAGS += -DBITCOIN_ONLY=1 +CFLAGS += -DU2F_ENABLED=0 +else +CFLAGS += -DBITCOIN_ONLY=0 +CFLAGS += -DU2F_ENABLED=1 +endif + ifeq ($(MEMORY_PROTECT), 0) CFLAGS += -DMEMORY_PROTECT=0 $(info MEMORY_PROTECT=0) diff --git a/legacy/firmware/Makefile b/legacy/firmware/Makefile index 9e34ef843..41ac8fb99 100644 --- a/legacy/firmware/Makefile +++ b/legacy/firmware/Makefile @@ -11,7 +11,6 @@ OBJS += otp.o OBJS += header.o endif -OBJS += u2f.o OBJS += messages.o OBJS += config.o OBJS += trezor.o @@ -26,12 +25,19 @@ OBJS += recovery.o OBJS += reset.o OBJS += signing.o OBJS += crypto.o + +ifeq ($(U2F_ENABLED),1) +OBJS += u2f.o +endif + +ifeq ($(BITCOIN_ONLY),0) OBJS += ethereum.o OBJS += ethereum_tokens.o +OBJS += lisk.o OBJS += nem2.o OBJS += nem_mosaics.o OBJS += stellar.o -OBJS += lisk.o +endif OBJS += debug.o @@ -98,11 +104,13 @@ OBJS += protob/messages-bitcoin.pb.o OBJS += protob/messages-common.pb.o OBJS += protob/messages-crypto.pb.o OBJS += protob/messages-debug.pb.o -OBJS += protob/messages-ethereum.pb.o OBJS += protob/messages-management.pb.o +ifeq ($(BITCOIN_ONLY),0) +OBJS += protob/messages-ethereum.pb.o +OBJS += protob/messages-lisk.pb.o OBJS += protob/messages-nem.pb.o OBJS += protob/messages-stellar.pb.o -OBJS += protob/messages-lisk.pb.o +endif OPTFLAGS ?= -Os @@ -122,13 +130,20 @@ CFLAGS += -I../vendor/nanopb -Iprotob -DPB_FIELD_16BIT=1 CFLAGS += -DDEBUG_LINK=$(DEBUG_LINK) CFLAGS += -DDEBUG_LOG=$(DEBUG_LOG) CFLAGS += -DSCM_REVISION='"$(shell git rev-parse HEAD | sed 's:\(..\):\\x\1:g')"' +CFLAGS += -DUSE_MONERO=0 +ifeq ($(BITCOIN_ONLY),0) CFLAGS += -DUSE_ETHEREUM=1 CFLAGS += -DUSE_NEM=1 -CFLAGS += -DUSE_MONERO=0 +MAKO_RENDER_FLAG = +else +CFLAGS += -DUSE_ETHEREUM=0 +CFLAGS += -DUSE_NEM=0 +MAKO_RENDER_FLAG = --bitcoin-only +endif %:: %.mako defs @printf " MAKO $@\n" - $(Q)$(PYTHON) ../vendor/trezor-common/tools/cointool.py render $@.mako + $(Q)$(PYTHON) ../vendor/trezor-common/tools/cointool.py render $(MAKO_RENDER_FLAG) $@.mako bl_data.h: bl_data.py bootloader.dat @printf " PYTHON bl_data.py\n" diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index 59f93774f..59b98a379 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -30,18 +30,14 @@ #include "curves.h" #include "debug.h" #include "ecdsa.h" -#include "ethereum.h" #include "fsm.h" #include "gettext.h" #include "hmac.h" #include "layout2.h" -#include "lisk.h" #include "memory.h" #include "memzero.h" #include "messages.h" #include "messages.pb.h" -#include "nem.h" -#include "nem2.h" #include "oled.h" #include "pinmatrix.h" #include "protect.h" @@ -51,13 +47,20 @@ #include "rng.h" #include "secp256k1.h" #include "signing.h" -#include "stellar.h" #include "supervise.h" #include "transaction.h" #include "trezor.h" #include "usb.h" #include "util.h" +#if !BITCOIN_ONLY +#include "ethereum.h" +#include "lisk.h" +#include "nem.h" +#include "nem2.h" +#include "stellar.h" +#endif + // message methods static uint8_t msg_resp[MSG_OUT_SIZE] __attribute__((aligned)); @@ -254,7 +257,12 @@ static bool fsm_layoutAddress(const char *address, const char *desc, #include "fsm_msg_common.h" #include "fsm_msg_crypto.h" #include "fsm_msg_debug.h" + +#if !BITCOIN_ONLY + #include "fsm_msg_ethereum.h" #include "fsm_msg_lisk.h" #include "fsm_msg_nem.h" #include "fsm_msg_stellar.h" + +#endif diff --git a/legacy/firmware/fsm_msg_common.h b/legacy/firmware/fsm_msg_common.h index e8c4c447d..44dece991 100644 --- a/legacy/firmware/fsm_msg_common.h +++ b/legacy/firmware/fsm_msg_common.h @@ -273,7 +273,9 @@ void fsm_msgCancel(const Cancel *msg) { (void)msg; recovery_abort(); signing_abort(); +#if !BITCOIN_ONLY ethereum_signing_abort(); +#endif fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); } diff --git a/legacy/firmware/layout2.c b/legacy/firmware/layout2.c index 61510249e..9b7d961b1 100644 --- a/legacy/firmware/layout2.c +++ b/legacy/firmware/layout2.c @@ -745,11 +745,17 @@ void layoutDecryptIdentity(const IdentityType *identity) { row_user[0] ? row_user : NULL, NULL, NULL, NULL); } +#if U2F_ENABLED + void layoutU2FDialog(const char *verb, const char *appname) { layoutDialog(&bmp_webauthn, NULL, verb, NULL, verb, _("U2F security key?"), NULL, appname, NULL, NULL); } +#endif + +#if !BITCOIN_ONLY + void layoutNEMDialog(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *address) { static char first_third[NEM_ADDRESS_SIZE / 3 + 1]; @@ -908,6 +914,8 @@ void layoutNEMLevy(const NEMMosaicDefinition *definition, uint8_t network) { } } +#endif + static inline bool is_slip18(const uint32_t *address_n, size_t address_n_count) { return address_n_count == 2 && address_n[0] == (0x80000000 + 10018) && diff --git a/legacy/firmware/protob/Makefile b/legacy/firmware/protob/Makefile index e456572d5..e1f3daced 100644 --- a/legacy/firmware/protob/Makefile +++ b/legacy/firmware/protob/Makefile @@ -2,6 +2,12 @@ ifneq ($(V),1) Q := @ endif +ifeq ($(BITCOIN_ONLY), 1) +SKIPPED_MESSAGES := Cardano Tezos Ripple Monero DebugMonero Ontology Tron Eos Binance Ethereum Lisk NEM Stellar +else +SKIPPED_MESSAGES := Cardano Tezos Ripple Monero DebugMonero Ontology Tron Eos Binance +endif + all: messages_map.h messages_map_limits.h messages-bitcoin.pb.c messages-common.pb.c messages-crypto.pb.c messages-debug.pb.c messages-ethereum.pb.c messages-management.pb.c messages-nem.pb.c messages.pb.c messages-stellar.pb.c messages-lisk.pb.c messages_nem_pb2.py PYTHON ?= python @@ -26,7 +32,7 @@ messages_%_pb2.py: messages-%.proto $(Q)protoc -I/usr/include -I. $< --python_out=. messages_map.h messages_map_limits.h: messages_map.py messages_pb2.py - $(Q)$(PYTHON) $< Cardano Tezos Ripple Monero DebugMonero Ontology Tron Eos Binance + $(Q)$(PYTHON) $< ${SKIPPED_MESSAGES} clean: rm -f *.pb *.o *.d *.pb.c *.pb.h *_pb2.py messages_map.h messages_map_limits.h diff --git a/legacy/firmware/usb.c b/legacy/firmware/usb.c index c55947e6c..a5b990d01 100644 --- a/legacy/firmware/usb.c +++ b/legacy/firmware/usb.c @@ -25,7 +25,9 @@ #include "messages.h" #include "timer.h" #include "trezor.h" +#if U2F_ENABLED #include "u2f.h" +#endif #include "usb.h" #include "util.h" @@ -36,11 +38,19 @@ #define USB_INTERFACE_INDEX_MAIN 0 #if DEBUG_LINK #define USB_INTERFACE_INDEX_DEBUG 1 +#if U2F_ENABLED #define USB_INTERFACE_INDEX_U2F 2 #define USB_INTERFACE_COUNT 3 #else +#define USB_INTERFACE_COUNT 2 +#endif +#else +#if U2F_ENABLED #define USB_INTERFACE_INDEX_U2F 1 #define USB_INTERFACE_COUNT 2 +#else +#define USB_INTERFACE_COUNT 1 +#endif #endif #define ENDPOINT_ADDRESS_MAIN_IN (0x81) @@ -49,8 +59,10 @@ #define ENDPOINT_ADDRESS_DEBUG_IN (0x82) #define ENDPOINT_ADDRESS_DEBUG_OUT (0x02) #endif +#if U2F_ENABLED #define ENDPOINT_ADDRESS_U2F_IN (0x83) #define ENDPOINT_ADDRESS_U2F_OUT (0x03) +#endif #define USB_STRINGS \ X(MANUFACTURER, "SatoshiLabs") \ @@ -88,6 +100,8 @@ static const struct usb_device_descriptor dev_descr = { .bNumConfigurations = 1, }; +#if U2F_ENABLED + static const uint8_t hid_report_descriptor_u2f[] = { 0x06, 0xd0, 0xf1, // USAGE_PAGE (FIDO Alliance) 0x09, 0x01, // USAGE (U2F HID Authenticator Device) @@ -160,7 +174,10 @@ static const struct usb_interface_descriptor hid_iface_u2f[] = {{ .extralen = sizeof(hid_function_u2f), }}; +#endif + #if DEBUG_LINK + static const struct usb_endpoint_descriptor webusb_endpoints_debug[2] = { { .bLength = USB_DT_ENDPOINT_SIZE, @@ -241,10 +258,12 @@ static const struct usb_interface ifaces[] = { .num_altsetting = 1, .altsetting = webusb_iface_debug, #endif +#if U2F_ENABLED }, { .num_altsetting = 1, .altsetting = hid_iface_u2f, +#endif }}; static const struct usb_config_descriptor config = { @@ -259,6 +278,8 @@ static const struct usb_config_descriptor config = { .interface = ifaces, }; +#if U2F_ENABLED + static enum usbd_request_return_codes hid_control_request( usbd_device *dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, usbd_control_complete_callback *complete) { @@ -277,6 +298,17 @@ static enum usbd_request_return_codes hid_control_request( return 1; } +static void u2f_rx_callback(usbd_device *dev, uint8_t ep) { + (void)ep; + static CONFIDENTIAL uint8_t buf[64] __attribute__((aligned(4))); + + debugLog(0, "", "u2f_rx_callback"); + if (usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_U2F_OUT, buf, 64) != 64) return; + u2fhid_read(tiny, (const U2FHID_FRAME *)(void *)buf); +} + +#endif + static volatile char tiny = 0; static void main_rx_callback(usbd_device *dev, uint8_t ep) { @@ -292,16 +324,8 @@ static void main_rx_callback(usbd_device *dev, uint8_t ep) { } } -static void u2f_rx_callback(usbd_device *dev, uint8_t ep) { - (void)ep; - static CONFIDENTIAL uint8_t buf[64] __attribute__((aligned(4))); - - debugLog(0, "", "u2f_rx_callback"); - if (usbd_ep_read_packet(dev, ENDPOINT_ADDRESS_U2F_OUT, buf, 64) != 64) return; - u2fhid_read(tiny, (const U2FHID_FRAME *)(void *)buf); -} - #if DEBUG_LINK + static void debug_rx_callback(usbd_device *dev, uint8_t ep) { (void)ep; static uint8_t buf[64] __attribute__((aligned(4))); @@ -314,6 +338,7 @@ static void debug_rx_callback(usbd_device *dev, uint8_t ep) { msg_read_tiny(buf, 64); } } + #endif static void set_config(usbd_device *dev, uint16_t wValue) { @@ -323,20 +348,23 @@ static void set_config(usbd_device *dev, uint16_t wValue) { 0); usbd_ep_setup(dev, ENDPOINT_ADDRESS_MAIN_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, main_rx_callback); +#if U2F_ENABLED usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); usbd_ep_setup(dev, ENDPOINT_ADDRESS_U2F_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, u2f_rx_callback); +#endif #if DEBUG_LINK usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_IN, USB_ENDPOINT_ATTR_INTERRUPT, 64, 0); usbd_ep_setup(dev, ENDPOINT_ADDRESS_DEBUG_OUT, USB_ENDPOINT_ATTR_INTERRUPT, 64, debug_rx_callback); #endif - +#if U2F_ENABLED usbd_register_control_callback( dev, USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, hid_control_request); +#endif } static usbd_device *usbd_dev = NULL; @@ -381,12 +409,14 @@ void usbPoll(void) { 64) { } } +#if U2F_ENABLED data = u2f_out_data(); if (data) { while (usbd_ep_write_packet(usbd_dev, ENDPOINT_ADDRESS_U2F_IN, data, 64) != 64) { } } +#endif #if DEBUG_LINK // write pending debug data data = msg_debug_out_data();