From 6d86a5de7706cbd77256dbaa64921708b6534289 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Mon, 2 May 2022 11:04:59 +0200 Subject: [PATCH] Global hash making --- src_features/signMessageEIP712/entrypoint.c | 4 +- src_features/signMessageEIP712/field_hash.c | 60 +++++---- src_features/signMessageEIP712/mem.c | 2 +- src_features/signMessageEIP712/path.c | 138 +++++++++++++++++++- 4 files changed, 176 insertions(+), 28 deletions(-) diff --git a/src_features/signMessageEIP712/entrypoint.c b/src_features/signMessageEIP712/entrypoint.c index 332fa64..5aff3e2 100644 --- a/src_features/signMessageEIP712/entrypoint.c +++ b/src_features/signMessageEIP712/entrypoint.c @@ -260,6 +260,7 @@ bool set_struct_name(const uint8_t *const data) } // TODO: Split this function +// TODO: Handle partial sends bool set_struct_field(const uint8_t *const data) { uint8_t data_idx = OFFSET_DATA; @@ -381,7 +382,6 @@ bool handle_apdu(const uint8_t *const data) switch (data[OFFSET_P2]) { case P2_NAME: - type_hash(structs_array, (char*)&data[OFFSET_DATA], data[OFFSET_LC], true); // set root type path_set_root((char*)&data[OFFSET_DATA], data[OFFSET_LC]); break; @@ -449,7 +449,7 @@ int main(void) } } #ifdef DEBUG - printf("\n%lu bytes used in RAM\n", (mem_max + 1)); + printf("%lu bytes used in RAM\n", (mem_max + 1)); #endif return EXIT_SUCCESS; } diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index 285be28..1d5c365 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -32,7 +32,8 @@ const uint8_t *field_hash(const uint8_t *data, const char *key; uint8_t keylen; e_type field_type; - uint8_t *hash_ptr = NULL; + uint8_t *value = NULL; + (void)data; if (fh == NULL) @@ -51,7 +52,10 @@ const uint8_t *field_hash(const uint8_t *data, data += sizeof(uint16_t); data_length -= sizeof(uint16_t); fh->state = FHS_WAITING_FOR_MORE; - cx_keccak_init((cx_hash_t*)&global_sha3, 256); // init hash + if (IS_DYN(field_type)) + { + cx_keccak_init((cx_hash_t*)&global_sha3, 256); // init hash + } } fh->remaining_size -= data_length; // if a dynamic type -> continue progressive hash @@ -78,8 +82,6 @@ const uint8_t *field_hash(const uint8_t *data, fwrite(key, sizeof(char), keylen, stdout); printf("\n"); - uint8_t *value = NULL; - if (!IS_DYN(field_type)) { switch (field_type) @@ -105,28 +107,39 @@ const uint8_t *field_hash(const uint8_t *data, { return NULL; } - cx_hash((cx_hash_t*)&global_sha3, - 0, - (uint8_t*)value, - EIP_712_ENCODED_FIELD_LENGTH, - NULL, - 0); - - // restore the memory location - mem_dealloc(EIP_712_ENCODED_FIELD_LENGTH); } - - if ((hash_ptr = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) + else { - return NULL; + if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) + { + return NULL; + } + // copy hash into memory + cx_hash((cx_hash_t*)&global_sha3, + CX_LAST, + NULL, + 0, + value, + KECCAK256_HASH_BYTESIZE); } - // copy hash into memory - cx_hash((cx_hash_t*)&global_sha3, - CX_LAST, - NULL, + + // TODO: Move elsewhere + uint8_t len = IS_DYN(field_type) ? + KECCAK256_HASH_BYTESIZE : + EIP_712_ENCODED_FIELD_LENGTH; + // last thing in mem is the hash of the previous field + // and just before it is the current hash context + cx_sha3_t *hash_ctx = (cx_sha3_t*)(value - sizeof(cx_sha3_t)); + // start the progressive hash on it + cx_hash((cx_hash_t*)hash_ctx, 0, - hash_ptr, - KECCAK256_HASH_BYTESIZE); + value, + len, + NULL, + 0); + // deallocate it + mem_dealloc(len); + printf("FEED %d\n", len); path_advance(); fh->state = FHS_IDLE; @@ -138,5 +151,6 @@ const uint8_t *field_hash(const uint8_t *data, return NULL; } } - return hash_ptr; + + return value; } diff --git a/src_features/signMessageEIP712/mem.c b/src_features/signMessageEIP712/mem.c index f3ed4aa..655d84a 100644 --- a/src_features/signMessageEIP712/mem.c +++ b/src_features/signMessageEIP712/mem.c @@ -5,7 +5,7 @@ #include "mem.h" -#define SIZE_MEM_BUFFER 2048 +#define SIZE_MEM_BUFFER 8192 static uint8_t mem_buffer[SIZE_MEM_BUFFER]; static size_t mem_idx; diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 7427896..9dbabfa 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -5,6 +5,8 @@ #include "mem.h" #include "context.h" #include "eip712.h" +#include "type_hash.h" +#include "shared_context.h" static s_path *path_struct = NULL; @@ -107,6 +109,43 @@ static bool path_depth_list_pop(void) return false; } path_struct->depth_count -= 1; + + // TODO: Move elsewhere + uint8_t shash[KECCAK256_HASH_BYTESIZE]; + cx_sha3_t *hash_ctx = mem_alloc(0) - sizeof(cx_sha3_t); + // finalize hash + cx_hash((cx_hash_t*)hash_ctx, + CX_LAST, + NULL, + 0, + &shash[0], + KECCAK256_HASH_BYTESIZE); + mem_dealloc(sizeof(cx_sha3_t)); // remove hash context +#ifdef DEBUG + // print computed hash + printf("SHASH POP 0x"); + for (int idx = 0; idx < KECCAK256_HASH_BYTESIZE; ++idx) + { + printf("%.02x", shash[idx]); + } + printf("\n"); +#endif + if (path_struct->depth_count > 0) + { + hash_ctx = mem_alloc(0) - sizeof(cx_sha3_t); // previous one + // continue progressive hash with the array hash + cx_hash((cx_hash_t*)hash_ctx, + 0, + &shash[0], + KECCAK256_HASH_BYTESIZE, + NULL, + 0); + } + else + { + printf("\n"); + } + return true; } @@ -125,6 +164,7 @@ static bool array_depth_list_push(uint8_t path_idx, uint8_t size) { return false; } + arr->path_index = path_idx; arr->size = size; path_struct->array_depth_count += 1; @@ -142,6 +182,28 @@ static bool array_depth_list_pop(void) { return false; } + + // TODO: Move elsewhere + uint8_t ahash[KECCAK256_HASH_BYTESIZE]; + cx_sha3_t *hash_ctx = mem_alloc(0) - sizeof(cx_sha3_t); + // finalize hash + cx_hash((cx_hash_t*)hash_ctx, + CX_LAST, + NULL, + 0, + &ahash[0], + KECCAK256_HASH_BYTESIZE); + mem_dealloc(sizeof(cx_sha3_t)); // remove hash context + hash_ctx = mem_alloc(0) - sizeof(cx_sha3_t); // previous one + // continue progressive hash with the array hash + cx_hash((cx_hash_t*)hash_ctx, + 0, + &ahash[0], + KECCAK256_HASH_BYTESIZE, + NULL, + 0); + printf("AHASH POP\n"); + path_struct->array_depth_count -= 1; return true; } @@ -166,7 +228,6 @@ static bool path_update(void) } while (struct_field_type(field_ptr) == TYPE_CUSTOM) { - // TODO: calculate the type hash here typename = get_struct_field_typename(field_ptr, &typename_len); if ((struct_ptr = get_structn(structs_array, typename, typename_len)) == NULL) { @@ -176,6 +237,33 @@ static bool path_update(void) { return false; } + + // TODO: Move elsewhere + cx_sha3_t *hash_ctx; + const uint8_t *thash_ptr; + + // allocate new hash context + if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) + { + return false; + } + cx_keccak_init((cx_hash_t*)hash_ctx, 256); // initialize it + // get the struct typehash + if ((thash_ptr = type_hash(structs_array, typename, typename_len, true)) == NULL) + { + return false; + } + // start the progressive hash on it + cx_hash((cx_hash_t*)hash_ctx, + 0, + thash_ptr, + KECCAK256_HASH_BYTESIZE, + NULL, + 0); + // deallocate it + mem_dealloc(KECCAK256_HASH_BYTESIZE); + printf("SHASH PUSH w/o deps %p\n", hash_ctx); + path_depth_list_push(); } return true; @@ -202,6 +290,30 @@ bool path_set_root(const char *const struct_name, uint8_t name_length) return false; } + // TODO: Move elsewhere + cx_sha3_t *hash_ctx; + const uint8_t *thash_ptr; + if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) + { + return false; + } + cx_keccak_init((cx_hash_t*)hash_ctx, 256); // init hash + if ((thash_ptr = type_hash(structs_array, struct_name, name_length, true)) == NULL) + { + return false; + } + // start the progressive hash on it + cx_hash((cx_hash_t*)hash_ctx, + 0, + thash_ptr, + KECCAK256_HASH_BYTESIZE, + NULL, + 0); + // deallocate it + mem_dealloc(KECCAK256_HASH_BYTESIZE); + printf("SHASH PUSH w/ deps %p\n", hash_ctx); + // + // init depth, at 0 : empty path path_struct->depth_count = 0; path_depth_list_push(); @@ -262,7 +374,8 @@ static bool check_and_add_array_depth(const void *depth, */ bool path_new_array_depth(uint8_t size) { - const void *field_ptr, *depth; + const void *field_ptr = NULL; + const void *depth = NULL; uint8_t depth_count; uint8_t total_count = 0; uint8_t pidx; @@ -302,6 +415,27 @@ bool path_new_array_depth(uint8_t size) printf("Did not find a matching array type.\n"); return false; } + // TODO: Move elsewhere + cx_sha3_t *hash_ctx; + if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) + { + return false; + } + printf("AHASH PUSH %p", hash_ctx); + if (struct_field_type(field_ptr) == TYPE_CUSTOM) + { + cx_sha3_t *old_ctx = (void*)hash_ctx - sizeof(cx_sha3_t); + + memcpy(hash_ctx, old_ctx, sizeof(cx_sha3_t)); + cx_keccak_init((cx_hash_t*)old_ctx, 256); // init hash + printf(" (switched)"); + } + else // solidity type + { + cx_keccak_init((cx_hash_t*)hash_ctx, 256); // init hash + } + printf("\n"); + return true; }