Skip to content

Commit

Permalink
big UI refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
jleni committed Mar 21, 2019
1 parent 2f814fc commit 4d3896b
Show file tree
Hide file tree
Showing 11 changed files with 539 additions and 227 deletions.
23 changes: 22 additions & 1 deletion docs/APDUSPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ All other packets/chunks should contain message to sign

--------------

### PUBLIC_KEY_SECP256K1_SHOWBECH32
### INS_SHOW_ADDR_SECP256K1

#### Command

Expand All @@ -154,3 +154,24 @@ All other packets/chunks should contain message to sign
| Path[PL-1] | byte (4) | Derivation Path Data | |

First three items in the derivation path will be hardened automatically hardened

### INS_GET_ADDR_SECP256K1

#### Command

| Field | Type | Content | Expected |
|------------|----------------|------------------------|--------------|
| CLA | byte (1) | Application Identifier | 0x55 |
| INS | byte (1) | Instruction ID | 0x04 |
| P1 | byte (1) | Parameter 1 | ignored |
| P2 | byte (1) | Parameter 2 | ignored |
| L | byte (1) | Bytes in payload | (depends) |
| HRP_LEN | byte(1) | Bech32 HRP Length | 1<=HRP_LEN<=83 |
| HRP | byte (HRP_LEN) | Bech32 HRP | |
| PL | byte (1) | Derivation Path Length | 3<=PL<=10 |
| Path[0] | byte (4) | Derivation Path Data | 44 |
| Path[1] | byte (4) | Derivation Path Data | 118 |
| .. | byte (4) | Derivation Path Data | |
| Path[PL-1] | byte (4) | Derivation Path Data | |

First three items in the derivation path will be hardened automatically hardened
168 changes: 102 additions & 66 deletions src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,22 @@ bool extractBip32(uint8_t *depth, uint32_t path[10], uint32_t rx, uint32_t offse
if (rx < req_offset || *depth > 10) {
return 0;
}

memcpy(path, G_io_apdu_buffer + offset + 1, *depth * 4);
return 1;
}

bool validateCosmosPath(uint8_t depth, uint32_t path[10]) {
// Only paths in the form 44'/118'/{account}'/0/{index} are supported
if (bip32_depth != 5) {
return 0;
}
if (path[0] != 0x8000002c || path[1] != 0x80000076 || path[3] != 0) {
return 0;
}
return 1;
}

