Skip to content

Commit

Permalink
Dev v1.0.9 (#85)
Browse files Browse the repository at this point in the history
* Display a brick warning when 3 PIN attempts left (#78)

Signed-off-by: eupn <[email protected]>

* PASS1-192 & PASS1-206 (#79)

* PASS1-192: Update trezor-firmware

Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>

* fixup! PASS1-192: Update trezor-firmware

* PASS1-192: Update build in order to use new trezor-firmware

Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>

* PASS1-206: Address verification fixes

- Fixed verify address in wallet pairing flow
- Fixed verify address menu for legacy addresses

* PASS1-206: More fixes for address verification

Added missing testnet prefixes
Some bitcoin addresses wrapped badly with 16 characters across, so just limit all to 14 characters per line

Co-authored-by: Jean-Pierre De Jesus DIAZ <[email protected]>

* Improve SE startup timing (#83)

Co-authored-by: eupn <[email protected]>

* PASS1-225: Casa integration changes (#84)

* PASS1-225: Casa integration changes

* PASS1-225: Remove Envoy; add assert back

* PASS1-225: Fix error message

* PASS1-225: Same SE delay for bootloader and firmware

Co-authored-by: eupn <[email protected]>
Co-authored-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Co-authored-by: eupn <[email protected]>
  • Loading branch information
4 people authored Apr 19, 2022
1 parent 4268b2e commit bbb7fca
Show file tree
Hide file tree
Showing 12,509 changed files with 4,440,992 additions and 72,118 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
4 changes: 2 additions & 2 deletions ports/stm32/Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ init: deps

# Lint only the python code of the project
lint-py:
pycodestyle --exclude trezor-firmware --statistics .
pycodestyle --exclude trezor-firmware,graphics.py --statistics boards/Passport

# Lint only the C code of the project
lint-c:
Expand All @@ -33,7 +33,7 @@ lint: lint-code lint-license
#

build:
make BOARD=Passport
make BOARD=Passport -j$(nproc)

# Sign current firmware build with the user.pem key and set specified version
sign version="1.0.0": build
Expand Down
6 changes: 6 additions & 0 deletions ports/stm32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,12 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_USBDEV:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
OBJ += $(BUILD)/pins_$(BOARD).o

# secp256k1-zkp ARM assembly.
# NOTE: this is done here because the assembly and the flag from the Unix and
# STM32 ports differ.
OBJ += $(SECP256K1_DIR)/src/asm/field_10x26_arm.o
CFLAGS += -DUSE_EXTERNAL_ASM -DSECP256K1_CONTEXT_SIZE=184

# This file contains performance critical functions so turn up the optimisation
# level. It doesn't add much to the code size and improves performance a bit.
# Don't use -O3 with this file because gcc tries to optimise memset in terms of itself.
Expand Down
4 changes: 2 additions & 2 deletions ports/stm32/boards/Passport/bootloader/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ static inline secresult is_se_programmed(void)
uint8_t config[128] = {0};

rc = se_config_read(config);
if (rc < 0)
if (rc < 0) {
LOCKUP_FOREVER(); /* Can't talk to the SE */

}
if ((config[86] != 0x55) && (config[87] != 0x55))
return SEC_TRUE;
return SEC_FALSE;
Expand Down
4 changes: 3 additions & 1 deletion ports/stm32/boards/Passport/bootloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ static void MPU_Config(void)
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

static void version(void)
void version(void)
{
passport_firmware_header_t *fwhdr = (passport_firmware_header_t *)FW_HDR;
char version[22] = {0};
Expand Down Expand Up @@ -444,6 +444,7 @@ int main(void)

random_boot_delay();


// Check for first-boot condition
if (flash_is_programmed() == SEC_FALSE) {
secresult result = flash_first_boot();
Expand Down Expand Up @@ -482,6 +483,7 @@ int main(void)
}
}


// Increment the boot counter
uint32_t counter_result;
if (se_add_counter(&counter_result, 1, 1) != 0) {
Expand Down
28 changes: 20 additions & 8 deletions ports/stm32/boards/Passport/common/se.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ static char *error_to_str(uint8_t error)
}
#endif /* PASSPORT_BOOTLOADER */

#define SE_BAUDRATE 230400U

void se_setup_usart(uint32_t baudrate);

uint8_t se_show_error(void)
{
uint8_t error = last_error;
Expand Down Expand Up @@ -518,14 +522,17 @@ void se_idle(void)

int se_wake(void)
{
// Set the slower baud rate for the WAKE command
// as per reference implementation
// to honor the tWLO timing parameter.
se_setup_usart(SE_BAUDRATE / 2);

// send zero (all low), delay 2.5ms
_send_byte(0x00);

#ifdef PASSPORT_BOOTLOADER
delay_us(2500);
#else
delay_us(1250);
#endif

se_setup_usart(SE_BAUDRATE);

return 0;
}
Expand Down Expand Up @@ -973,9 +980,10 @@ void se_dump_stats(void)
tmp = 0;
}

#define SE_BAUDRATE 230400U

void se_setup(void)
/**
* Sets up the USART and its speed for the secure element's Single Wire Interface (SWI).
*/
void se_setup_usart(uint32_t baudrate)
{
/*
* MY_UART is pointer to USART_Typedef struct
Expand All @@ -985,7 +993,7 @@ void se_setup(void)
uint32_t uart_clock_prescaler = 0;

/* Calculate the baud rate divisor */
uartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), SE_BAUDRATE, uart_clock_prescaler));
uartdiv = (uint16_t)(UART_DIV_SAMPLING16(HAL_RCC_GetPCLK1Freq(), baudrate, uart_clock_prescaler));

#ifdef DEV_STATS
memset(&stats, 0, sizeof(stats));
Expand Down Expand Up @@ -1039,6 +1047,10 @@ void se_setup(void)
MY_UART->CR1 |= USART_CR1_UE;
}

void se_setup(void) {
se_setup_usart(SE_BAUDRATE);
}

// Just read a one-way counter.
//
int se_get_counter(uint32_t *result, uint8_t counter_number)
Expand Down
4 changes: 2 additions & 2 deletions ports/stm32/boards/Passport/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
('data_codecs/__init__.py', 'data_codecs/data_format.py', 'data_codecs/data_decoder.py', 'data_codecs/data_encoder.py',
'data_codecs/data_sampler.py', 'data_codecs/qr_factory.py', 'data_codecs/qr_codec.py', 'data_codecs/ur1_codec.py', 'data_codecs/ur2_codec.py',
'data_codecs/multisig_config_sampler.py', 'data_codecs/psbt_txn_sampler.py', 'data_codecs/seed_sampler.py',
'data_codecs/address_sampler.py', 'data_codecs/http_sampler.py', 'data_codecs/qr_type.py'))
'data_codecs/address_sampler.py', 'data_codecs/http_sampler.py', 'data_codecs/qr_type.py', 'data_codecs/sign_message_sampler.py'))
freeze('$(MPY_DIR)/ports/stm32/boards/Passport/modules',
('wallets/sw_wallets.py', 'wallets/bluewallet.py', 'wallets/electrum.py', 'wallets/constants.py', 'wallets/utils.py',
'wallets/multisig_json.py', 'wallets/multisig_import.py', 'wallets/generic_json_wallet.py', 'wallets/sparrow.py',
'wallets/bitcoin_core.py', 'wallets/wasabi.py', 'wallets/btcpay.py', 'wallets/gordian.py', 'wallets/lily.py',
'wallets/fullynoded.py', 'wallets/dux_reserve.py', 'wallets/specter.py', 'wallets/casa.py', 'wallets/vault.py',
'wallets/caravan.py', 'wallets/simple_bitcoin_wallet.py'))
'wallets/caravan.py', 'wallets/simple_bitcoin_wallet.py', 'wallets/nunchuk.py'))
18 changes: 8 additions & 10 deletions ports/stm32/boards/Passport/modfoundation.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,10 +895,8 @@ QR_find_qr_codes(mp_obj_t self)
// printf("Data: %s\n", payload);

