From 1bc86754733c9c86518b71b8014356048ebeba09 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Fri, 4 Mar 2022 18:15:37 +0100 Subject: [PATCH] Initial version --- src_features/signMessageEIP712/entrypoint.c | 269 ++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 src_features/signMessageEIP712/entrypoint.c diff --git a/src_features/signMessageEIP712/entrypoint.c b/src_features/signMessageEIP712/entrypoint.c new file mode 100644 index 0000000..5fc05b5 --- /dev/null +++ b/src_features/signMessageEIP712/entrypoint.c @@ -0,0 +1,269 @@ +#include +#include +#include +#include +#include + + +enum { + OFFSET_CLA = 0, + OFFSET_INS, + OFFSET_P1, + OFFSET_P2, + OFFSET_LC, + OFFSET_DATA +}; + +typedef enum +{ + // contract defined struct + TYPE_CUSTOM = 0, + // native types + TYPE_SOLIDITY_INT, + TYPE_SOLIDITY_UINT, + TYPE_SOLIDITY_ADDRESS, + TYPE_SOLIDITY_BOOL, + TYPE_SOLIDITY_STRING, + TYPE_SOLIDITY_BYTE, + TYPE_SOLIDITY_BYTES_FIX, + TYPE_SOLIDITY_BYTES_DYN +} e_type; + + +// APDUs INS +#define INS_STRUCT_DEF 0x18 +#define INS_STRUCT_IMPL 0x1A + +// TypeDesc masks +#define TYPE_MASK (0xF) +#define ARRAY_MASK (1 << 7) +#define TYPESIZE_MASK (1 << 6) + + +#define SIZE_MEM_BUFFER 1024 +uint8_t mem_buffer[SIZE_MEM_BUFFER]; +uint16_t mem_idx; + +uint8_t *structs_array; +uint8_t *current_struct_fields_array; + + + +bool set_struct_name(uint8_t *data) +{ + // increment number of structs + *structs_array += 1; + + // copy length + mem_buffer[mem_idx++] = data[OFFSET_LC]; + + // copy name + memmove(&mem_buffer[mem_idx], &data[OFFSET_DATA], data[OFFSET_LC]); + mem_idx += data[OFFSET_LC]; + + // initialize number of fields + current_struct_fields_array = &mem_buffer[mem_idx]; + mem_buffer[mem_idx++] = 0; + return true; +} + +bool set_struct_field(uint8_t *data) +{ + uint8_t data_idx = OFFSET_DATA; + uint8_t type_desc, len; + + // increment number of struct fields + *current_struct_fields_array += 1; + + // copy TypeDesc + type_desc = data[data_idx++]; + mem_buffer[mem_idx++] = type_desc; + + // check TypeSize flag in TypeDesc + if (type_desc & TYPESIZE_MASK) + { + // copy TypeSize + mem_buffer[mem_idx++] = data[data_idx++]; + } + if ((type_desc & TYPE_MASK) == TYPE_CUSTOM) + { + len = data[data_idx++]; + // copy custom struct name length + mem_buffer[mem_idx++] = len; + // copy name + memmove(&mem_buffer[mem_idx], &data[data_idx], len); + mem_idx += len; + data_idx += len; + } + + // copy length + len = data[data_idx++]; + mem_buffer[mem_idx++] = len; + + // copy name + memmove(&mem_buffer[mem_idx], &data[data_idx], len); + mem_idx += len; + return true; +} + +void dump_mem(void) +{ + uint8_t *mem = structs_array + 1; + uint8_t type_desc; + uint8_t fields_count; + + for (int i = 0; i < *structs_array; ++i) + { + fwrite(mem + 1, *mem, sizeof(*mem), stdout); + printf("("); + mem += (1 + *mem); + fields_count = *mem; + mem += 1; + for (int y = 0; y < fields_count; ++y) + { + if (y > 0) printf(","); + type_desc = *mem; + mem += 1; + switch (type_desc & TYPE_MASK) + { + case TYPE_CUSTOM: + fwrite(mem + 1, *mem, sizeof(*mem), stdout); + mem += (1 + *mem); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + case TYPE_SOLIDITY_UINT: + printf("u"); + case TYPE_SOLIDITY_INT: + printf("int"); + if (type_desc & TYPESIZE_MASK) + { + printf("%d", (*mem * 8)); + mem += 1; + } + break; + case TYPE_SOLIDITY_ADDRESS: + printf("address"); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + case TYPE_SOLIDITY_BOOL: + printf("bool"); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + case TYPE_SOLIDITY_STRING: + printf("string"); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + case TYPE_SOLIDITY_BYTE: + printf("byte"); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + case TYPE_SOLIDITY_BYTES_FIX: + printf("bytes"); + if (type_desc & TYPESIZE_MASK) + { + printf("%d", *mem); + mem += 1; + } + break; + case TYPE_SOLIDITY_BYTES_DYN: + printf("bytes"); + if (type_desc & TYPESIZE_MASK) mem += 1; + break; + default: + // should not be in here :^) + break; + } + if (type_desc & ARRAY_MASK) printf("[]"); + printf(" "); + fwrite(mem + 1, *mem, sizeof(*mem), stdout); + mem += (1 + *mem); + } + printf(")\n"); + } +} + +bool handle_apdu(uint8_t *data) +{ + switch (data[OFFSET_INS]) + { + case INS_STRUCT_DEF: + switch (data[OFFSET_P2]) + { + case 0x00: + set_struct_name(data); + break; + case 0xFF: + set_struct_field(data); + break; + default: + printf("Unknown P2 0x%x for APDU 0x%x\n", data[OFFSET_P2], data[OFFSET_INS]); + return false; + } + break; + case INS_STRUCT_IMPL: + break; + default: + printf("Unrecognized APDU"); + return false; + } + return true; +} + +void init_heap(void) +{ + // init global variables + mem_idx = 0; + + // set types pointer + structs_array = &mem_buffer[mem_idx]; + + // create len(types) + mem_buffer[mem_idx++] = 0; +} + +int main(void) +{ + uint8_t buf[256]; + uint8_t idx; + int state; + uint8_t payload_size; + + init_heap(); + + state = OFFSET_CLA; + idx = 0; + while (true) + { + if (fread(&buf[idx], sizeof(buf[0]), 1, stdin) == 0) break; + switch (state) + { + case OFFSET_CLA: + case OFFSET_INS: + case OFFSET_P1: + case OFFSET_P2: + state += 1; + idx += 1; + break; + case OFFSET_LC: + payload_size = buf[idx]; + state = OFFSET_DATA; + idx += 1; + break; + case OFFSET_DATA: + if (--payload_size == 0) + { + handle_apdu(buf); + state = OFFSET_CLA; + idx = 0; + } + else idx += 1; + break; + default: + printf("Unexpected APDU state!\n"); + return EXIT_FAILURE; + } + } + dump_mem(); + printf("\n%d bytes used in RAM\n", mem_idx); + return EXIT_SUCCESS; +}