bool extractHRP(uint8_t *len, char *hrp, uint32_t rx, uint32_t offset) {
if (rx < offset + 1) {
THROW(APDU_CODE_DATA_INVALID);
Expand Down Expand Up @@ -189,7 +201,7 @@ bool process_chunk(volatile uint32_t *tx, uint32_t rx, bool getBip32) {

//region View Transaction Handlers

int getTxData(
int tx_getData(
char *title, int max_title_length,
char *key, int max_key_length,
char *value, int max_value_length,
Expand Down Expand Up @@ -220,6 +232,53 @@ int getTxData(
return 0;
}

void tx_accept_sign() {
// Generate keys
cx_ecfp_public_key_t publicKey;
cx_ecfp_private_key_t privateKey;
uint8_t privateKeyData[32];

unsigned int length = 0;
int result = 0;
switch (current_sigtype) {
case SECP256K1:
os_perso_derive_node_bip32(
CX_CURVE_256K1,
bip32_path, bip32_depth,
privateKeyData, NULL);

keys_secp256k1(&publicKey, &privateKey, privateKeyData);
memset(privateKeyData, 0, 32);

result = sign_secp256k1(
transaction_get_buffer(),
transaction_get_buffer_length(),
G_io_apdu_buffer,
IO_APDU_BUFFER_SIZE,
&length,
&privateKey);
break;
default:
THROW(APDU_CODE_INS_NOT_SUPPORTED);
break;
}
if (result == 1) {
set_code(G_io_apdu_buffer, length, APDU_CODE_OK);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, length + 2);
view_display_signing_success();
} else {
set_code(G_io_apdu_buffer, length, APDU_CODE_SIGN_VERIFY_ERROR);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, length + 2);
view_display_signing_error();
}
}

void tx_reject() {
set_code(G_io_apdu_buffer, 0, APDU_CODE_COMMAND_NOT_ALLOWED);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
view_idle(0);
}

//endregion

//region View Address Handlers
Expand All @@ -241,14 +300,13 @@ void get_pk_compressed(uint8_t *pkc) {
memcpy(pkc, publicKey.W, PK_COMPRESSED_LEN);
}

int getAddrData(
char *title, int max_title_length,
char *key, int max_key_length,
char *value, int max_value_length,
int page_index,
int chunk_index,
int *page_count_out,
int *chunk_count_out) {
int addr_getData(char *title, int max_title_length,
char *key, int max_key_length,
char *value, int max_value_length,
int page_index,
int chunk_index,
int *page_count_out,
int *chunk_count_out) {

*page_count_out = 0x7FFFFFFF;
*chunk_count_out = 1;
Expand All @@ -271,6 +329,12 @@ int getAddrData(
return 0;
}

void addr_accept() {
}

void addr_reject() {
}

//endregion

void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
Expand All @@ -290,8 +354,7 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {

switch (G_io_apdu_buffer[OFFSET_INS]) {
case INS_GET_VERSION: {
unsigned int UX_ALLOWED = (ux.params.len != BOLOS_UX_IGNORE && \
ux.params.len != BOLOS_UX_CONTINUE); \
unsigned int UX_ALLOWED = (ux.params.len != BOLOS_UX_IGNORE && ux.params.len != BOLOS_UX_CONTINUE);

#ifdef TESTING_ENABLED
G_io_apdu_buffer[0] = 0xFF;
Expand All @@ -313,6 +376,10 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
THROW(APDU_CODE_DATA_INVALID);
}

if (!validateCosmosPath(bip32_depth, bip32_path)) {
THROW(APDU_CODE_DATA_INVALID);
}

cx_ecfp_public_key_t publicKey;
getPubKey(&publicKey);

Expand All @@ -332,14 +399,33 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
THROW(APDU_CODE_DATA_INVALID);
}

if (bip32_depth != 5) {
// Only paths in the form 44'/118'/{account}'/0/{index} are supported
if (!validateCosmosPath(bip32_depth, bip32_path)) {
THROW(APDU_CODE_DATA_INVALID);
}

view_set_handlers(addr_getData, addr_accept, addr_reject);
view_addr_confirm(bip32_path[4] & 0x7FFFFFF);

*flags |= IO_ASYNCH_REPLY;
}

case INS_GET_ADDR_SECP256K1: {
// Parse arguments
if (!extractHRP(&bech32_hrp_len, bech32_hrp, rx, OFFSET_DATA)) {
THROW(APDU_CODE_DATA_INVALID);
}

if (!extractBip32(&bip32_depth, bip32_path, rx, OFFSET_DATA + bech32_hrp_len + 1)) {
THROW(APDU_CODE_DATA_INVALID);
}

if (!validateCosmosPath(bip32_depth, bip32_path)) {
THROW(APDU_CODE_DATA_INVALID);
}

view_addr_show(bip32_path[4] & 0x7FFFFFF);
view_set_handlers(addr_getData, NULL, NULL);
view_addr_confirm(bip32_path[4] & 0x7FFFFFF);

//// THROW(APDU_CODE_OK);
*flags |= IO_ASYNCH_REPLY;
}

Expand All @@ -356,8 +442,8 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
THROW(APDU_CODE_BAD_KEY_HANDLE);
}

view_set_handlers(tx_getData, tx_accept_sign, tx_reject);
view_tx_show(0);
//view_display_tx_menu(0);

*flags |= IO_ASYNCH_REPLY;
break;
Expand Down Expand Up @@ -449,62 +535,12 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
END_TRY;
}

void reject_transaction() {
set_code(G_io_apdu_buffer, 0, APDU_CODE_COMMAND_NOT_ALLOWED);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
view_idle(0);
}

void sign_transaction() {
// Generate keys
cx_ecfp_public_key_t publicKey;
cx_ecfp_private_key_t privateKey;
uint8_t privateKeyData[32];

unsigned int length = 0;
int result = 0;
switch (current_sigtype) {
case SECP256K1:
os_perso_derive_node_bip32(
CX_CURVE_256K1,
bip32_path, bip32_depth,
privateKeyData, NULL);

keys_secp256k1(&publicKey, &privateKey, privateKeyData);
memset(privateKeyData, 0, 32);

result = sign_secp256k1(
transaction_get_buffer(),
transaction_get_buffer_length(),
G_io_apdu_buffer,
IO_APDU_BUFFER_SIZE,
&length,
&privateKey);
break;
default:
THROW(APDU_CODE_INS_NOT_SUPPORTED);
break;
}
if (result == 1) {
set_code(G_io_apdu_buffer, length, APDU_CODE_OK);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, length + 2);
view_display_signing_success();
} else {
set_code(G_io_apdu_buffer, length, APDU_CODE_SIGN_VERIFY_ERROR);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, length + 2);
view_display_signing_error();
}
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"

void app_main() {
volatile uint32_t rx = 0, tx = 0, flags = 0;

view_set_tx_event_handlers(&getTxData, &sign_transaction, &reject_transaction);
view_set_addr_event_handlers(&getAddrData);

for (;;) {
volatile uint16_t sw = 0;

Expand Down
3 changes: 2 additions & 1 deletion src/app_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
#define OFFSET_DATA 5 //< Data offset

#define INS_GET_VERSION 0
#define INS_PUBLIC_KEY_SECP256K1 1
#define INS_PUBLIC_KEY_SECP256K1 1 // Deprecated
#define INS_SIGN_SECP256K1 2
#define INS_SHOW_ADDR_SECP256K1 3
#define INS_GET_ADDR_SECP256K1 4

#ifdef TESTING_ENABLED
#define INS_HASH_TEST 100
Expand Down
Loading

0 comments on commit 4d3896b

Please sign in to comment.