From 0100eed1fdec957b0b95d99e374f53a884bf3b5a Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Tue, 19 Jul 2022 11:04:16 +0200 Subject: [PATCH] EIP712 code now uses the global apdu response code; error handling improvements --- src_features/signMessageEIP712/context.c | 7 + src_features/signMessageEIP712/encode_field.c | 8 + src_features/signMessageEIP712/entrypoint.c | 261 ++++++++++-------- src_features/signMessageEIP712/field_hash.c | 11 +- .../format_hash_field_type.c | 15 +- src_features/signMessageEIP712/path.c | 14 +- .../signMessageEIP712/sol_typenames.c | 5 + src_features/signMessageEIP712/type_hash.c | 8 +- src_features/signMessageEIP712/ui_logic.c | 5 + 9 files changed, 207 insertions(+), 127 deletions(-) diff --git a/src_features/signMessageEIP712/context.c b/src_features/signMessageEIP712/context.c index ce56704..8d30e20 100644 --- a/src_features/signMessageEIP712/context.c +++ b/src_features/signMessageEIP712/context.c @@ -10,6 +10,9 @@ #include "path.h" #include "field_hash.h" #include "ui_logic.h" +#include "apdu_constants.h" // APDU response codes +#include "shared_context.h" // reset_app_context +#include "ui_callbacks.h" // ui_idle s_eip712_context *eip712_context = NULL; @@ -24,6 +27,7 @@ bool eip712_context_init(void) if ((eip712_context = MEM_ALLOC_AND_ALIGN_TYPE(*eip712_context)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } @@ -50,6 +54,7 @@ bool eip712_context_init(void) // set types pointer if ((eip712_context->structs_array = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } @@ -65,6 +70,8 @@ void eip712_context_deinit(void) ui_712_deinit(); mem_reset(); eip712_context = NULL; + reset_app_context(); + ui_idle(); } #endif diff --git a/src_features/signMessageEIP712/encode_field.c b/src_features/signMessageEIP712/encode_field.c index ce78a89..a4d0f2b 100644 --- a/src_features/signMessageEIP712/encode_field.c +++ b/src_features/signMessageEIP712/encode_field.c @@ -6,6 +6,7 @@ #include "mem.h" #include "eip712.h" #include "shared_context.h" +#include "apdu_constants.h" // APDU response codes typedef enum { @@ -32,6 +33,7 @@ static void *field_encode(const uint8_t *const value, if (length > EIP_712_ENCODED_FIELD_LENGTH) // sanity check { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return NULL; } if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) @@ -51,6 +53,10 @@ static void *field_encode(const uint8_t *const value, } memcpy(&padded_value[start_idx], value, length); } + else + { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; + } return padded_value; } @@ -115,6 +121,7 @@ void *encode_boolean(const bool *const value, uint8_t length) { if (length != 1) // sanity check { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return NULL; } return encode_uint((uint8_t*)value, length); @@ -131,6 +138,7 @@ void *encode_address(const uint8_t *const value, uint8_t length) { if (length != ADDRESS_LENGTH) // sanity check { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return NULL; } return encode_uint(value, length); diff --git a/src_features/signMessageEIP712/entrypoint.c b/src_features/signMessageEIP712/entrypoint.c index f568ac9..2daf964 100644 --- a/src_features/signMessageEIP712/entrypoint.c +++ b/src_features/signMessageEIP712/entrypoint.c @@ -113,7 +113,8 @@ const uint8_t *get_next_struct_field_array_lvl(const uint8_t *ptr) break; default: // should not be in here :^) - break; + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; + return NULL; } return ptr + 1; } @@ -254,6 +255,7 @@ bool set_struct_name(const uint8_t *const data) // copy length if ((length_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *length_ptr = data[OFFSET_LC]; @@ -261,6 +263,7 @@ bool set_struct_name(const uint8_t *const data) // copy name if ((name_ptr = mem_alloc(sizeof(char) * data[OFFSET_LC])) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } memmove(name_ptr, &data[OFFSET_CDATA], data[OFFSET_LC]); @@ -268,6 +271,7 @@ bool set_struct_name(const uint8_t *const data) // initialize number of fields if ((eip712_context->current_struct_fields_array = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *(eip712_context->current_struct_fields_array) = 0; @@ -295,6 +299,7 @@ bool set_struct_field(const uint8_t *const data) // copy TypeDesc if ((type_desc_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *type_desc_ptr = data[data_idx++]; @@ -305,6 +310,7 @@ bool set_struct_field(const uint8_t *const data) // copy TypeSize if ((type_size_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *type_size_ptr = data[data_idx++]; @@ -314,6 +320,7 @@ bool set_struct_field(const uint8_t *const data) // copy custom struct name length if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *typename_len_ptr = data[data_idx++]; @@ -321,6 +328,7 @@ bool set_struct_field(const uint8_t *const data) // copy name if ((typename = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } memmove(typename, &data[data_idx], *typename_len_ptr); @@ -330,6 +338,7 @@ bool set_struct_field(const uint8_t *const data) { if ((array_levels_count = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *array_levels_count = data[data_idx++]; @@ -337,6 +346,7 @@ bool set_struct_field(const uint8_t *const data) { if ((array_level = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *array_level = data[data_idx++]; @@ -347,13 +357,15 @@ bool set_struct_field(const uint8_t *const data) case ARRAY_FIXED_SIZE: if ((array_level_size = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *array_level_size = data[data_idx++]; break; default: // should not be in here :^) - break; + apdu_response_code = APDU_RESPONSE_INVALID_DATA; + return false; } } } @@ -361,6 +373,7 @@ bool set_struct_field(const uint8_t *const data) // copy length if ((fieldname_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *fieldname_len_ptr = data[data_idx++]; @@ -368,12 +381,29 @@ bool set_struct_field(const uint8_t *const data) // copy name if ((fieldname_ptr = mem_alloc(sizeof(char) * *fieldname_len_ptr)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } memmove(fieldname_ptr, &data[data_idx], *fieldname_len_ptr); return true; } +void handle_eip712_return_code(bool ret) +{ + if (ret) + { + apdu_response_code = APDU_RESPONSE_OK; + } + *(uint16_t*)G_io_apdu_buffer = __builtin_bswap16(apdu_response_code); + + // Send back the response, do not restart the event loop + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + + if (!ret) + { + eip712_context_deinit(); + } +} bool handle_eip712_struct_def(const uint8_t *const apdu_buf) { @@ -381,101 +411,77 @@ bool handle_eip712_struct_def(const uint8_t *const apdu_buf) if (eip712_context == NULL) { - if (!eip712_context_init()) - { - return false; - } - } - switch (apdu_buf[OFFSET_P2]) - { - case P2_NAME: - ret = set_struct_name(apdu_buf); - break; - case P2_FIELD: - ret = set_struct_field(apdu_buf); - break; - default: - PRINTF("Unknown P2 0x%x for APDU 0x%x\n", - apdu_buf[OFFSET_P2], - apdu_buf[OFFSET_INS]); - ret = false; + ret = eip712_context_init(); } if (ret) { - G_io_apdu_buffer[0] = 0x90; - G_io_apdu_buffer[1] = 0x00; + switch (apdu_buf[OFFSET_P2]) + { + case P2_NAME: + ret = set_struct_name(apdu_buf); + break; + case P2_FIELD: + ret = set_struct_field(apdu_buf); + break; + default: + PRINTF("Unknown P2 0x%x for APDU 0x%x\n", + apdu_buf[OFFSET_P2], + apdu_buf[OFFSET_INS]); + apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; + ret = false; + } } - else - { - G_io_apdu_buffer[0] = 0x6A; - G_io_apdu_buffer[1] = 0x80; - } - // Send back the response, do not restart the event loop - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + handle_eip712_return_code(ret); return ret; } bool handle_eip712_struct_impl(const uint8_t *const apdu_buf) { - bool ret = true; + bool ret = false; bool reply_apdu = true; - switch (apdu_buf[OFFSET_P2]) + if (eip712_context == NULL) { - case P2_NAME: - // set root type - if (path_set_root((char*)&apdu_buf[OFFSET_CDATA], - apdu_buf[OFFSET_LC])) - { - if (N_storage.verbose_eip712) + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; + } + else + { + switch (apdu_buf[OFFSET_P2]) + { + case P2_NAME: + // set root type + if ((ret = path_set_root((char*)&apdu_buf[OFFSET_CDATA], + apdu_buf[OFFSET_LC]))) + { + if (N_storage.verbose_eip712) + { + ui_712_review_struct(path_get_root()); + reply_apdu = false; + } + ui_712_field_flags_reset(); + } + break; + case P2_FIELD: + if ((ret = field_hash(&apdu_buf[OFFSET_CDATA], + apdu_buf[OFFSET_LC], + apdu_buf[OFFSET_P1] != P1_COMPLETE))) { - ui_712_review_struct(path_get_root()); reply_apdu = false; } - ui_712_field_flags_reset(); - } - else - { - ret = false; - } - break; - case P2_FIELD: - if (field_hash(&apdu_buf[OFFSET_CDATA], - apdu_buf[OFFSET_LC], - apdu_buf[OFFSET_P1] != P1_COMPLETE)) - { - reply_apdu = false; - } - else - { - ret = false; - } - break; - case P2_ARRAY: - if (!path_new_array_depth(apdu_buf[OFFSET_CDATA])) - { - ret = false; - } - break; - default: - PRINTF("Unknown P2 0x%x for APDU 0x%x\n", - apdu_buf[OFFSET_P2], - apdu_buf[OFFSET_INS]); - ret = false; + break; + case P2_ARRAY: + ret = path_new_array_depth(apdu_buf[OFFSET_CDATA]); + break; + default: + PRINTF("Unknown P2 0x%x for APDU 0x%x\n", + apdu_buf[OFFSET_P2], + apdu_buf[OFFSET_INS]); + apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; + } } if (reply_apdu) { - if (ret) - { - G_io_apdu_buffer[0] = 0x90; - G_io_apdu_buffer[1] = 0x00; - } - else - { - G_io_apdu_buffer[0] = 0x6a; - G_io_apdu_buffer[1] = 0x80; - } - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + handle_eip712_return_code(ret); } return ret; } @@ -594,6 +600,7 @@ bool provide_filtering_info(const uint8_t *const payload, uint8_t length, uin { if (path_get_root_type() != ROOT_DOMAIN) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } } @@ -601,6 +608,7 @@ bool provide_filtering_info(const uint8_t *const payload, uint8_t length, uin { if (path_get_root_type() != ROOT_MESSAGE) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } } @@ -705,65 +713,74 @@ bool handle_eip712_filtering(const uint8_t *const apdu_buf) bool ret = true; bool reply_apdu = true; - switch (apdu_buf[OFFSET_P1]) + if (eip712_context == NULL) { - case P1_ACTIVATE: - if (!N_storage.verbose_eip712) - { - ui_712_set_filtering_mode(EIP712_FILTERING_FULL); - ret = compute_schema_hash(); - } - break; - case P1_CONTRACT_NAME: - case P1_FIELD_NAME: - if (ui_712_get_filtering_mode() == EIP712_FILTERING_FULL) - { - ret = provide_filtering_info(&apdu_buf[OFFSET_CDATA], - apdu_buf[OFFSET_LC], - apdu_buf[OFFSET_P1]); - if ((apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) && ret) + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; + ret = false; + } + else + { + switch (apdu_buf[OFFSET_P1]) + { + case P1_ACTIVATE: + if (!N_storage.verbose_eip712) { - reply_apdu = false; + ui_712_set_filtering_mode(EIP712_FILTERING_FULL); + ret = compute_schema_hash(); } - } - break; - default: - PRINTF("Unknown P1 0x%x for APDU 0x%x\n", - apdu_buf[OFFSET_P1], - apdu_buf[OFFSET_INS]); - ret = false; + break; + case P1_CONTRACT_NAME: + case P1_FIELD_NAME: + if (ui_712_get_filtering_mode() == EIP712_FILTERING_FULL) + { + ret = provide_filtering_info(&apdu_buf[OFFSET_CDATA], + apdu_buf[OFFSET_LC], + apdu_buf[OFFSET_P1]); + if ((apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) && ret) + { + reply_apdu = false; + } + } + break; + default: + PRINTF("Unknown P1 0x%x for APDU 0x%x\n", + apdu_buf[OFFSET_P1], + apdu_buf[OFFSET_INS]); + apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; + ret = false; + } } if (reply_apdu) { - if (ret) - { - G_io_apdu_buffer[0] = 0x90; - G_io_apdu_buffer[1] = 0x00; - } - else - { - G_io_apdu_buffer[0] = 0x6A; - G_io_apdu_buffer[1] = 0x80; - } - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + handle_eip712_return_code(ret); } return ret; } bool handle_eip712_sign(const uint8_t *const apdu_buf) { - if (parseBip32(&apdu_buf[OFFSET_CDATA], - &apdu_buf[OFFSET_LC], - &tmpCtx.messageSigningContext.bip32) == NULL) + bool ret = false; + + if (eip712_context == NULL) { - return false; + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; } - if (!N_storage.verbose_eip712 && (ui_712_get_filtering_mode() == EIP712_FILTERING_BASIC)) + else if (parseBip32(&apdu_buf[OFFSET_CDATA], + &apdu_buf[OFFSET_LC], + &tmpCtx.messageSigningContext.bip32) != NULL) { - ui_712_message_hash(); + if (!N_storage.verbose_eip712 && (ui_712_get_filtering_mode() == EIP712_FILTERING_BASIC)) + { + ui_712_message_hash(); + } + ret = true; + ui_712_end_sign(); } - ui_712_end_sign(); - return true; + if (!ret) + { + handle_eip712_return_code(ret); + } + return ret; } diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index 3289ce3..c3a4eae 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -12,6 +12,7 @@ #include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "context.h" // contract_addr #include "utils.h" // u64_from_BE +#include "apdu_constants.h" // APDU response codes static s_field_hashing *fh = NULL; @@ -21,6 +22,7 @@ bool field_hash_init(void) { if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } fh->state = FHS_IDLE; @@ -54,13 +56,14 @@ bool field_hash(const uint8_t *data, // get field by path if ((field_ptr = path_get_field()) == NULL) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } key = get_struct_field_keyname(field_ptr, &keylen); field_type = struct_field_type(field_ptr); if (fh->state == FHS_IDLE) // first packet for this frame { - fh->remaining_size = (data[0] << 8) | data[1]; // network byte order + fh->remaining_size = __builtin_bswap16(*(uint16_t*)&data[0]); // network byte order data += sizeof(uint16_t); data_length -= sizeof(uint16_t); fh->state = FHS_WAITING_FOR_MORE; @@ -85,6 +88,7 @@ bool field_hash(const uint8_t *data, { if (partial) // only makes sense if marked as complete { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } #ifdef DEBUG @@ -118,6 +122,7 @@ bool field_hash(const uint8_t *data, break; case TYPE_CUSTOM: default: + apdu_response_code = APDU_RESPONSE_INVALID_DATA; PRINTF("Unknown solidity type!\n"); return false; } @@ -132,6 +137,7 @@ bool field_hash(const uint8_t *data, { if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } // copy hash into memory @@ -167,6 +173,7 @@ bool field_hash(const uint8_t *data, { if (data_length != sizeof(eip712_context->contract_addr)) { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; PRINTF("Unexpected verifyingContract length!\n"); return false; } @@ -178,6 +185,7 @@ bool field_hash(const uint8_t *data, if (chainId != chainConfig->chainId) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; PRINTF("EIP712Domain chain ID mismatch, expected 0x%.*h, got 0x%.*h !\n", sizeof(chainConfig->chainId), &chainConfig->chainId, @@ -195,6 +203,7 @@ bool field_hash(const uint8_t *data, { if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } G_io_apdu_buffer[0] = 0x90; diff --git a/src_features/signMessageEIP712/format_hash_field_type.c b/src_features/signMessageEIP712/format_hash_field_type.c index 399ef36..b8a3892 100644 --- a/src_features/signMessageEIP712/format_hash_field_type.c +++ b/src_features/signMessageEIP712/format_hash_field_type.c @@ -5,6 +5,7 @@ #include "mem_utils.h" #include "eip712.h" #include "hash_bytes.h" +#include "apdu_constants.h" // APDU response codes /** * Format & hash a struct field typesize @@ -30,9 +31,14 @@ static bool format_hash_field_type_size(const void *const field_ptr, cx_hash_t * break; default: // should not be in here :^) + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } - uint_str_ptr = mem_alloc_and_format_uint(field_size, &uint_str_len); + if ((uint_str_ptr = mem_alloc_and_format_uint(field_size, &uint_str_len)) == NULL) + { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; + return false; + } hash_nbytes((uint8_t*)uint_str_ptr, uint_str_len, hash_ctx); mem_dealloc(uint_str_len); return true; @@ -63,12 +69,17 @@ static bool format_hash_field_type_array_levels(const void *const field_ptr, cx_ case ARRAY_DYNAMIC: break; case ARRAY_FIXED_SIZE: - uint_str_ptr = mem_alloc_and_format_uint(array_size, &uint_str_len); + if ((uint_str_ptr = mem_alloc_and_format_uint(array_size, &uint_str_len)) == NULL) + { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; + return false; + } hash_nbytes((uint8_t*)uint_str_ptr, uint_str_len, hash_ctx); mem_dealloc(uint_str_len); break; default: // should not be in here :^) + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } hash_byte(']', hash_ctx); diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 4ed05bc..e630e23 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -11,6 +11,7 @@ #include "ethUtils.h" #include "mem_utils.h" #include "ui_logic.h" +#include "apdu_constants.h" // APDU response codes static s_path *path_struct = NULL; @@ -214,10 +215,12 @@ static bool array_depth_list_push(uint8_t path_idx, uint8_t size) if (path_struct == NULL) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } if (path_struct->array_depth_count == MAX_ARRAY_DEPTH) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } @@ -345,6 +348,7 @@ bool path_set_root(const char *const struct_name, uint8_t name_length) { if (path_struct == NULL) { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } @@ -358,6 +362,7 @@ bool path_set_root(const char *const struct_name, uint8_t name_length) PRINTF("%c", struct_name[i]); } PRINTF(")!\n"); + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } @@ -366,12 +371,12 @@ bool path_set_root(const char *const struct_name, uint8_t name_length) const uint8_t *thash_ptr; if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*hash_ctx)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } cx_keccak_init(hash_ctx, 256); // init hash if ((thash_ptr = type_hash(eip712_context->structs_array, struct_name, name_length)) == NULL) { - PRINTF("Memory allocation failed!\n"); return false; } // start the progressive hash on it @@ -427,6 +432,7 @@ static bool check_and_add_array_depth(const void *depth, if (path_struct == NULL) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } arr_idx = (total_count - path_struct->array_depth_count) - 1; @@ -441,6 +447,7 @@ static bool check_and_add_array_depth(const void *depth, expected_type = struct_field_array_depth(depth, &expected_size); if ((expected_type == ARRAY_FIXED_SIZE) && (expected_size != size)) { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; PRINTF("Unexpected array depth size. (expected %d, got %d)\n", expected_size, size); return false; @@ -475,12 +482,14 @@ bool path_new_array_depth(uint8_t size) { if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } if (struct_field_is_array(field_ptr)) { if ((depth = get_struct_field_array_lvls_array(field_ptr, &depth_count)) == NULL) { + apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; return false; } total_count += depth_count; @@ -497,6 +506,7 @@ bool path_new_array_depth(uint8_t size) if (pidx == path_struct->depth_count) { + apdu_response_code = APDU_RESPONSE_INVALID_DATA; PRINTF("Did not find a matching array type.\n"); return false; } @@ -505,6 +515,7 @@ bool path_new_array_depth(uint8_t size) // memory address not aligned, padd it if ((hash_ctx = mem_alloc(sizeof(*hash_ctx))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } if (struct_field_type(field_ptr) == TYPE_CUSTOM) @@ -652,6 +663,7 @@ bool path_init(void) { if (path_struct == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; path_struct = MEM_ALLOC_AND_ALIGN_TYPE(*path_struct); } return path_struct != NULL; diff --git a/src_features/signMessageEIP712/sol_typenames.c b/src_features/signMessageEIP712/sol_typenames.c index ea1d1f2..eff24da 100644 --- a/src_features/signMessageEIP712/sol_typenames.c +++ b/src_features/signMessageEIP712/sol_typenames.c @@ -7,6 +7,7 @@ #include "context.h" #include "mem.h" #include "os_pic.h" +#include "apdu_constants.h" // APDU response codes // Bit indicating they are more types associated to this typename #define TYPENAME_MORE_TYPE (1 << 7) @@ -33,6 +34,7 @@ static bool find_enum_matches(const uint8_t (*enum_to_idx)[TYPES_COUNT - 1][IDX_ } if ((enum_match = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } *enum_match = (*enum_to_idx)[e_idx][IDX_ENUM]; @@ -77,6 +79,7 @@ bool sol_typenames_init(void) { if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } // get pointer to the allocated space just above @@ -84,6 +87,7 @@ bool sol_typenames_init(void) if ((typename_ptr = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return false; } // copy typename @@ -130,6 +134,7 @@ const char *get_struct_field_sol_typename(const uint8_t *field_ptr, if (typename_found) return (char*)typename_ptr; typename_ptr += *length; } + apdu_response_code = APDU_RESPONSE_INVALID_DATA; return NULL; // Not found } diff --git a/src_features/signMessageEIP712/type_hash.c b/src_features/signMessageEIP712/type_hash.c index fe7ca08..a4ee85b 100644 --- a/src_features/signMessageEIP712/type_hash.c +++ b/src_features/signMessageEIP712/type_hash.c @@ -11,6 +11,7 @@ #include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "format_hash_field_type.h" #include "hash_bytes.h" +#include "apdu_constants.h" // APDU response codes /** * @@ -162,6 +163,7 @@ static const void **get_struct_dependencies(const void *const structs_array, *deps_count += 1; if ((new_dep = MEM_ALLOC_AND_ALIGN_TYPE(void*)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return NULL; } if (*deps_count == 1) @@ -213,7 +215,10 @@ const uint8_t *type_hash(const void *const structs_array, // loop over each struct and generate string for (int idx = 0; idx < deps_count; ++idx) { - encode_and_hash_type(*deps); + if (encode_and_hash_type(*deps) == false) + { + return NULL; + } deps += 1; } mem_dealloc(mem_alloc(0) - mem_loc_bak); @@ -221,6 +226,7 @@ const uint8_t *type_hash(const void *const structs_array, // End progressive hashing if ((hash_ptr = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; return NULL; } // copy hash into memory diff --git a/src_features/signMessageEIP712/ui_logic.c b/src_features/signMessageEIP712/ui_logic.c index 6fb7827..fa21891 100644 --- a/src_features/signMessageEIP712/ui_logic.c +++ b/src_features/signMessageEIP712/ui_logic.c @@ -16,6 +16,7 @@ #include "context.h" // eip712_context_deinit #include "uint256.h" // tostring256 && tostring256_signed #include "path.h" // path_get_root_type +#include "apdu_constants.h" // APDU response codes static t_ui_context *ui_ctx = NULL; @@ -359,6 +360,10 @@ bool ui_712_init(void) ui_ctx->pos = UI_712_POS_REVIEW; ui_ctx->filtering_mode = EIP712_FILTERING_BASIC; } + else + { + apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; + } return ui_ctx != NULL; }