diff --git a/Makefile.genericwallet b/Makefile.genericwallet index 225d775..e08690d 100755 --- a/Makefile.genericwallet +++ b/Makefile.genericwallet @@ -61,7 +61,7 @@ DEFINES := ST31 gcc __IO=volatile DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128 DEFINES += HAVE_BAGL HAVE_PRINTF DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -DEFINES += LEDGER_MAJOR_VERSION=1 LEDGER_MINOR_VERSION=0 LEDGER_PATCH_VERSION=2 +DEFINES += LEDGER_MAJOR_VERSION=1 LEDGER_MINOR_VERSION=0 LEDGER_PATCH_VERSION=3 # U2F DEFINES += HAVE_U2F diff --git a/src_common/ethUstream.c b/src_common/ethUstream.c index e35319a..02077c0 100644 --- a/src_common/ethUstream.c +++ b/src_common/ethUstream.c @@ -20,6 +20,7 @@ #define MAX_INT256 32 #define MAX_ADDRESS 20 +#define MAX_V 2 void initTx(txContext_t *context, cx_sha3_t *sha3, txContent_t *content, ustreamProcess_t customProcessor, void *extra) { @@ -227,12 +228,44 @@ static void processData(txContext_t *context) { } } +static void processV(txContext_t *context) { + if (context->currentFieldIsList) { + screen_printf("Invalid type for RLP_V\n"); + THROW(EXCEPTION); + } + if (context->currentFieldLength > MAX_V) { + screen_printf("Invalid length for RLP_V\n"); + THROW(EXCEPTION); + } + if (context->currentFieldPos < context->currentFieldLength) { + uint32_t copySize = + (context->commandLength < + ((context->currentFieldLength - context->currentFieldPos)) + ? context->commandLength + : context->currentFieldLength - context->currentFieldPos); + copyTxData(context, context->content->v + context->currentFieldPos, + copySize); + } + if (context->currentFieldPos == context->currentFieldLength) { + context->content->vLength = context->currentFieldLength; + context->currentField++; + context->processingField = false; + } +} + static parserStatus_e processTxInternal(txContext_t *context) { for (;;) { bool processedCustom = false; + // EIP 155 style transasction if (context->currentField == TX_RLP_DONE) { return USTREAM_FINISHED; } + // Old style transaction + if ((context->currentField == TX_RLP_V) && + (context->commandLength == 0)) { + context->content->vLength = 0; + return USTREAM_FINISHED; + } if (context->commandLength == 0) { return USTREAM_PROCESSING; } @@ -307,8 +340,13 @@ static parserStatus_e processTxInternal(txContext_t *context) { processTo(context); break; case TX_RLP_DATA: + case TX_RLP_R: + case TX_RLP_S: processData(context); break; + case TX_RLP_V: + processV(context); + break; default: screen_printf("Invalid RLP decoder context\n"); return USTREAM_FAULT; diff --git a/src_common/ethUstream.h b/src_common/ethUstream.h index bb3658f..bd05700 100644 --- a/src_common/ethUstream.h +++ b/src_common/ethUstream.h @@ -32,6 +32,9 @@ typedef enum rlpTxField_e { TX_RLP_TO, TX_RLP_VALUE, TX_RLP_DATA, + TX_RLP_V, + TX_RLP_R, + TX_RLP_S, TX_RLP_DONE } rlpTxField_e; @@ -52,6 +55,8 @@ typedef struct txContent_t { txInt256_t value; uint8_t destination[20]; uint8_t destinationLength; + uint8_t v[2]; + uint8_t vLength; } txContent_t; typedef struct txContext_t { diff --git a/src_genericwallet/main.c b/src_genericwallet/main.c index 71d404e..3a6c683 100644 --- a/src_genericwallet/main.c +++ b/src_genericwallet/main.c @@ -30,8 +30,6 @@ #include "u2f_service.h" #include "u2f_transport.h" -volatile unsigned char u2fInputBuffer[64]; -volatile unsigned char u2fOutputBuffer[64]; volatile unsigned char u2fMessageBuffer[U2F_MAX_MESSAGE_SIZE]; extern void USB_power_U2F(unsigned char enabled, unsigned char fido); @@ -1377,7 +1375,19 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) { sizeof(tmpCtx.transactionContext.hash), signature); os_memset(&privateKey, 0, sizeof(privateKey)); // Parity is present in the sequence tag in the legacy API - G_io_apdu_buffer[0] = 27 + (signature[0] & 0x01); + if (txContent.vLength == 0) { + // Legacy API + G_io_apdu_buffer[0] = 27 + (signature[0] & 0x01); + } else { + // New API + uint8_t v; + if (txContent.vLength == 1) { + v = txContent.v[0]; + } else { + v = txContent.v[1]; + } + G_io_apdu_buffer[0] = (v * 2) + 35 + (signature[0] & 0x01); + } rLength = signature[3]; sLength = signature[4 + rLength + 1]; rOffset = (rLength == 33 ? 1 : 0); @@ -1748,7 +1758,6 @@ void handleApdu(volatile unsigned int *flags, volatile unsigned int *tx) { G_io_apdu_buffer[OFFSET_LC], flags, tx); break; - default: THROW(0x6D00); break; @@ -1942,8 +1951,8 @@ __attribute__((section(".boot"))) int main(void) { #ifdef HAVE_U2F os_memset((unsigned char *)&u2fService, 0, sizeof(u2fService)); - u2fService.inputBuffer = (uint8_t *)u2fInputBuffer; - u2fService.outputBuffer = (uint8_t *)u2fOutputBuffer; + u2fService.inputBuffer = G_io_apdu_buffer; + u2fService.outputBuffer = G_io_apdu_buffer; u2fService.messageBuffer = (uint8_t *)u2fMessageBuffer; u2fService.messageBufferSize = U2F_MAX_MESSAGE_SIZE; u2f_initialize_service((u2f_service_t *)&u2fService);