diff --git a/src_features/signMessageEIP712/context.c b/src_features/signMessageEIP712/context.c new file mode 100644 index 0000000..6db0e0d --- /dev/null +++ b/src_features/signMessageEIP712/context.c @@ -0,0 +1,31 @@ +#include +#include +#include "context.h" +#include "eip712.h" +#include "mem.h" +#include "sol_typenames.h" + +uint8_t *typenames_array; +uint8_t *structs_array; +uint8_t *current_struct_fields_array; + +/** + * + * @return a boolean indicating if the initialization was successful or not + */ +bool init_eip712_context(void) +{ + // init global variables + mem_init(); + + if (init_sol_typenames() == false) + return false; + + // set types pointer + if ((structs_array = mem_alloc(sizeof(uint8_t))) == NULL) + return false; + + // create len(types) + *structs_array = 0; + return true; +} diff --git a/src_features/signMessageEIP712/context.h b/src_features/signMessageEIP712/context.h new file mode 100644 index 0000000..7c4520b --- /dev/null +++ b/src_features/signMessageEIP712/context.h @@ -0,0 +1,13 @@ +#ifndef EIP712_CTX_H_ +#define EIP712_CTX_H_ + +#include + + +extern uint8_t *typenames_array; +extern uint8_t *structs_array; +extern uint8_t *current_struct_fields_array; + +bool init_eip712_context(void); + +#endif // EIP712_CTX_H_ diff --git a/src_features/signMessageEIP712/eip712.h b/src_features/signMessageEIP712/eip712.h index e7e1cae..6d51647 100644 --- a/src_features/signMessageEIP712/eip712.h +++ b/src_features/signMessageEIP712/eip712.h @@ -35,13 +35,6 @@ typedef enum ARRAY_FIXED_SIZE } e_array_type; -typedef enum -{ - IDX_ENUM = 0, - IDX_STR_IDX, - IDX_COUNT -} t_typename_matcher_idx; - #define MIN(a,b) ((a > b) ? b : a) #define MAX(a,b) ((a > b) ? a : b) @@ -64,9 +57,6 @@ typedef enum #define TYPESIZE_MASK (1 << 6) #define TYPENAME_ENUM (0xF) -// Solidity typenames array mask -#define TYPENAME_MORE_TYPE (1 << 7) // For custom typename - #define KECCAK256_HASH_LENGTH 32 typedef struct @@ -90,7 +80,6 @@ typedef struct } t_struct_field; - // TODO: Move these into a new file const char *get_struct_name(const uint8_t *ptr, uint8_t *const length); const uint8_t *get_struct_fields_array(const uint8_t *ptr, @@ -115,5 +104,7 @@ const uint8_t *get_next_struct_field(const void *ptr); const uint8_t *get_structn(const uint8_t *const ptr, const char *const name_ptr, const uint8_t name_length); +const void *get_array_in_mem(const void *ptr, uint8_t *const array_size); +const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length); #endif // EIP712_H_ diff --git a/src_features/signMessageEIP712/entrypoint.c b/src_features/signMessageEIP712/entrypoint.c index baf9421..9e85e40 100644 --- a/src_features/signMessageEIP712/entrypoint.c +++ b/src_features/signMessageEIP712/entrypoint.c @@ -7,12 +7,10 @@ #include "eip712.h" #include "mem.h" #include "type_hash.h" +#include "context.h" +#include "sol_typenames.h" -static uint8_t *typenames_array; -static uint8_t *structs_array; -static uint8_t *current_struct_fields_array; - // lib functions const void *get_array_in_mem(const void *ptr, uint8_t *const array_size) { @@ -20,7 +18,7 @@ const void *get_array_in_mem(const void *ptr, uint8_t *const array_size) return (ptr + 1); } -static inline const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length) +const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length) { return (char*)get_array_in_mem(ptr, string_length); } @@ -64,39 +62,6 @@ const char *get_struct_field_custom_typename(const uint8_t *ptr, return get_string_in_mem(ptr, length); } -// ptr must point to the beginning of a struct field -const char *get_struct_field_sol_typename(const uint8_t *ptr, - uint8_t *const length) -{ - e_type field_type; - const uint8_t *typename_ptr; - uint8_t typenames_count; - bool more_type; - bool typename_found; - - field_type = struct_field_type(ptr); - typename_ptr = get_array_in_mem(typenames_array, &typenames_count); - typename_found = false; - while (typenames_count-- > 0) - { - more_type = true; - while (more_type) - { - more_type = *typename_ptr & TYPENAME_MORE_TYPE; - e_type type_enum = *typename_ptr & TYPENAME_ENUM; - if (type_enum == field_type) - { - typename_found = true; - } - typename_ptr += 1; - } - typename_ptr = (uint8_t*)get_string_in_mem(typename_ptr, length); - if (typename_found) return (char*)typename_ptr; - typename_ptr += *length; - } - return NULL; // Not found -} - // ptr must point to the beginning of a struct field const char *get_struct_field_typename(const uint8_t *ptr, uint8_t *const length) @@ -431,101 +396,6 @@ bool handle_apdu(const uint8_t *const data) return true; } -bool init_typenames(void) -{ - const char *const typenames_str[] = { - "int", - "uint", - "address", - "bool", - "string", - "byte", - "bytes" - }; - const int enum_to_idx[][IDX_COUNT] = { - { TYPE_SOL_INT, 0 }, - { TYPE_SOL_UINT, 1}, - { TYPE_SOL_ADDRESS, 2 }, - { TYPE_SOL_BOOL, 3 }, - { TYPE_SOL_STRING, 4 }, - { TYPE_SOL_BYTE, 5 }, - { TYPE_SOL_BYTES_FIX, 6 }, - { TYPE_SOL_BYTES_DYN, 6 } - }; - uint8_t *previous_match; - uint8_t *typename_len_ptr; - char *typename_ptr; - - if ((typenames_array = mem_alloc(sizeof(uint8_t))) == NULL) - { - return false; - } - *typenames_array = 0; - // loop over typenames - for (size_t s_idx = 0; - s_idx < (sizeof(typenames_str) / sizeof(typenames_str[IDX_ENUM])); - ++s_idx) - { - previous_match = NULL; - // loop over enum/typename pairs - for (size_t e_idx = 0; - e_idx < (sizeof(enum_to_idx) / sizeof(enum_to_idx[IDX_ENUM])); - ++e_idx) - { - if (s_idx == (size_t)enum_to_idx[e_idx][IDX_STR_IDX]) // match - { - if (previous_match) // in case of a previous match, mark it - { - *previous_match |= TYPENAME_MORE_TYPE; - } - if ((previous_match = mem_alloc(sizeof(uint8_t))) == NULL) - { - return false; - } - *previous_match = enum_to_idx[e_idx][IDX_ENUM]; - } - } - - if (previous_match) // if at least one match was found - { - if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) - { - return false; - } - // get pointer to the allocated space just above - *typename_len_ptr = strlen(typenames_str[s_idx]); - - - if ((typename_ptr = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) - { - return false; - } - // copy typename - memcpy(typename_ptr, typenames_str[s_idx], *typename_len_ptr); - } - // increment array size - *typenames_array += 1; - } - return true; -} - -bool init_eip712_context(void) -{ - // init global variables - init_mem(); - - if (init_typenames() == false) - return false; - - // set types pointer - if ((structs_array = mem_alloc(sizeof(uint8_t))) == NULL) - return false; - - // create len(types) - *structs_array = 0; - return true; -} - int main(void) { uint8_t buf[260]; // 4 bytes APDU header + 256 bytes payload diff --git a/src_features/signMessageEIP712/sol_typenames.c b/src_features/signMessageEIP712/sol_typenames.c new file mode 100644 index 0000000..018c263 --- /dev/null +++ b/src_features/signMessageEIP712/sol_typenames.c @@ -0,0 +1,132 @@ +#include +#include +#include "sol_typenames.h" +#include "eip712.h" +#include "context.h" +#include "mem.h" + +// Bit indicating they are more types associated to this typename +#define TYPENAME_MORE_TYPE (1 << 7) + +enum +{ + IDX_ENUM = 0, + IDX_STR_IDX, + IDX_COUNT +}; + +bool init_sol_typenames(void) +{ + const char *const typenames_str[] = { + "int", // 0 + "uint", // 1 + "address", // 2 + "bool", // 3 + "string", // 4 + "byte", // 5 + "bytes" // 6 + }; + const uint8_t enum_to_idx[][IDX_COUNT] = { + { TYPE_SOL_INT, 0 }, + { TYPE_SOL_UINT, 1 }, + { TYPE_SOL_ADDRESS, 2 }, + { TYPE_SOL_BOOL, 3 }, + { TYPE_SOL_STRING, 4 }, + { TYPE_SOL_BYTE, 5 }, + { TYPE_SOL_BYTES_FIX, 6 }, + { TYPE_SOL_BYTES_DYN, 6 } + }; + uint8_t *previous_match; + uint8_t *typename_len_ptr; + char *typename_ptr; + + if ((typenames_array = mem_alloc(sizeof(uint8_t))) == NULL) + { + return false; + } + *typenames_array = 0; + // loop over typenames + for (size_t s_idx = 0; + s_idx < (sizeof(typenames_str) / sizeof(typenames_str[IDX_ENUM])); + ++s_idx) + { + previous_match = NULL; + // loop over enum/typename pairs + for (size_t e_idx = 0; + e_idx < (sizeof(enum_to_idx) / sizeof(enum_to_idx[IDX_ENUM])); + ++e_idx) + { + if (s_idx == (size_t)enum_to_idx[e_idx][IDX_STR_IDX]) // match + { + if (previous_match) // in case of a previous match, mark it + { + *previous_match |= TYPENAME_MORE_TYPE; + } + if ((previous_match = mem_alloc(sizeof(uint8_t))) == NULL) + { + return false; + } + *previous_match = enum_to_idx[e_idx][IDX_ENUM]; + } + } + + if (previous_match) // if at least one match was found + { + if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) + { + return false; + } + // get pointer to the allocated space just above + *typename_len_ptr = strlen(typenames_str[s_idx]); + + + if ((typename_ptr = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) + { + return false; + } + // copy typename + memcpy(typename_ptr, typenames_str[s_idx], *typename_len_ptr); + } + // increment array size + *typenames_array += 1; + } + return true; +} + +/** + * + * @param[in] field_ptr pointer to a struct field + * @param[out] length length of the returned typename + * @return typename or \ref NULL in case it wasn't found + */ +const char *get_struct_field_sol_typename(const uint8_t *field_ptr, + uint8_t *const length) +{ + e_type field_type; + const uint8_t *typename_ptr; + uint8_t typenames_count; + bool more_type; + bool typename_found; + + field_type = struct_field_type(field_ptr); + typename_ptr = get_array_in_mem(typenames_array, &typenames_count); + typename_found = false; + while (typenames_count-- > 0) + { + more_type = true; + while (more_type) + { + more_type = *typename_ptr & TYPENAME_MORE_TYPE; + e_type type_enum = *typename_ptr & TYPENAME_ENUM; + if (type_enum == field_type) + { + typename_found = true; + } + typename_ptr += 1; + } + typename_ptr = (uint8_t*)get_string_in_mem(typename_ptr, length); + if (typename_found) return (char*)typename_ptr; + typename_ptr += *length; + } + return NULL; // Not found +} diff --git a/src_features/signMessageEIP712/sol_typenames.h b/src_features/signMessageEIP712/sol_typenames.h new file mode 100644 index 0000000..b1e2a67 --- /dev/null +++ b/src_features/signMessageEIP712/sol_typenames.h @@ -0,0 +1,12 @@ +#ifndef SOL_TYPENAMES_H_ +#define SOL_TYPENAMES_H_ + +#include +#include + +bool init_sol_typenames(void); + +const char *get_struct_field_sol_typename(const uint8_t *ptr, + uint8_t *const length); + +#endif // SOL_TYPENAMES_H_