From 01179730a13bfd7f70f5d0f65c16f0cdeda24f20 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Fri, 1 Jul 2022 18:23:35 +0200 Subject: [PATCH] Updated the EIP-712 filtering signature specs; Update the verification implementation to now handle field path intead of only the field key name --- doc/ethapp.adoc | 4 +- src_features/signMessageEIP712/entrypoint.c | 92 +++++++++------------ src_features/signMessageEIP712/path.c | 40 ++++++--- src_features/signMessageEIP712/path.h | 4 +- src_features/signMessageEIP712/ui_logic.c | 2 +- 5 files changed, 71 insertions(+), 71 deletions(-) diff --git a/doc/ethapp.adoc b/doc/ethapp.adoc index fe5ce5e..33d613f 100644 --- a/doc/ethapp.adoc +++ b/doc/ethapp.adoc @@ -812,7 +812,7 @@ Perfect moment to do it is when the domain implementation has been sent, just be The signature is computed on : -chain ID (BE) || contract address || schema hash || display name length || display name +chain ID (BE) || contract address || schema hash || display name ##### Field name substitution @@ -821,7 +821,7 @@ Name substitution commands should come before the corresponding *SEND STRUCT IMP The signature is computed on : -chain ID (BE) || contract address || schema hash || json key length || json key || display name length || display name +chain ID (BE) || contract address || schema hash || field path || display name #### Coding diff --git a/src_features/signMessageEIP712/entrypoint.c b/src_features/signMessageEIP712/entrypoint.c index 260b476..f568ac9 100644 --- a/src_features/signMessageEIP712/entrypoint.c +++ b/src_features/signMessageEIP712/entrypoint.c @@ -480,6 +480,7 @@ bool handle_eip712_struct_impl(const uint8_t *const apdu_buf) return ret; } +#include "hash_bytes.h" static bool verify_filtering_signature(uint8_t dname_length, const char *const dname, uint8_t sig_length, @@ -498,72 +499,55 @@ static bool verify_filtering_signature(uint8_t dname_length, // Chain ID chain_id = __builtin_bswap64(chainConfig->chainId); - cx_hash((cx_hash_t*)&hash_ctx, - 0, - (uint8_t*)&chain_id, - sizeof(chain_id), - NULL, - 0); + hash_nbytes((uint8_t*)&chain_id, sizeof(chain_id), (cx_hash_t*)&hash_ctx); // Contract address - cx_hash((cx_hash_t*)&hash_ctx, - 0, - eip712_context->contract_addr, - sizeof(eip712_context->contract_addr), - NULL, - 0); + hash_nbytes(eip712_context->contract_addr, + sizeof(eip712_context->contract_addr), + (cx_hash_t*)&hash_ctx); // Schema hash - cx_hash((cx_hash_t*)&hash_ctx, - 0, - eip712_context->schema_hash, - sizeof(eip712_context->schema_hash), - NULL, - 0); + hash_nbytes(eip712_context->schema_hash, + sizeof(eip712_context->schema_hash), + (cx_hash_t*)&hash_ctx); if (p1 == P1_FIELD_NAME) { - if ((field_ptr = path_get_field()) == NULL) - { - return false; - } - if ((key = get_struct_field_keyname(field_ptr, &key_len)) == NULL) - { - return false; - } + uint8_t depth_count = path_get_depth_count(); - // Key length - cx_hash((cx_hash_t*)&hash_ctx, - 0, - &key_len, - sizeof(key_len), - NULL, - 0); + for (uint8_t i = 0; i < depth_count; ++i) + { + if (i > 0) + { + hash_byte('.', (cx_hash_t*)&hash_ctx); + } + if ((field_ptr = path_get_nth_field(i + 1)) != NULL) + { + if ((key = get_struct_field_keyname(field_ptr, &key_len)) != NULL) + { + // field name + hash_nbytes((uint8_t*)key, key_len, (cx_hash_t*)&hash_ctx); - // Key - cx_hash((cx_hash_t*)&hash_ctx, - 0, - (uint8_t*)key, - sizeof(char) * key_len, - NULL, - 0); + // array levels + if (struct_field_is_array(field_ptr)) + { + uint8_t lvl_count; + + get_struct_field_array_lvls_array(field_ptr, &lvl_count); + for (int j = 0; j < lvl_count; ++j) + { + hash_nbytes((uint8_t*)".[]", 3, (cx_hash_t*)&hash_ctx); + } + } + } + } + } } - // Display name length - cx_hash((cx_hash_t*)&hash_ctx, - 0, - &dname_length, - sizeof(dname_length), - NULL, - 0); - // Display name - cx_hash((cx_hash_t*)&hash_ctx, - 0, - (uint8_t*)dname, - sizeof(char) * dname_length, - NULL, - 0); + hash_nbytes((uint8_t*)dname, + sizeof(char) * dname_length, + (cx_hash_t*)&hash_ctx); // Finalize hash cx_hash((cx_hash_t*)&hash_ctx, diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 4be0cb3..4ed05bc 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -18,11 +18,11 @@ static s_path *path_struct = NULL; * Get the field pointer to by the first N depths of the path. * * @param[out] fields_count_ptr the number of fields in the last evaluated depth - * @param[in] depth_count the number of depths to evaluate (N) + * @param[in] n the number of depths to evaluate * @return the feld which the first Nth depths points to */ -static const void *get_nth_field_from_path(uint8_t *const fields_count_ptr, - uint8_t depth_count) +static const void *get_nth_field(uint8_t *const fields_count_ptr, + uint8_t n) { const void *struct_ptr = path_struct->root_struct; const void *field_ptr = NULL; @@ -34,11 +34,11 @@ static const void *get_nth_field_from_path(uint8_t *const fields_count_ptr, { return NULL; } - if (depth_count > path_struct->depth_count) // sanity check + if (n > path_struct->depth_count) // sanity check { return NULL; } - for (uint8_t depth = 0; depth < depth_count; ++depth) + for (uint8_t depth = 0; depth < n; ++depth) { field_ptr = get_struct_fields_array(struct_ptr, &fields_count); @@ -74,19 +74,24 @@ static const void *get_nth_field_from_path(uint8_t *const fields_count_ptr, * @param[out] the number of fields in the depth of the returned field * @return the field which the path points to */ -static inline const void *get_field_from_path(uint8_t *const fields_count) +static inline const void *get_field(uint8_t *const fields_count) { - return get_nth_field_from_path(fields_count, path_struct->depth_count); + return get_nth_field(fields_count, path_struct->depth_count); } -const void *path_get_nth_struct_to_last(uint8_t n) +const void *path_get_nth_field(uint8_t n) +{ + return get_nth_field(NULL, n); +} + +const void *path_get_nth_field_to_last(uint8_t n) { const char *typename; uint8_t typename_len; const void *field_ptr; const void *struct_ptr = NULL; - field_ptr = get_nth_field_from_path(NULL, path_struct->depth_count - n); + field_ptr = get_nth_field(NULL, path_struct->depth_count - n); if (field_ptr != NULL) { typename = get_struct_field_typename(field_ptr, &typename_len); @@ -102,7 +107,7 @@ const void *path_get_nth_struct_to_last(uint8_t n) */ const void *path_get_field(void) { - return get_field_from_path(NULL); + return get_field(NULL); } /** @@ -281,7 +286,7 @@ static bool path_update(void) { return false; } - if ((field_ptr = get_field_from_path(NULL)) == NULL) + if ((field_ptr = get_field(NULL)) == NULL) { return false; } @@ -468,7 +473,7 @@ bool path_new_array_depth(uint8_t size) for (pidx = 0; pidx < path_struct->depth_count; ++pidx) { - if ((field_ptr = get_nth_field_from_path(NULL, pidx + 1)) == NULL) + if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) { return false; } @@ -532,7 +537,7 @@ static bool path_advance_in_struct(void) { return false; } - if ((get_field_from_path(&fields_count)) == NULL) + if ((get_field(&fields_count)) == NULL) { return false; } @@ -629,6 +634,15 @@ const void *path_get_root(void) return path_struct->root_struct; } +uint8_t path_get_depth_count(void) +{ + if (path_struct == NULL) + { + return 0; + } + return path_struct->depth_count; +} + /** * Allocates the path indexes in memory and sets it with a depth of 0. * diff --git a/src_features/signMessageEIP712/path.h b/src_features/signMessageEIP712/path.h index ef43a2c..cf21c8c 100644 --- a/src_features/signMessageEIP712/path.h +++ b/src_features/signMessageEIP712/path.h @@ -39,7 +39,9 @@ void path_deinit(void); bool path_new_array_depth(uint8_t size); e_root_type path_get_root_type(void); const void *path_get_root(void); -const void *path_get_nth_struct_to_last(uint8_t n); +const void *path_get_nth_field(uint8_t n); +const void *path_get_nth_field_to_last(uint8_t n); +uint8_t path_get_depth_count(void); #endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_features/signMessageEIP712/ui_logic.c b/src_features/signMessageEIP712/ui_logic.c index eef3aeb..6fb7827 100644 --- a/src_features/signMessageEIP712/ui_logic.c +++ b/src_features/signMessageEIP712/ui_logic.c @@ -132,7 +132,7 @@ void ui_712_next_field(void) } if (ui_ctx->structs_to_review > 0) { - ui_712_review_struct(path_get_nth_struct_to_last(ui_ctx->structs_to_review)); + ui_712_review_struct(path_get_nth_field_to_last(ui_ctx->structs_to_review)); ui_ctx->structs_to_review -= 1; } else