vstr_t vstr;
int code_len = strlen((const char*)data.payload);

vstr_init(&vstr, code_len + 1);
vstr_add_strn(&vstr, (const char*)data.payload, code_len); // Can append to vstr if necessary
vstr_init(&vstr, data.payload_len + 1);
vstr_add_strn(&vstr, (const char*)data.payload, data.payload_len); // Can append to vstr if necessary

return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
}
Expand Down Expand Up @@ -1725,23 +1723,23 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bip39_get_words_matching_prefix_obj,

#include "bip39.h"

/// def mnemonic_to_entropy(self) -> None
/// def mnemonic_to_bits(self) -> None
/// '''
/// Call trezorcrypto's mnemonic_to_entropy() C function since it's not exposed through their
/// Call trezorcrypto's mnemonic_to_bits() C function since it's not exposed through their
/// Python interface.
/// '''
STATIC mp_obj_t
bip39_mnemonic_to_entropy(mp_obj_t self, mp_obj_t mnemonic, mp_obj_t entropy)
bip39_mnemonic_to_bits(mp_obj_t self, mp_obj_t mnemonic, mp_obj_t entropy)
{
mp_check_self(mp_obj_is_str_or_bytes(mnemonic));
GET_STR_DATA_LEN(mnemonic, mnemonic_str, mnemonic_len);
mp_buffer_info_t entropy_info;
mp_get_buffer_raise(entropy, &entropy_info, MP_BUFFER_WRITE);

int len = mnemonic_to_entropy((const char*)mnemonic_str, entropy_info.buf);
int len = mnemonic_to_bits((const char*)mnemonic_str, entropy_info.buf);
return mp_obj_new_int(len);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(bip39_mnemonic_to_entropy_obj, bip39_mnemonic_to_entropy);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(bip39_mnemonic_to_bits_obj, bip39_mnemonic_to_bits);

STATIC mp_obj_t
bip39___del__(mp_obj_t self)
Expand All @@ -1754,7 +1752,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bip39___del___obj, bip39___del__);
STATIC const mp_rom_map_elem_t bip39_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_foundation) },
{ MP_ROM_QSTR(MP_QSTR_get_words_matching_prefix), MP_ROM_PTR(&bip39_get_words_matching_prefix_obj) },
{ MP_ROM_QSTR(MP_QSTR_mnemonic_to_entropy), MP_ROM_PTR(&bip39_mnemonic_to_entropy_obj) },
{ MP_ROM_QSTR(MP_QSTR_mnemonic_to_bits), MP_ROM_PTR(&bip39_mnemonic_to_bits_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&bip39___del___obj) },
};
STATIC MP_DEFINE_CONST_DICT(bip39_locals_dict, bip39_locals_dict_table);
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/boards/Passport/modtcc-codecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ STATIC mp_obj_t modtcc_bech32_encode(mp_obj_t hrp_obj, mp_obj_t segwit_version_o
size_t data_len);
*/
// printf("hrp=%s, data_len=%d\n", hrp, data_len);
int rv = bech32_encode(vstr.buf, hrp, data, data_len);
int rv = bech32_encode(vstr.buf, hrp, data, data_len, BECH32_ENCODING_BECH32);

