diff --git a/app/src/crypto_helper.c b/app/src/crypto_helper.c index 2e1bd15..9d71915 100644 --- a/app/src/crypto_helper.c +++ b/app/src/crypto_helper.c @@ -39,7 +39,7 @@ zxerr_t crypto_sha256(const uint8_t *input, uint16_t inputLen, uint8_t *output, MEMZERO(output, outputLen); #if defined(TARGET_NANOS) || defined(TARGET_NANOS2) || defined(TARGET_NANOX) || defined(TARGET_STAX) - cx_hash_sha256(input, inputLen, output, CX_SHA256_SIZE); + CHECK_CXERROR(cx_hash_sha256(input, inputLen, output, CX_SHA256_SIZE)); #else picohash_ctx_t ctx; picohash_init_sha256(&ctx); diff --git a/app/src/parser_impl.c b/app/src/parser_impl.c index d7d6f86..df0d471 100644 --- a/app/src/parser_impl.c +++ b/app/src/parser_impl.c @@ -118,7 +118,7 @@ static parser_error_t parser_get_network_id(parser_context_t *c, parser_tx_t *v) static parser_error_t parser_verify_codec(parser_context_t *ctx) { uint16_t codec = 0; - read_u16(ctx, &codec); + CHECK_ERROR(read_u16(ctx, &codec)); if (codec != 0) { return parser_invalid_codec; } diff --git a/app/src/parser_impl_common.c b/app/src/parser_impl_common.c index a840c1b..fae5607 100644 --- a/app/src/parser_impl_common.c +++ b/app/src/parser_impl_common.c @@ -48,6 +48,11 @@ static const uint32_t chain_lookup_len = sizeof(chain_lookup_table) / sizeof(cha CTX_CHECK_AVAIL((CTX), (SIZE)) \ (CTX)->offset += (SIZE); +#define CTX_CHECK_BUFFER(CTX) \ + if ((CTX) == NULL || ((CTX)->offset > (CTX)->bufferLen)) { \ + return parser_unexpected_buffer_end; \ + } + parser_error_t read_u64(parser_context_t *ctx, uint64_t *result) { if (result == NULL) { return parser_unexpected_error; @@ -109,6 +114,16 @@ parser_error_t read_u8(parser_context_t *ctx, uint8_t *result) { return parser_ok; } +parser_error_t checkAvailableBytes(parser_context_t *ctx, uint16_t buffLen) { + CTX_CHECK_AVAIL(ctx, buffLen) + return parser_ok; +} + +parser_error_t verifyContext(parser_context_t *ctx) { + CTX_CHECK_BUFFER(ctx) + return parser_ok; +} + parser_error_t verifyBytes(parser_context_t *ctx, uint16_t buffLen) { CTX_CHECK_AVAIL(ctx, buffLen) CTX_CHECK_AND_ADVANCE(ctx, buffLen) diff --git a/app/src/parser_impl_common.h b/app/src/parser_impl_common.h index 8ded570..5e7f5ba 100644 --- a/app/src/parser_impl_common.h +++ b/app/src/parser_impl_common.h @@ -26,6 +26,8 @@ parser_error_t read_u32(parser_context_t *ctx, uint32_t *result); parser_error_t read_u64(parser_context_t *ctx, uint64_t *result); parser_error_t verifyBytes(parser_context_t *ctx, uint16_t buffLen); parser_error_t readBytes(parser_context_t *ctx, uint8_t *buff, uint16_t buffLen); +parser_error_t checkAvailableBytes(parser_context_t *ctx, uint16_t buffLen); +parser_error_t verifyContext(parser_context_t *ctx); parser_error_t parser_get_chain_id(parser_context_t *c, parser_tx_t *v); parser_error_t parser_get_chain_alias(const uint8_t *blockchain_id, char *chain); diff --git a/app/src/parser_print_common.c b/app/src/parser_print_common.c index 8959b46..f98b0f5 100644 --- a/app/src/parser_print_common.c +++ b/app/src/parser_print_common.c @@ -22,8 +22,6 @@ #include "zxformat.h" #include "zxmacros.h" -#define ALPHABET_ENCODE "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - #if defined(TARGET_NANOS) || defined(TARGET_NANOS2) || defined(TARGET_NANOX) || defined(TARGET_STAX) #include "cx.h" #include "cx_sha256.h" @@ -106,10 +104,10 @@ parser_error_t printAddress(const uint8_t *pubkey, network_id_e network_id, char const char *hrp = ""; switch (network_id) { case songbird: - hrp = " song"; + hrp = "song"; break; case coston: - hrp = " costwo"; + hrp = "costwo"; break; case coston2: hrp = "costwo"; @@ -161,7 +159,7 @@ parser_error_t printNodeId(const uint8_t *nodeId, char *outVal, uint16_t outValL // Calculate SHA256 checksum uint8_t checksum[CX_SHA256_SIZE] = {0}; #if defined(TARGET_NANOS) || defined(TARGET_NANOS2) || defined(TARGET_NANOX) || defined(TARGET_STAX) - cx_hash_sha256(nodeId, NODE_ID_LEN, checksum, CX_SHA256_SIZE); + CHECK_CXERROR(cx_hash_sha256(nodeId, NODE_ID_LEN, checksum, CX_SHA256_SIZE)); #else picohash_ctx_t ctx; picohash_init_sha256(&ctx); diff --git a/app/src/tx_cchain.c b/app/src/tx_cchain.c index eb46b0a..d4474be 100644 --- a/app/src/tx_cchain.c +++ b/app/src/tx_cchain.c @@ -22,6 +22,7 @@ static parser_error_t parser_handle_cchain_export(parser_context_t *c, parser_tx_t *v) { // Get destination chain + CHECK_ERROR(checkAvailableBytes(c, BLOCKCHAIN_ID_LEN)); v->tx.c_export_tx.destination_chain = c->buffer + c->offset; if (!MEMCMP(v->tx.c_export_tx.destination_chain, v->blockchain_id, BLOCKCHAIN_ID_LEN)) { return parser_unexpected_chain; @@ -35,6 +36,7 @@ static parser_error_t parser_handle_cchain_export(parser_context_t *c, parser_tx } // Pointer to inputs + CHECK_ERROR(verifyContext(c)); v->tx.c_export_tx.evm_inputs.ins = c->buffer + c->offset; CHECK_ERROR(parse_evm_inputs(c, &v->tx.c_export_tx.evm_inputs)); @@ -46,6 +48,7 @@ static parser_error_t parser_handle_cchain_export(parser_context_t *c, parser_tx // Pointer to outputs if (v->tx.c_export_tx.secp_outs.n_outs > 0) { + CHECK_ERROR(verifyContext(c)); v->tx.c_export_tx.secp_outs.outs = c->buffer + c->offset; v->tx.c_export_tx.secp_outs.outs_offset = c->offset; CHECK_ERROR(parse_transferable_secp_output(c, &v->tx.c_export_tx.secp_outs, false)); @@ -56,6 +59,7 @@ static parser_error_t parser_handle_cchain_export(parser_context_t *c, parser_tx static parser_error_t parser_handle_cchain_import(parser_context_t *c, parser_tx_t *v) { // Get source chain + CHECK_ERROR(checkAvailableBytes(c, BLOCKCHAIN_ID_LEN)); v->tx.c_import_tx.source_chain = c->buffer + c->offset; if (!MEMCMP(v->tx.c_import_tx.source_chain, v->blockchain_id, BLOCKCHAIN_ID_LEN)) { return parser_unexpected_chain; @@ -69,6 +73,7 @@ static parser_error_t parser_handle_cchain_import(parser_context_t *c, parser_tx } // Pointer to inputs + CHECK_ERROR(verifyContext(c)); v->tx.c_import_tx.secp_inputs.ins = c->buffer + c->offset; CHECK_ERROR(parse_transferable_secp_input(c, &v->tx.c_import_tx.secp_inputs)); @@ -80,6 +85,7 @@ static parser_error_t parser_handle_cchain_import(parser_context_t *c, parser_tx // Pointer to outputs if (v->tx.c_import_tx.evm_outs.n_outs > 0) { + CHECK_ERROR(verifyContext(c)); v->tx.c_import_tx.evm_outs.outs = c->buffer + c->offset; v->tx.c_import_tx.evm_outs.outs_offset = c->offset; CHECK_ERROR(parse_evm_output(c, &v->tx.c_import_tx.evm_outs)); diff --git a/app/src/tx_pchain.c b/app/src/tx_pchain.c index c65a5fc..dbb78b8 100644 --- a/app/src/tx_pchain.c +++ b/app/src/tx_pchain.c @@ -29,6 +29,7 @@ static parser_error_t parser_base_tx(parser_context_t *c, transferable_in_secp_t // Pointer to outputs if (outputs->n_outs > 0) { + CHECK_ERROR(verifyContext(c)); outputs->outs = c->buffer + c->offset; CHECK_ERROR(parse_transferable_secp_output(c, outputs, true)); } @@ -38,6 +39,7 @@ static parser_error_t parser_base_tx(parser_context_t *c, transferable_in_secp_t // Pointer to inputs if (inputs->n_ins > 0) { + CHECK_ERROR(verifyContext(c)); inputs->ins = c->buffer + c->offset; CHECK_ERROR(parse_transferable_secp_input(c, inputs)); } @@ -57,6 +59,7 @@ parser_error_t parser_handle_p_export_tx(parser_context_t *c, parser_tx_t *v) { CHECK_ERROR(parser_base_tx(c, &v->tx.p_export_tx.base_secp_ins, &v->tx.p_export_tx.base_secp_outs)); // Get destination chain + CHECK_ERROR(checkAvailableBytes(c, BLOCKCHAIN_ID_LEN)); v->tx.p_export_tx.destination_chain = c->buffer + c->offset; if (!MEMCMP(PIC(v->tx.p_export_tx.destination_chain), v->blockchain_id, BLOCKCHAIN_ID_LEN)) { return parser_unexpected_chain; @@ -70,6 +73,7 @@ parser_error_t parser_handle_p_export_tx(parser_context_t *c, parser_tx_t *v) { } // Pointer to outputs + CHECK_ERROR(verifyContext(c)); v->tx.p_export_tx.secp_outs.outs = c->buffer + c->offset; v->tx.p_export_tx.secp_outs.outs_offset = c->offset; CHECK_ERROR(parse_transferable_secp_output(c, &v->tx.p_export_tx.secp_outs, true)); @@ -82,6 +86,7 @@ parser_error_t parser_handle_p_import_tx(parser_context_t *c, parser_tx_t *v) { CHECK_ERROR(parser_base_tx(c, &v->tx.p_import_tx.base_secp_ins, &v->tx.p_import_tx.base_secp_outs)); // Get source chain + CHECK_ERROR(checkAvailableBytes(c, BLOCKCHAIN_ID_LEN)); v->tx.p_import_tx.source_chain = c->buffer + c->offset; if (!MEMCMP(v->tx.p_import_tx.source_chain, v->blockchain_id, BLOCKCHAIN_ID_LEN)) { return parser_unexpected_chain; @@ -95,6 +100,7 @@ parser_error_t parser_handle_p_import_tx(parser_context_t *c, parser_tx_t *v) { } // Pointer to inputs + CHECK_ERROR(verifyContext(c)); v->tx.p_import_tx.secp_ins.ins = c->buffer + c->offset; v->tx.p_import_tx.secp_ins.ins_offset = c->offset; CHECK_ERROR(parse_transferable_secp_input(c, &v->tx.p_import_tx.secp_ins)); @@ -107,6 +113,7 @@ parser_error_t parser_handle_add_delegator_validator(parser_context_t *c, parser CHECK_ERROR(parser_base_tx(c, &v->tx.add_del_val_tx.base_secp_ins, &v->tx.add_del_val_tx.base_secp_outs)); // Node ID + CHECK_ERROR(verifyContext(c)); v->tx.add_del_val_tx.node_id = c->buffer + c->offset; CHECK_ERROR(verifyBytes(c, NODE_ID_LEN)); @@ -130,6 +137,7 @@ parser_error_t parser_handle_add_delegator_validator(parser_context_t *c, parser } // Pointer to outputs + CHECK_ERROR(verifyContext(c)); v->tx.add_del_val_tx.staked_outs.outs = c->buffer + c->offset; CHECK_ERROR(parse_transferable_secp_output(c, &v->tx.add_del_val_tx.staked_outs, false)); @@ -138,6 +146,7 @@ parser_error_t parser_handle_add_delegator_validator(parser_context_t *c, parser } // Pointer to owners output + CHECK_ERROR(verifyContext(c)); v->tx.add_del_val_tx.owners_out.outs = c->buffer + c->offset; v->tx.add_del_val_tx.owners_out.n_outs = 1; CHECK_ERROR(parse_secp_owners_output(c, &v->tx.add_del_val_tx.owners_out)); diff --git a/docs/APDUSPEC.md b/docs/APDUSPEC.md index b7331c8..ab492a2 100644 --- a/docs/APDUSPEC.md +++ b/docs/APDUSPEC.md @@ -54,7 +54,7 @@ The general structure of commands and responses is as follows: | INS | byte (1) | Instruction ID | 0x00 | | P1 | byte (1) | Parameter 1 | ignored | | P2 | byte (1) | Parameter 2 | ignored | -| L | byte (1) | Bytes in payload | 0x0 | +| L | byte (1) | Bytes in payload | 0 | #### Response