if(rv != 1) {
mp_raise_ValueError("encode fail");
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/boards/Passport/modules/accept_terms_ux.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def show(self):
elif self.state == self.SHOW_URL_QR:
# Show QR code
url = 'https://foundationdevices.com/setup'
result = await ux_show_text_as_ur(title='Setup Guide', qr_text=url, qr_type=QRType.QR, left_btn='BACK', right_btn='NEXT')
result = await ux_show_text_as_ur(title='Setup Guide', qr_text=url, qr_type=QRType.QR, left_btn='BACK', right_btn='NEXT', is_cbor=False)
if result == 'x':
self.goto_prev()
else:
Expand Down
79 changes: 60 additions & 19 deletions ports/stm32/boards/Passport/modules/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,19 @@
# Every function here is called directly by a menu item. They should all be async.
#

import pyb
import version
import gc
from files import CardMissingError, CardSlot
# import main
from uasyncio import sleep_ms
import common
from common import settings, system, noise, dis
from utils import (UXStateMachine, imported, pretty_short_delay, xfp2str, to_str,
truncate_string_to_width, set_next_addr, get_accounts, run_chooser,
make_account_name_num, is_valid_address, save_next_addr, needs_microsd, format_btc_address,
is_all_zero, bytes_to_hex_str, split_to_lines, is_valid_btc_address, do_address_verify, run_chooser)
from wallets.utils import get_export_mode, get_addr_type_from_address, get_deriv_path_from_addr_type_and_acct
from ux import (the_ux, ux_confirm, ux_enter_pin,
ux_enter_text, ux_scan_qr_code, ux_shutdown,
get_accounts, run_chooser, make_account_name_num, needs_microsd,
is_all_zero, bytes_to_hex_str, split_to_lines, is_valid_btc_address,
do_address_verify, run_chooser)
from wallets.utils import (get_addr_type_from_deriv_path, get_addr_type_from_address,
get_deriv_path_from_addr_type_and_acct)
from ux import (the_ux, ux_confirm, ux_enter_text, ux_scan_qr_code, ux_shutdown,
ux_show_story, ux_show_story_sequence, ux_show_text_as_ur, ux_show_word_list)
from se_commands import *
from data_codecs.qr_type import QRType
Expand Down Expand Up @@ -272,7 +270,6 @@ async def show(self):
if address == None:
return

address = address.lower()
address, is_valid_btc = await is_valid_btc_address(address)
if is_valid_btc == False:
if not self.goto_prev():
Expand All @@ -286,7 +283,7 @@ async def show(self):
deriv_path = get_deriv_path_from_addr_type_and_acct(addr_type, self.acct_num, is_multisig)

result = await do_address_verify(self.acct_num, address, addr_type, deriv_path, self.multisig_wallet)
if result == 'x':
if not result:
if not self.goto_prev():
return
else:
Expand All @@ -311,10 +308,19 @@ async def update_firmware(*a):
import trezorcrypto

# Don't show any files that are pubkeys
def no_pubkeys(filename):
return not filename.endswith('-pub.bin')
def is_valid_firmware(filename, header):
if filename.endswith('-pub.bin'):
return False

result = system.validate_firmware_header(header)
return result[0]

fn = await file_picker('On the next screen, select the firmware file you want to install.', suffix='.bin', title='Select File', taster=no_pubkeys)
fn = await file_picker(
'On the next screen, select the firmware file you want to install.',
suffix='.bin',
title='Select File',
taster=is_valid_firmware,
bite_size=FW_HEADER_SIZE)
# print('\nselected fn = {}\n'.format(fn))
if not fn:
return
Expand Down Expand Up @@ -670,7 +676,7 @@ async def handle_seed_data_format(mnemonic):
return False

bip = bip39()
len = bip.mnemonic_to_entropy(mnemonic, entropy)
len = bip.mnemonic_to_bits(mnemonic, entropy)

if len == 264: # 24 words x 11 bits each
trim_pos = 32
Expand Down Expand Up @@ -698,6 +704,34 @@ async def handle_seed_data_format(mnemonic):
await goto_top_menu()
return True

async def handle_sign_message_format(data):
from common import dis
from public_constants import AF_CLASSIC
from auth import sign_msg

if data != None:
try:
parts = data.split(b'\n')
if len(parts) != 2:
await ux_show_story('Invalid message format.', title='Error', right_btn='DONE')
return False
# print('parts={}'.format(parts))
msg_to_sign = parts[0]
deriv_path_to_sign = parts[1]
# print('handle_sign_message_format signing msg: {} deriv_path: {}'.format(msg_to_sign, deriv_path_to_sign))

dis.fullscreen('Analyzing...')
system.show_busy_bar()
# TODO: determine addr_type dynamically instead of hard coded passing AF_CLASSIC
await sign_msg(msg_to_sign, deriv_path_to_sign, AF_CLASSIC)
except Exception as e:
await ux_show_story('Error signing message:\n\n{}'.format(e), title='Error', right_btn='DONE')
return False
finally:
system.hide_busy_bar()

return False

async def erase_wallet(menu, label, item):
# Erase the seed words, and private key from this wallet!
# This is super dangerous for the customer's money.
Expand Down Expand Up @@ -1003,7 +1037,7 @@ async def list_files(*a):
await ux_show_story('File:\n %s\n\n%s' % (basename, digest), title='SHA256')


async def file_picker(msg, suffix=None, min_size=None, max_size=None, taster=None, choices=None, none_msg=None, title='Select', folder_path=None):
async def file_picker(msg, suffix=None, min_size=None, max_size=None, taster=None, bite_size=None, choices=None, none_msg=None, title='Select', folder_path=None):
# present a menu w/ a list of files... to be read
# - optionally, enforce a max size, and provide a "tasting" function
# - if msg==None, don't prompt, just do the search and return list
Expand Down Expand Up @@ -1059,8 +1093,16 @@ async def file_picker(msg, suffix=None, min_size=None, max_size=None, taster=Non
continue

if taster is not None:
# Read a small amount for the taster to check if requested
if bite_size is not None:
with open(full_fname, 'rb') as fp:
# Read the bite size that the taster requested
bite = fp.read(bite_size)
try:
yummy = taster(full_fname)
if bite_size is not None:
yummy = taster(full_fname, bite)
else:
yummy = taster(full_fname)
except IOError:
# print("fail: %s" % full_fname)
yummy = False
Expand Down Expand Up @@ -1157,7 +1199,7 @@ def is_psbt(filename):
if not choices:
await ux_show_story("""\
Copy an unsigned PSBT transaction onto the microSD card and insert it into Passport.
""", title=title)
""", title=title, center=True, center_vertically=True)
return

if len(choices) == 1:
Expand Down Expand Up @@ -1591,7 +1633,7 @@ async def test_ur(*a):

async def test_ur_encoder(_1, _2, item):
await ux_show_text_as_ur(title='Test UR Encoding', msg='Animated UR Code', qr_text=b'Y\x01\x00\x91n\xc6\\\xf7|\xad\xf5\\\xd7\xf9\xcd\xa1\xa1\x03\x00&\xdd\xd4.\x90[w\xad\xc3nO-<\xcb\xa4O\x7f\x04\xf2\xdeD\xf4-\x84\xc3t\xa0\xe1I\x13o%\xb0\x18RTYa\xd5_\x7fz\x8c\xdem\x0e.\xc4?;-\xcbdJ"\t\xe8\xc9\xe3J\xf5\xc4ty\x84\xa5\xe8s\xc9\xcf_\x96^%\xee)\x03\x9f\xdf\x8c\xa7O\x1cv\x9f\xc0~\xb7\xeb\xae\xc4n\x06\x95\xae\xa6\xcb\xd6\x0b>\xc4\xbb\xff\x1b\x9f\xfe\x8a\x9er@\x12\x93w\xb9\xd3q\x1e\xd3\x8dA/\xbbDB%o\x1eoY^\x0f\xc5\x7f\xedE\x1f\xb0\xa0\x10\x1f\xb7k\x1f\xb1\xe1\xb8\x8c\xfd\xfd\xaa\x94b\x94\xa4}\xe8\xff\xf1s\xf0!\xc0\xe6\xf6[\x05\xc0\xa4\x94\xe5\x07\x91\'\n\x00P\xa7:\xe6\x9bg%PZ.\xc8\xa5y\x14W\xc9\x87m\xd3J\xad\xd1\x92\xa5:\xa0\xdcf\xb5V\xc0\xc2\x15\xc7\xce\xb8$\x8bq|"\x95\x1ee0[V\xa3pn>\x86\xeb\x01\xc8\x03\xbb\xf9\x15\xd8\x0e\xdc\xd6MM',
qr_type=QRType.UR1, qr_args=None)
qr_type=QRType.UR1, qr_args=None, is_cbor=False)

async def test_num_entry(*a):
num = await ux_enter_text('Enter Number', label='Enter an integer', num_only=True)
Expand Down Expand Up @@ -1699,7 +1741,6 @@ async def test_ur1_old(*a):
else:
print('decode_ur() failed!')


async def test_ur1(*a):
from ur1.decode_ur import decode_ur
from ur1.encode_ur import encode_ur
Expand Down
Loading

0 comments on commit bbb7fca

Please sign in to comment.