EIP-712 code linting

This commit is contained in:
Alexandre Paillier
2022-07-19 11:49:18 +02:00
parent 0cf21cdf73
commit de9e895ad9
44 changed files with 778 additions and 1402 deletions

View File

@@ -34,14 +34,13 @@
#define COMMON_CLA 0xB0 #define COMMON_CLA 0xB0
#define COMMON_INS_GET_WALLET_ID 0x04 #define COMMON_INS_GET_WALLET_ID 0x04
#define APDU_RESPONSE_OK 0x9000 #define APDU_RESPONSE_OK 0x9000
#define APDU_RESPONSE_INVALID_DATA 0x6a80 #define APDU_RESPONSE_INVALID_DATA 0x6a80
#define APDU_RESPONSE_INSUFFICIENT_MEMORY 0x6a84 #define APDU_RESPONSE_INSUFFICIENT_MEMORY 0x6a84
#define APDU_RESPONSE_INVALID_INS 0x6d00 #define APDU_RESPONSE_INVALID_INS 0x6d00
#define APDU_RESPONSE_INVALID_P1_P2 0x6b00 #define APDU_RESPONSE_INVALID_P1_P2 0x6b00
#define APDU_RESPONSE_CONDITION_NOT_SATISFIED 0x6985 #define APDU_RESPONSE_CONDITION_NOT_SATISFIED 0x6985
#define APDU_RESPONSE_REF_DATA_NOT_USABLE 0x6a88 #define APDU_RESPONSE_REF_DATA_NOT_USABLE 0x6a88
#ifdef HAVE_STARKWARE #ifdef HAVE_STARKWARE
@@ -63,14 +62,7 @@
#endif #endif
enum { enum { OFFSET_CLA = 0, OFFSET_INS, OFFSET_P1, OFFSET_P2, OFFSET_LC, OFFSET_CDATA };
OFFSET_CLA = 0,
OFFSET_INS,
OFFSET_P1,
OFFSET_P2,
OFFSET_LC,
OFFSET_CDATA
};
void handleGetPublicKey(uint8_t p1, void handleGetPublicKey(uint8_t p1,
uint8_t p2, uint8_t p2,

View File

@@ -71,7 +71,7 @@ const internalStorage_t N_storage_real;
chain_config_t *chainConfig; chain_config_t *chainConfig;
void reset_app_context() { void reset_app_context() {
//PRINTF("!!RESET_APP_CONTEXT\n"); // PRINTF("!!RESET_APP_CONTEXT\n");
appState = APP_STATE_IDLE; appState = APP_STATE_IDLE;
called_from_swap = false; called_from_swap = false;
pluginType = OLD_INTERNAL; pluginType = OLD_INTERNAL;
@@ -664,8 +664,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
break; break;
case INS_SIGN_EIP_712_MESSAGE: case INS_SIGN_EIP_712_MESSAGE:
if (G_io_apdu_buffer[OFFSET_P2] == 0) if (G_io_apdu_buffer[OFFSET_P2] == 0) {
{
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_ITEMS); memset(tmpCtx.transactionContext.tokenSet, 0, MAX_ITEMS);
handleSignEIP712Message_v0(G_io_apdu_buffer[OFFSET_P1], handleSignEIP712Message_v0(G_io_apdu_buffer[OFFSET_P1],
G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer[OFFSET_P2],
@@ -673,15 +672,13 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
G_io_apdu_buffer[OFFSET_LC], G_io_apdu_buffer[OFFSET_LC],
flags, flags,
tx); tx);
} } else {
else
{
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
*flags |= IO_ASYNCH_REPLY; *flags |= IO_ASYNCH_REPLY;
handle_eip712_sign(G_io_apdu_buffer); handle_eip712_sign(G_io_apdu_buffer);
#else #else
THROW(0x6B00); THROW(0x6B00);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
} }
break; break;
@@ -723,7 +720,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
*flags |= IO_ASYNCH_REPLY; *flags |= IO_ASYNCH_REPLY;
handle_eip712_filtering(G_io_apdu_buffer); handle_eip712_filtering(G_io_apdu_buffer);
break; break;
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#if 0 #if 0
case 0xFF: // return to dashboard case 0xFF: // return to dashboard

View File

@@ -29,7 +29,7 @@ typedef struct internalStorage_t {
unsigned char displayNonce; unsigned char displayNonce;
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
bool verbose_eip712; bool verbose_eip712;
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
uint8_t initialized; uint8_t initialized;
} internalStorage_t; } internalStorage_t;

View File

@@ -7,7 +7,7 @@ void switch_settings_display_data(void);
void switch_settings_display_nonce(void); void switch_settings_display_nonce(void);
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
void switch_settings_verbose_eip712(void); void switch_settings_verbose_eip712(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// clang-format off // clang-format off
@@ -148,27 +148,22 @@ UX_FLOW(ux_settings_flow,
&ux_settings_flow_display_nonce_step, &ux_settings_flow_display_nonce_step,
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
&ux_settings_flow_verbose_eip712_step, &ux_settings_flow_verbose_eip712_step,
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
&ux_settings_flow_back_step); &ux_settings_flow_back_step);
void display_settings(const ux_flow_step_t* const start_step) { void display_settings(const ux_flow_step_t* const start_step) {
const char *const values[] = { const char* const values[] = {"Enabled", "Disabled"};
"Enabled", bool settings[] = {N_storage.dataAllowed,
"Disabled" N_storage.contractDetails,
}; N_storage.displayNonce,
bool settings[] = {
N_storage.dataAllowed,
N_storage.contractDetails,
N_storage.displayNonce,
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
N_storage.verbose_eip712 N_storage.verbose_eip712
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
}; };
uint8_t offset = 0; uint8_t offset = 0;
uint8_t increment = MAX(strlen(values[0]), strlen(values[1])) + 1; uint8_t increment = MAX(strlen(values[0]), strlen(values[1])) + 1;
for (unsigned int i = 0; i < (sizeof(settings) / sizeof(settings[0])); ++i) for (unsigned int i = 0; i < (sizeof(settings) / sizeof(settings[0])); ++i) {
{
strlcpy(strings.common.fullAddress + offset, strlcpy(strings.common.fullAddress + offset,
(settings[i] ? values[0] : values[1]), (settings[i] ? values[0] : values[1]),
sizeof(strings.common.fullAddress) - offset); sizeof(strings.common.fullAddress) - offset);
@@ -197,13 +192,12 @@ void switch_settings_display_nonce(void) {
} }
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
void switch_settings_verbose_eip712(void) void switch_settings_verbose_eip712(void) {
{
bool value = !N_storage.verbose_eip712; bool value = !N_storage.verbose_eip712;
nvm_write((void*) &N_storage.verbose_eip712, (void*) &value, sizeof(value)); nvm_write((void*) &N_storage.verbose_eip712, (void*) &value, sizeof(value));
display_settings(&ux_settings_flow_verbose_eip712_step); display_settings(&ux_settings_flow_verbose_eip712_step);
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// clang-format off // clang-format off

View File

@@ -22,14 +22,13 @@
#include "uint256.h" #include "uint256.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void array_hexstr(char* strbuf, const void* bin, unsigned int len); void array_hexstr(char* strbuf, const void* bin, unsigned int len);
void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target); void convertUint128BE(const uint8_t* const data, uint32_t length, uint128_t* const target);
void convertUint256BE(const uint8_t *const data, uint32_t length, uint256_t *const target); void convertUint256BE(const uint8_t* const data, uint32_t length, uint256_t* const target);
void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target); void convertUint64BEto128(const uint8_t* const data, uint32_t length, uint128_t* const target);
uint64_t u64_from_BE(const uint8_t* in, uint8_t size); uint64_t u64_from_BE(const uint8_t* in, uint8_t size);

View File

@@ -5,23 +5,20 @@
#define SIZE_MEM_BUFFER 5120 #define SIZE_MEM_BUFFER 5120
static uint8_t mem_buffer[SIZE_MEM_BUFFER]; static uint8_t mem_buffer[SIZE_MEM_BUFFER];
static size_t mem_idx; static size_t mem_idx;
/** /**
* Initializes the memory buffer index * Initializes the memory buffer index
*/ */
void mem_init(void) void mem_init(void) {
{
mem_idx = 0; mem_idx = 0;
} }
/** /**
* Resets the memory buffer index * Resets the memory buffer index
*/ */
void mem_reset(void) void mem_reset(void) {
{
mem_init(); mem_init();
} }
@@ -34,9 +31,8 @@ void mem_reset(void)
* @param[in] size Requested allocation size in bytes * @param[in] size Requested allocation size in bytes
* @return Allocated memory pointer; \ref NULL if not enough space left. * @return Allocated memory pointer; \ref NULL if not enough space left.
*/ */
void *mem_alloc(size_t size) void *mem_alloc(size_t size) {
{ if ((mem_idx + size) > SIZE_MEM_BUFFER) // Buffer exceeded
if ((mem_idx + size) > SIZE_MEM_BUFFER) // Buffer exceeded
{ {
return NULL; return NULL;
} }
@@ -49,16 +45,13 @@ void *mem_alloc(size_t size)
* *
* @param[in] size Requested deallocation size in bytes * @param[in] size Requested deallocation size in bytes
*/ */
void mem_dealloc(size_t size) void mem_dealloc(size_t size) {
{ if (size > mem_idx) // More than is already allocated
if (size > mem_idx) // More than is already allocated
{ {
mem_idx = 0; mem_idx = 0;
} } else {
else
{
mem_idx -= size; mem_idx -= size;
} }
} }
#endif // HAVE_DYN_MEM_ALLOC #endif // HAVE_DYN_MEM_ALLOC

View File

@@ -5,11 +5,11 @@
#include <stdlib.h> #include <stdlib.h>
void mem_init(void); void mem_init(void);
void mem_reset(void); void mem_reset(void);
void *mem_alloc(size_t size); void *mem_alloc(size_t size);
void mem_dealloc(size_t size); void mem_dealloc(size_t size);
#endif // HAVE_DYN_MEM_ALLOC #endif // HAVE_DYN_MEM_ALLOC
#endif // MEM_H_ #endif // MEM_H_

View File

@@ -14,26 +14,22 @@
* *
* @return pointer to memory area or \ref NULL if the allocation failed * @return pointer to memory area or \ref NULL if the allocation failed
*/ */
char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
{ char *mem_ptr;
char *mem_ptr; uint32_t value_copy;
uint32_t value_copy; uint8_t size;
uint8_t size;
size = 1; // minimum size, even if 0 size = 1; // minimum size, even if 0
value_copy = value; value_copy = value;
while (value_copy >= 10) while (value_copy >= 10) {
{
value_copy /= 10; value_copy /= 10;
size += 1; size += 1;
} }
// +1 for the null character // +1 for the null character
if ((mem_ptr = mem_alloc(sizeof(char) * (size + 1)))) if ((mem_ptr = mem_alloc(sizeof(char) * (size + 1)))) {
{
snprintf(mem_ptr, (size + 1), "%u", value); snprintf(mem_ptr, (size + 1), "%u", value);
mem_dealloc(sizeof(char)); // to skip the null character mem_dealloc(sizeof(char)); // to skip the null character
if (length != NULL) if (length != NULL) {
{
*length = size; *length = size;
} }
} }
@@ -49,18 +45,16 @@ char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length)
* *
* @return pointer to the memory area, \ref NULL if the allocation failed * @return pointer to the memory area, \ref NULL if the allocation failed
*/ */
void *mem_alloc_and_align(size_t size, size_t alignment) void *mem_alloc_and_align(size_t size, size_t alignment) {
{ uint8_t align_diff = (uintptr_t) mem_alloc(0) % alignment;
uint8_t align_diff = (uintptr_t)mem_alloc(0) % alignment;
if (align_diff > 0) // alignment needed if (align_diff > 0) // alignment needed
{ {
if (mem_alloc(alignment - align_diff) == NULL) if (mem_alloc(alignment - align_diff) == NULL) {
{
return NULL; return NULL;
} }
} }
return mem_alloc(size); return mem_alloc(size);
} }
#endif // HAVE_DYN_MEM_ALLOC #endif // HAVE_DYN_MEM_ALLOC

View File

@@ -6,11 +6,11 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define MEM_ALLOC_AND_ALIGN_TYPE(type) mem_alloc_and_align(sizeof(type), __alignof__(type)) #define MEM_ALLOC_AND_ALIGN_TYPE(type) mem_alloc_and_align(sizeof(type), __alignof__(type))
char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars); char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars);
void *mem_alloc_and_align(size_t size, size_t alignment); void *mem_alloc_and_align(size_t size, size_t alignment);
#endif // HAVE_DYN_MEM_ALLOC #endif // HAVE_DYN_MEM_ALLOC
#endif // MEM_UTILS_H_ #endif // MEM_UTILS_H_

View File

@@ -21,7 +21,7 @@
#include <string.h> #include <string.h>
#include "uint128.h" #include "uint128.h"
#include "uint_common.h" #include "uint_common.h"
#include "ethUtils.h" // HEXDIGITS #include "ethUtils.h" // HEXDIGITS
void readu128BE(const uint8_t *const buffer, uint128_t *const target) { void readu128BE(const uint8_t *const buffer, uint128_t *const target) {
UPPER_P(target) = readUint64BE(buffer); UPPER_P(target) = readUint64BE(buffer);

View File

@@ -21,8 +21,8 @@
#include <string.h> #include <string.h>
#include "uint256.h" #include "uint256.h"
#include "uint_common.h" #include "uint_common.h"
#include "ethUstream.h" // INT256_LENGTH #include "ethUstream.h" // INT256_LENGTH
#include "ethUtils.h" // HEXDIGITS #include "ethUtils.h" // HEXDIGITS
void readu256BE(const uint8_t *const buffer, uint256_t *const target) { void readu256BE(const uint8_t *const buffer, uint256_t *const target) {
readu128BE(buffer, &UPPER_P(target)); readu128BE(buffer, &UPPER_P(target));

View File

@@ -58,5 +58,4 @@ bool tostring256_signed(const uint256_t *const number,
char *const out, char *const out,
uint32_t out_length); uint32_t out_length);
#endif // _UINT256_H_ #endif // _UINT256_H_

View File

@@ -32,4 +32,4 @@ void read_u64_be(const uint8_t *const in, uint64_t *const out);
uint64_t readUint64BE(const uint8_t *const buffer); uint64_t readUint64BE(const uint8_t *const buffer);
void reverseString(char *const str, uint32_t length); void reverseString(char *const str, uint32_t length);
#endif //_UINT_COMMON_H_ #endif //_UINT_COMMON_H_

View File

@@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "commands_712.h" #include "commands_712.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "context.h" #include "context.h"
#include "field_hash.h" #include "field_hash.h"
#include "path.h" #include "path.h"
@@ -22,19 +22,16 @@
* *
* @param[in] success whether the command was successful * @param[in] success whether the command was successful
*/ */
void handle_eip712_return_code(bool success) void handle_eip712_return_code(bool success) {
{ if (success) {
if (success)
{
apdu_response_code = APDU_RESPONSE_OK; apdu_response_code = APDU_RESPONSE_OK;
} }
*(uint16_t*)G_io_apdu_buffer = __builtin_bswap16(apdu_response_code); *(uint16_t *) G_io_apdu_buffer = __builtin_bswap16(apdu_response_code);
// Send back the response, do not restart the event loop // Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
if (!success) if (!success) {
{
eip712_context_deinit(); eip712_context_deinit();
} }
} }
@@ -45,18 +42,14 @@ void handle_eip712_return_code(bool success)
* @param[in] apdu_buf the APDU payload * @param[in] apdu_buf the APDU payload
* @return whether the command was successful or not * @return whether the command was successful or not
*/ */
bool handle_eip712_struct_def(const uint8_t *const apdu_buf) bool handle_eip712_struct_def(const uint8_t *const apdu_buf) {
{
bool ret = true; bool ret = true;
if (eip712_context == NULL) if (eip712_context == NULL) {
{
ret = eip712_context_init(); ret = eip712_context_init();
} }
if (ret) if (ret) {
{ switch (apdu_buf[OFFSET_P2]) {
switch (apdu_buf[OFFSET_P2])
{
case P2_NAME: case P2_NAME:
ret = set_struct_name(apdu_buf[OFFSET_LC], &apdu_buf[OFFSET_CDATA]); ret = set_struct_name(apdu_buf[OFFSET_LC], &apdu_buf[OFFSET_CDATA]);
break; break;
@@ -65,8 +58,8 @@ bool handle_eip712_struct_def(const uint8_t *const apdu_buf)
break; break;
default: default:
PRINTF("Unknown P2 0x%x for APDU 0x%x\n", PRINTF("Unknown P2 0x%x for APDU 0x%x\n",
apdu_buf[OFFSET_P2], apdu_buf[OFFSET_P2],
apdu_buf[OFFSET_INS]); apdu_buf[OFFSET_INS]);
apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; apdu_response_code = APDU_RESPONSE_INVALID_P1_P2;
ret = false; ret = false;
} }
@@ -81,26 +74,18 @@ bool handle_eip712_struct_def(const uint8_t *const apdu_buf)
* @param[in] apdu_buf the APDU payload * @param[in] apdu_buf the APDU payload
* @return whether the command was successful or not * @return whether the command was successful or not
*/ */
bool handle_eip712_struct_impl(const uint8_t *const apdu_buf) bool handle_eip712_struct_impl(const uint8_t *const apdu_buf) {
{
bool ret = false; bool ret = false;
bool reply_apdu = true; bool reply_apdu = true;
if (eip712_context == NULL) if (eip712_context == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
} } else {
else switch (apdu_buf[OFFSET_P2]) {
{
switch (apdu_buf[OFFSET_P2])
{
case P2_NAME: case P2_NAME:
// set root type // set root type
if ((ret = path_set_root((char*)&apdu_buf[OFFSET_CDATA], if ((ret = path_set_root((char *) &apdu_buf[OFFSET_CDATA], apdu_buf[OFFSET_LC]))) {
apdu_buf[OFFSET_LC]))) if (N_storage.verbose_eip712) {
{
if (N_storage.verbose_eip712)
{
ui_712_review_struct(path_get_root()); ui_712_review_struct(path_get_root());
reply_apdu = false; reply_apdu = false;
} }
@@ -110,14 +95,12 @@ bool handle_eip712_struct_impl(const uint8_t *const apdu_buf)
case P2_FIELD: case P2_FIELD:
if ((ret = field_hash(&apdu_buf[OFFSET_CDATA], if ((ret = field_hash(&apdu_buf[OFFSET_CDATA],
apdu_buf[OFFSET_LC], apdu_buf[OFFSET_LC],
apdu_buf[OFFSET_P1] != P1_COMPLETE))) apdu_buf[OFFSET_P1] != P1_COMPLETE))) {
{
reply_apdu = false; reply_apdu = false;
} }
break; break;
case P2_ARRAY: case P2_ARRAY:
ret = path_new_array_depth(&apdu_buf[OFFSET_CDATA], ret = path_new_array_depth(&apdu_buf[OFFSET_CDATA], apdu_buf[OFFSET_LC]);
apdu_buf[OFFSET_LC]);
break; break;
default: default:
PRINTF("Unknown P2 0x%x for APDU 0x%x\n", PRINTF("Unknown P2 0x%x for APDU 0x%x\n",
@@ -126,8 +109,7 @@ bool handle_eip712_struct_impl(const uint8_t *const apdu_buf)
apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; apdu_response_code = APDU_RESPONSE_INVALID_P1_P2;
} }
} }
if (reply_apdu) if (reply_apdu) {
{
handle_eip712_return_code(ret); handle_eip712_return_code(ret);
} }
return ret; return ret;
@@ -139,54 +121,43 @@ bool handle_eip712_struct_impl(const uint8_t *const apdu_buf)
* @param[in] apdu_buf the APDU payload * @param[in] apdu_buf the APDU payload
* @return whether the command was successful or not * @return whether the command was successful or not
*/ */
bool handle_eip712_filtering(const uint8_t *const apdu_buf) bool handle_eip712_filtering(const uint8_t *const apdu_buf) {
{
bool ret = true; bool ret = true;
bool reply_apdu = true; bool reply_apdu = true;
e_filtering_type type; e_filtering_type type;
if (eip712_context == NULL) if (eip712_context == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
ret = false; ret = false;
} } else {
else switch (apdu_buf[OFFSET_P1]) {
{
switch (apdu_buf[OFFSET_P1])
{
case P1_ACTIVATE: case P1_ACTIVATE:
if (!N_storage.verbose_eip712) if (!N_storage.verbose_eip712) {
{
ui_712_set_filtering_mode(EIP712_FILTERING_FULL); ui_712_set_filtering_mode(EIP712_FILTERING_FULL);
ret = compute_schema_hash(); ret = compute_schema_hash();
} }
break; break;
case P1_CONTRACT_NAME: case P1_CONTRACT_NAME:
case P1_FIELD_NAME: case P1_FIELD_NAME:
type = (apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) type = (apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) ? FILTERING_CONTRACT_NAME
? FILTERING_CONTRACT_NAME : FILTERING_STRUCT_FIELD;
: FILTERING_STRUCT_FIELD; if (ui_712_get_filtering_mode() == EIP712_FILTERING_FULL) {
if (ui_712_get_filtering_mode() == EIP712_FILTERING_FULL) ret =
{ provide_filtering_info(&apdu_buf[OFFSET_CDATA], apdu_buf[OFFSET_LC], type);
ret = provide_filtering_info(&apdu_buf[OFFSET_CDATA], if ((apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) && ret) {
apdu_buf[OFFSET_LC],
type);
if ((apdu_buf[OFFSET_P1] == P1_CONTRACT_NAME) && ret)
{
reply_apdu = false; reply_apdu = false;
} }
} }
break; break;
default: default:
PRINTF("Unknown P1 0x%x for APDU 0x%x\n", PRINTF("Unknown P1 0x%x for APDU 0x%x\n",
apdu_buf[OFFSET_P1], apdu_buf[OFFSET_P1],
apdu_buf[OFFSET_INS]); apdu_buf[OFFSET_INS]);
apdu_response_code = APDU_RESPONSE_INVALID_P1_P2; apdu_response_code = APDU_RESPONSE_INVALID_P1_P2;
ret = false; ret = false;
} }
} }
if (reply_apdu) if (reply_apdu) {
{
handle_eip712_return_code(ret); handle_eip712_return_code(ret);
} }
return ret; return ret;
@@ -198,32 +169,24 @@ bool handle_eip712_filtering(const uint8_t *const apdu_buf)
* @param[in] apdu_buf the APDU payload * @param[in] apdu_buf the APDU payload
* @return whether the command was successful or not * @return whether the command was successful or not
*/ */
bool handle_eip712_sign(const uint8_t *const apdu_buf) bool handle_eip712_sign(const uint8_t *const apdu_buf) {
{
bool ret = false; bool ret = false;
uint8_t length = apdu_buf[OFFSET_LC]; uint8_t length = apdu_buf[OFFSET_LC];
if (eip712_context == NULL) if (eip712_context == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
} } else if (parseBip32(&apdu_buf[OFFSET_CDATA], &length, &tmpCtx.messageSigningContext.bip32) !=
else if (parseBip32(&apdu_buf[OFFSET_CDATA], NULL) {
&length, if (!N_storage.verbose_eip712 && (ui_712_get_filtering_mode() == EIP712_FILTERING_BASIC)) {
&tmpCtx.messageSigningContext.bip32) != NULL)
{
if (!N_storage.verbose_eip712 && (ui_712_get_filtering_mode() == EIP712_FILTERING_BASIC))
{
ui_712_message_hash(); ui_712_message_hash();
} }
ret = true; ret = true;
ui_712_end_sign(); ui_712_end_sign();
} }
if (!ret) if (!ret) {
{
handle_eip712_return_code(ret); handle_eip712_return_code(ret);
} }
return ret; return ret;
} }
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -7,27 +7,27 @@
#include <stdint.h> #include <stdint.h>
// APDUs P1 // APDUs P1
#define P1_COMPLETE 0x00 #define P1_COMPLETE 0x00
#define P1_PARTIAL 0xFF #define P1_PARTIAL 0xFF
#define P1_ACTIVATE 0x00 #define P1_ACTIVATE 0x00
#define P1_CONTRACT_NAME 0x0F #define P1_CONTRACT_NAME 0x0F
#define P1_FIELD_NAME 0xFF #define P1_FIELD_NAME 0xFF
// APDUs P2 // APDUs P2
#define P2_NAME 0x00 #define P2_NAME 0x00
#define P2_ARRAY 0x0F #define P2_ARRAY 0x0F
#define P2_FIELD 0xFF #define P2_FIELD 0xFF
#define P2_KEY 0x00 #define P2_KEY 0x00
#define P2_VALUE 0xFF #define P2_VALUE 0xFF
#define DOMAIN_STRUCT_NAME "EIP712Domain" #define DOMAIN_STRUCT_NAME "EIP712Domain"
bool handle_eip712_struct_def(const uint8_t *const apdu_buf); bool handle_eip712_struct_def(const uint8_t *const apdu_buf);
bool handle_eip712_struct_impl(const uint8_t *const apdu_buf); bool handle_eip712_struct_impl(const uint8_t *const apdu_buf);
bool handle_eip712_sign(const uint8_t *const apdu_buf); bool handle_eip712_sign(const uint8_t *const apdu_buf);
bool handle_eip712_filtering(const uint8_t *const apdu_buf); bool handle_eip712_filtering(const uint8_t *const apdu_buf);
void handle_eip712_return_code(bool success); void handle_eip712_return_code(bool success);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // EIP712_H_ #endif // EIP712_H_

View File

@@ -10,9 +10,9 @@
#include "field_hash.h" #include "field_hash.h"
#include "ui_logic.h" #include "ui_logic.h"
#include "typed_data.h" #include "typed_data.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "shared_context.h" // reset_app_context #include "shared_context.h" // reset_app_context
#include "ui_callbacks.h" // ui_idle #include "ui_callbacks.h" // ui_idle
s_eip712_context *eip712_context = NULL; s_eip712_context *eip712_context = NULL;
@@ -21,38 +21,32 @@ s_eip712_context *eip712_context = NULL;
* *
* @return a boolean indicating if the initialization was successful or not * @return a boolean indicating if the initialization was successful or not
*/ */
bool eip712_context_init(void) bool eip712_context_init(void) {
{
// init global variables // init global variables
mem_init(); mem_init();
if ((eip712_context = MEM_ALLOC_AND_ALIGN_TYPE(*eip712_context)) == NULL) if ((eip712_context = MEM_ALLOC_AND_ALIGN_TYPE(*eip712_context)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
if (sol_typenames_init() == false) if (sol_typenames_init() == false) {
{
return false; return false;
} }
if (path_init() == false) if (path_init() == false) {
{
return false; return false;
} }
if (field_hash_init() == false) if (field_hash_init() == false) {
{
return false; return false;
} }
if (ui_712_init() == false) if (ui_712_init() == false) {
{
return false; return false;
} }
if (typed_data_init() == false) // this needs to be initialized last ! if (typed_data_init() == false) // this needs to be initialized last !
{ {
return false; return false;
} }
@@ -63,8 +57,7 @@ bool eip712_context_init(void)
/** /**
* De-initialize the EIP712 context * De-initialize the EIP712 context
*/ */
void eip712_context_deinit(void) void eip712_context_deinit(void) {
{
typed_data_deinit(); typed_data_deinit();
path_deinit(); path_deinit();
field_hash_deinit(); field_hash_deinit();

View File

@@ -4,19 +4,18 @@
#ifdef HAVE_EIP712_FULL_SUPPORT #ifdef HAVE_EIP712_FULL_SUPPORT
#include <stdbool.h> #include <stdbool.h>
#include "ethUstream.h" // ADDRESS_LENGTH #include "ethUstream.h" // ADDRESS_LENGTH
typedef struct typedef struct {
{
uint8_t contract_addr[ADDRESS_LENGTH]; uint8_t contract_addr[ADDRESS_LENGTH];
uint8_t schema_hash[224 / 8]; uint8_t schema_hash[224 / 8];
} s_eip712_context; } s_eip712_context;
extern s_eip712_context *eip712_context; extern s_eip712_context *eip712_context;
bool eip712_context_init(void); bool eip712_context_init(void);
void eip712_context_deinit(void); void eip712_context_deinit(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // EIP712_CTX_H_ #endif // EIP712_CTX_H_

View File

@@ -5,13 +5,9 @@
#include "encode_field.h" #include "encode_field.h"
#include "mem.h" #include "mem.h"
#include "shared_context.h" #include "shared_context.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
typedef enum typedef enum { MSB, LSB } e_padding_type;
{
MSB,
LSB
} e_padding_type;
/** /**
* Encode a field value to 32 bytes (padded) * Encode a field value to 32 bytes (padded)
@@ -25,20 +21,17 @@ typedef enum
static void *field_encode(const uint8_t *const value, static void *field_encode(const uint8_t *const value,
uint8_t length, uint8_t length,
e_padding_type ptype, e_padding_type ptype,
uint8_t pval) uint8_t pval) {
{
uint8_t *padded_value; uint8_t *padded_value;
uint8_t start_idx; uint8_t start_idx;
if (length > EIP_712_ENCODED_FIELD_LENGTH) // sanity check if (length > EIP_712_ENCODED_FIELD_LENGTH) // sanity check
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return NULL; return NULL;
} }
if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) {
{ switch (ptype) {
switch (ptype)
{
case MSB: case MSB:
memset(padded_value, pval, EIP_712_ENCODED_FIELD_LENGTH - length); memset(padded_value, pval, EIP_712_ENCODED_FIELD_LENGTH - length);
start_idx = EIP_712_ENCODED_FIELD_LENGTH - length; start_idx = EIP_712_ENCODED_FIELD_LENGTH - length;
@@ -49,12 +42,10 @@ static void *field_encode(const uint8_t *const value,
break; break;
default: default:
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; // should not be here return NULL; // should not be here
} }
memcpy(&padded_value[start_idx], value, length); memcpy(&padded_value[start_idx], value, length);
} } else {
else
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
} }
return padded_value; return padded_value;
@@ -67,8 +58,7 @@ static void *field_encode(const uint8_t *const value,
* @param[in] length its byte-length * @param[in] length its byte-length
* @return the encoded value * @return the encoded value
*/ */
void *encode_uint(const uint8_t *const value, uint8_t length) void *encode_uint(const uint8_t *const value, uint8_t length) {
{
// no length check here since it will be checked by field_encode // no length check here since it will be checked by field_encode
return field_encode(value, length, MSB, 0x00); return field_encode(value, length, MSB, 0x00);
} }
@@ -81,16 +71,13 @@ void *encode_uint(const uint8_t *const value, uint8_t length)
* @param[in] typesize the type size in bytes * @param[in] typesize the type size in bytes
* @return the encoded value * @return the encoded value
*/ */
void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize) void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize) {
{
uint8_t padding_value; uint8_t padding_value;
if ((length == typesize) && (value[0] & (1 << 7))) // negative number if ((length == typesize) && (value[0] & (1 << 7))) // negative number
{ {
padding_value = 0xFF; padding_value = 0xFF;
} } else {
else
{
padding_value = 0x00; padding_value = 0x00;
} }
// no length check here since it will be checked by field_encode // no length check here since it will be checked by field_encode
@@ -104,8 +91,7 @@ void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize
* @param[in] length its byte-length * @param[in] length its byte-length
* @return the encoded value * @return the encoded value
*/ */
void *encode_bytes(const uint8_t *const value, uint8_t length) void *encode_bytes(const uint8_t *const value, uint8_t length) {
{
// no length check here since it will be checked by field_encode // no length check here since it will be checked by field_encode
return field_encode(value, length, LSB, 0x00); return field_encode(value, length, LSB, 0x00);
} }
@@ -117,14 +103,13 @@ void *encode_bytes(const uint8_t *const value, uint8_t length)
* @param[in] length its byte-length * @param[in] length its byte-length
* @return the encoded value * @return the encoded value
*/ */
void *encode_boolean(const bool *const value, uint8_t length) void *encode_boolean(const bool *const value, uint8_t length) {
{ if (length != 1) // sanity check
if (length != 1) // sanity check
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return NULL; return NULL;
} }
return encode_uint((uint8_t*)value, length); return encode_uint((uint8_t *) value, length);
} }
/** /**
@@ -134,9 +119,8 @@ void *encode_boolean(const bool *const value, uint8_t length)
* @param[in] length its byte-length * @param[in] length its byte-length
* @return the encoded value * @return the encoded value
*/ */
void *encode_address(const uint8_t *const value, uint8_t length) void *encode_address(const uint8_t *const value, uint8_t length) {
{ if (length != ADDRESS_LENGTH) // sanity check
if (length != ADDRESS_LENGTH) // sanity check
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return NULL; return NULL;
@@ -144,4 +128,4 @@ void *encode_address(const uint8_t *const value, uint8_t length)
return encode_uint(value, length); return encode_uint(value, length);
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,14 +6,14 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define EIP_712_ENCODED_FIELD_LENGTH 32 #define EIP_712_ENCODED_FIELD_LENGTH 32
void *encode_uint(const uint8_t *const value, uint8_t length); void *encode_uint(const uint8_t *const value, uint8_t length);
void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize); void *encode_int(const uint8_t *const value, uint8_t length, uint8_t typesize);
void *encode_boolean(const bool *const value, uint8_t length); void *encode_boolean(const bool *const value, uint8_t length);
void *encode_address(const uint8_t *const value, uint8_t length); void *encode_address(const uint8_t *const value, uint8_t length);
void *encode_bytes(const uint8_t *const value, uint8_t length); void *encode_bytes(const uint8_t *const value, uint8_t length);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // ENCODE_FIELD_H_ #endif // ENCODE_FIELD_H_

View File

@@ -8,10 +8,10 @@
#include "mem_utils.h" #include "mem_utils.h"
#include "shared_context.h" #include "shared_context.h"
#include "ui_logic.h" #include "ui_logic.h"
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "context.h" // contract_addr #include "context.h" // contract_addr
#include "utils.h" // u64_from_BE #include "utils.h" // u64_from_BE
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
#include "commands_712.h" #include "commands_712.h"
#include "hash_bytes.h" #include "hash_bytes.h"
@@ -23,12 +23,9 @@ static s_field_hashing *fh = NULL;
* *
* @return whether the initialization was successful or not * @return whether the initialization was successful or not
*/ */
bool field_hash_init(void) bool field_hash_init(void) {
{ if (fh == NULL) {
if (fh == NULL) if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL) {
{
if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL)
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -40,8 +37,7 @@ bool field_hash_init(void)
/** /**
* Deinitialize the field hash context * Deinitialize the field hash context
*/ */
void field_hash_deinit(void) void field_hash_deinit(void) {
{
fh = NULL; fh = NULL;
} }
@@ -55,18 +51,16 @@ void field_hash_deinit(void)
*/ */
static const uint8_t *field_hash_prepare(const void *const field_ptr, static const uint8_t *field_hash_prepare(const void *const field_ptr,
const uint8_t *data, const uint8_t *data,
uint8_t *data_length) uint8_t *data_length) {
{
e_type field_type; e_type field_type;
field_type = struct_field_type(field_ptr); field_type = struct_field_type(field_ptr);
fh->remaining_size = __builtin_bswap16(*(uint16_t*)&data[0]); // network byte order fh->remaining_size = __builtin_bswap16(*(uint16_t *) &data[0]); // network byte order
data += sizeof(uint16_t); data += sizeof(uint16_t);
*data_length -= sizeof(uint16_t); *data_length -= sizeof(uint16_t);
fh->state = FHS_WAITING_FOR_MORE; fh->state = FHS_WAITING_FOR_MORE;
if (IS_DYN(field_type)) if (IS_DYN(field_type)) {
{ cx_keccak_init(&global_sha3, 256); // init hash
cx_keccak_init(&global_sha3, 256); // init hash
ui_712_new_field(field_ptr, data, *data_length); ui_712_new_field(field_ptr, data, *data_length);
} }
return data; return data;
@@ -84,14 +78,12 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr,
*/ */
static const uint8_t *field_hash_finalize_static(const void *const field_ptr, static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
const uint8_t *const data, const uint8_t *const data,
uint8_t data_length) uint8_t data_length) {
{
uint8_t *value = NULL; uint8_t *value = NULL;
e_type field_type; e_type field_type;
field_type = struct_field_type(field_ptr); field_type = struct_field_type(field_ptr);
switch (field_type) switch (field_type) {
{
case TYPE_SOL_INT: case TYPE_SOL_INT:
value = encode_int(data, data_length, get_struct_field_typesize(field_ptr)); value = encode_int(data, data_length, get_struct_field_typesize(field_ptr));
break; break;
@@ -105,7 +97,7 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
value = encode_address(data, data_length); value = encode_address(data, data_length);
break; break;
case TYPE_SOL_BOOL: case TYPE_SOL_BOOL:
value = encode_boolean((bool*)data, data_length); value = encode_boolean((bool *) data, data_length);
break; break;
case TYPE_CUSTOM: case TYPE_CUSTOM:
default: default:
@@ -113,8 +105,7 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
PRINTF("Unknown solidity type!\n"); PRINTF("Unknown solidity type!\n");
} }
if (value == NULL) if (value == NULL) {
{
return NULL; return NULL;
} }
ui_712_new_field(field_ptr, data, data_length); ui_712_new_field(field_ptr, data, data_length);
@@ -128,22 +119,15 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
* *
* @return pointer to the hash, \ref NULL if it failed * @return pointer to the hash, \ref NULL if it failed
*/ */
static uint8_t *field_hash_finalize_dynamic(void) static uint8_t *field_hash_finalize_dynamic(void) {
{
uint8_t *value; uint8_t *value;
if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return NULL; return NULL;
} }
// copy hash into memory // copy hash into memory
cx_hash((cx_hash_t*)&global_sha3, cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, value, KECCAK256_HASH_BYTESIZE);
CX_LAST,
NULL,
0,
value,
KECCAK256_HASH_BYTESIZE);
return value; return value;
} }
@@ -153,24 +137,20 @@ static uint8_t *field_hash_finalize_dynamic(void)
* @param[in] field_type the struct field's type * @param[in] field_type the struct field's type
* @param[in] hash the field hash * @param[in] hash the field hash
*/ */
static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash) static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash) {
{
uint8_t len; uint8_t len;
if (IS_DYN(field_type)) if (IS_DYN(field_type)) {
{
len = KECCAK256_HASH_BYTESIZE; len = KECCAK256_HASH_BYTESIZE;
} } else {
else
{
len = EIP_712_ENCODED_FIELD_LENGTH; len = EIP_712_ENCODED_FIELD_LENGTH;
} }
// last thing in mem is the hash of the previous field // last thing in mem is the hash of the previous field
// and just before it is the current hash context // and just before it is the current hash context
cx_sha3_t *hash_ctx = (cx_sha3_t*)(hash - sizeof(cx_sha3_t)); cx_sha3_t *hash_ctx = (cx_sha3_t *) (hash - sizeof(cx_sha3_t));
// continue the progressive hash on it // continue the progressive hash on it
hash_nbytes(hash, len, (cx_hash_t*)hash_ctx); hash_nbytes(hash, len, (cx_hash_t *) hash_ctx);
// deallocate it // deallocate it
mem_dealloc(len); mem_dealloc(len);
} }
@@ -187,29 +167,23 @@ static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash)
*/ */
static bool field_hash_domain_special_fields(const void *const field_ptr, static bool field_hash_domain_special_fields(const void *const field_ptr,
const uint8_t *const data, const uint8_t *const data,
uint8_t data_length) uint8_t data_length) {
{
const char *key; const char *key;
uint8_t keylen; uint8_t keylen;
key = get_struct_field_keyname(field_ptr, &keylen); key = get_struct_field_keyname(field_ptr, &keylen);
// copy contract address into context // copy contract address into context
if (strncmp(key, "verifyingContract", keylen) == 0) if (strncmp(key, "verifyingContract", keylen) == 0) {
{ if (data_length != sizeof(eip712_context->contract_addr)) {
if (data_length != sizeof(eip712_context->contract_addr))
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
PRINTF("Unexpected verifyingContract length!\n"); PRINTF("Unexpected verifyingContract length!\n");
return false; return false;
} }
memcpy(eip712_context->contract_addr, data, data_length); memcpy(eip712_context->contract_addr, data, data_length);
} } else if (strncmp(key, "chainId", keylen) == 0) {
else if (strncmp(key, "chainId", keylen) == 0)
{
uint64_t chainId = u64_from_BE(data, data_length); uint64_t chainId = u64_from_BE(data, data_length);
if (chainId != chainConfig->chainId) if (chainId != chainConfig->chainId) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
PRINTF("EIP712Domain chain ID mismatch, expected 0x%.*h, got 0x%.*h !\n", PRINTF("EIP712Domain chain ID mismatch, expected 0x%.*h, got 0x%.*h !\n",
sizeof(chainConfig->chainId), sizeof(chainConfig->chainId),
@@ -232,35 +206,25 @@ static bool field_hash_domain_special_fields(const void *const field_ptr,
*/ */
static bool field_hash_finalize(const void *const field_ptr, static bool field_hash_finalize(const void *const field_ptr,
const uint8_t *const data, const uint8_t *const data,
uint8_t data_length) uint8_t data_length) {
{
const uint8_t *value = NULL; const uint8_t *value = NULL;
e_type field_type; e_type field_type;
field_type = struct_field_type(field_ptr); field_type = struct_field_type(field_ptr);
if (!IS_DYN(field_type)) if (!IS_DYN(field_type)) {
{ if ((value = field_hash_finalize_static(field_ptr, data, data_length)) == NULL) {
if ((value = field_hash_finalize_static(field_ptr,
data,
data_length)) == NULL)
{
return false; return false;
} }
} } else {
else if ((value = field_hash_finalize_dynamic()) == NULL) {
{
if ((value = field_hash_finalize_dynamic()) == NULL)
{
return false; return false;
} }
} }
field_hash_feed_parent(field_type, value); field_hash_feed_parent(field_type, value);
if (path_get_root_type() == ROOT_DOMAIN) if (path_get_root_type() == ROOT_DOMAIN) {
{ if (field_hash_domain_special_fields(field_ptr, data, data_length) == false) {
if (field_hash_domain_special_fields(field_ptr, data, data_length) == false)
{
return false; return false;
} }
} }
@@ -278,50 +242,40 @@ static bool field_hash_finalize(const void *const field_ptr,
* @param[in] partial whether there is more of that data coming later or not * @param[in] partial whether there is more of that data coming later or not
* @return whether the data hashing was successful or not * @return whether the data hashing was successful or not
*/ */
bool field_hash(const uint8_t *data, bool field_hash(const uint8_t *data, uint8_t data_length, bool partial) {
uint8_t data_length,
bool partial)
{
const void *field_ptr; const void *field_ptr;
e_type field_type; e_type field_type;
if ((fh == NULL) || ((field_ptr = path_get_field()) == NULL)) if ((fh == NULL) || ((field_ptr = path_get_field()) == NULL)) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
field_type = struct_field_type(field_ptr); field_type = struct_field_type(field_ptr);
if (fh->state == FHS_IDLE) // first packet for this frame if (fh->state == FHS_IDLE) // first packet for this frame
{ {
data = field_hash_prepare(field_ptr, data, &data_length); data = field_hash_prepare(field_ptr, data, &data_length);
} }
if (data_length > fh->remaining_size) if (data_length > fh->remaining_size) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
fh->remaining_size -= data_length; fh->remaining_size -= data_length;
// if a dynamic type -> continue progressive hash // if a dynamic type -> continue progressive hash
if (IS_DYN(field_type)) if (IS_DYN(field_type)) {
{ hash_nbytes(data, data_length, (cx_hash_t *) &global_sha3);
hash_nbytes(data, data_length, (cx_hash_t*)&global_sha3);
} }
if (fh->remaining_size == 0) if (fh->remaining_size == 0) {
{ if (partial) // only makes sense if marked as complete
if (partial) // only makes sense if marked as complete
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if (field_hash_finalize(field_ptr, data, data_length) == false) if (field_hash_finalize(field_ptr, data, data_length) == false) {
{
return false; return false;
} }
} } else {
else if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
{
if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
@@ -332,4 +286,4 @@ bool field_hash(const uint8_t *data,
return true; return true;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,26 +6,19 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define IS_DYN(type) (((type) == TYPE_SOL_STRING) || ((type) == TYPE_SOL_BYTES_DYN)) #define IS_DYN(type) (((type) == TYPE_SOL_STRING) || ((type) == TYPE_SOL_BYTES_DYN))
typedef enum typedef enum { FHS_IDLE, FHS_WAITING_FOR_MORE } e_field_hashing_state;
{
FHS_IDLE,
FHS_WAITING_FOR_MORE
} e_field_hashing_state;
typedef struct typedef struct {
{ uint16_t remaining_size;
uint16_t remaining_size; uint8_t state; // e_field_hashing_state
uint8_t state; // e_field_hashing_state } s_field_hashing;
} s_field_hashing;
bool field_hash_init(void); bool field_hash_init(void);
void field_hash_deinit(void); void field_hash_deinit(void);
bool field_hash(const uint8_t *data, bool field_hash(const uint8_t *data, uint8_t data_length, bool partial);
uint8_t data_length,
bool partial);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // FIELD_HASH_H_ #endif // FIELD_HASH_H_

View File

@@ -2,59 +2,49 @@
#include "filtering.h" #include "filtering.h"
#include "hash_bytes.h" #include "hash_bytes.h"
#include "ethUstream.h" // INT256_LENGTH #include "ethUstream.h" // INT256_LENGTH
#include "apdu_constants.h" // APDU return codes #include "apdu_constants.h" // APDU return codes
#include "context.h" #include "context.h"
#include "commands_712.h" #include "commands_712.h"
#include "typed_data.h" #include "typed_data.h"
#include "path.h" #include "path.h"
#include "ui_logic.h" #include "ui_logic.h"
#ifdef HAVE_EIP712_TESTING_KEY #ifdef HAVE_EIP712_TESTING_KEY
static const uint8_t EIP712_FEEDER_PUBLIC_KEY[] = { static const uint8_t EIP712_FEEDER_PUBLIC_KEY[] = {
0x04, 0x4c, 0xca, 0x8f, 0xad, 0x49, 0x6a, 0xa5, 0x04, 0x0a, 0x00, 0xa7, 0xeb, 0x2f, 0x04, 0x4c, 0xca, 0x8f, 0xad, 0x49, 0x6a, 0xa5, 0x04, 0x0a, 0x00, 0xa7, 0xeb,
0x5c, 0xc3, 0xb8, 0x53, 0x76, 0xd8, 0x8b, 0xa1, 0x47, 0xa7, 0xd7, 0x05, 0x4a, 0x99, 0x2f, 0x5c, 0xc3, 0xb8, 0x53, 0x76, 0xd8, 0x8b, 0xa1, 0x47, 0xa7, 0xd7, 0x05,
0xc6, 0x40, 0x56, 0x18, 0x87, 0xfe, 0x17, 0xa0, 0x96, 0xe3, 0x6c, 0x3b, 0x52, 0x3b, 0x4a, 0x99, 0xc6, 0x40, 0x56, 0x18, 0x87, 0xfe, 0x17, 0xa0, 0x96, 0xe3, 0x6c,
0x24, 0x4f, 0x3e, 0x2f, 0xf7, 0xf8, 0x40, 0xae, 0x26, 0xc4, 0xe7, 0x7a, 0xd3, 0xbc, 0x3b, 0x52, 0x3b, 0x24, 0x4f, 0x3e, 0x2f, 0xf7, 0xf8, 0x40, 0xae, 0x26, 0xc4,
0x73, 0x9a, 0xf5, 0xde, 0x6f, 0x2d, 0x77, 0xa7, 0xb6 0xe7, 0x7a, 0xd3, 0xbc, 0x73, 0x9a, 0xf5, 0xde, 0x6f, 0x2d, 0x77, 0xa7, 0xb6};
}; #endif // HAVE_EIP712_TESTING_KEY
#endif // HAVE_EIP712_TESTING_KEY
/** /**
* Reconstruct the field path and hash it * Reconstruct the field path and hash it
* *
* @param[in] hash_ctx the hashing context * @param[in] hash_ctx the hashing context
*/ */
static void hash_filtering_path(cx_hash_t *const hash_ctx) static void hash_filtering_path(cx_hash_t *const hash_ctx) {
{
const void *field_ptr; const void *field_ptr;
const char *key; const char *key;
uint8_t key_len; uint8_t key_len;
for (uint8_t i = 0; i < path_get_depth_count(); ++i) for (uint8_t i = 0; i < path_get_depth_count(); ++i) {
{ if (i > 0) {
if (i > 0)
{
hash_byte('.', hash_ctx); hash_byte('.', hash_ctx);
} }
if ((field_ptr = path_get_nth_field(i + 1)) != NULL) if ((field_ptr = path_get_nth_field(i + 1)) != NULL) {
{ if ((key = get_struct_field_keyname(field_ptr, &key_len)) != NULL) {
if ((key = get_struct_field_keyname(field_ptr, &key_len)) != NULL)
{
// field name // field name
hash_nbytes((uint8_t*)key, key_len, hash_ctx); hash_nbytes((uint8_t *) key, key_len, hash_ctx);
// array levels // array levels
if (struct_field_is_array(field_ptr)) if (struct_field_is_array(field_ptr)) {
{
uint8_t lvl_count; uint8_t lvl_count;
get_struct_field_array_lvls_array(field_ptr, &lvl_count); get_struct_field_array_lvls_array(field_ptr, &lvl_count);
for (int j = 0; j < lvl_count; ++j) for (int j = 0; j < lvl_count; ++j) {
{ hash_nbytes((uint8_t *) ".[]", 3, hash_ctx);
hash_nbytes((uint8_t*)".[]", 3, hash_ctx);
} }
} }
} }
@@ -76,8 +66,7 @@ static bool verify_filtering_signature(uint8_t dname_length,
const char *const dname, const char *const dname,
uint8_t sig_length, uint8_t sig_length,
const uint8_t *const sig, const uint8_t *const sig,
e_filtering_type type) e_filtering_type type) {
{
uint8_t hash[INT256_LENGTH]; uint8_t hash[INT256_LENGTH];
cx_ecfp_public_key_t verifying_key; cx_ecfp_public_key_t verifying_key;
cx_sha256_t hash_ctx; cx_sha256_t hash_ctx;
@@ -87,35 +76,27 @@ static bool verify_filtering_signature(uint8_t dname_length,
// Chain ID // Chain ID
chain_id = __builtin_bswap64(chainConfig->chainId); chain_id = __builtin_bswap64(chainConfig->chainId);
hash_nbytes((uint8_t*)&chain_id, sizeof(chain_id), (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) &chain_id, sizeof(chain_id), (cx_hash_t *) &hash_ctx);
// Contract address // Contract address
hash_nbytes(eip712_context->contract_addr, hash_nbytes(eip712_context->contract_addr,
sizeof(eip712_context->contract_addr), sizeof(eip712_context->contract_addr),
(cx_hash_t*)&hash_ctx); (cx_hash_t *) &hash_ctx);
// Schema hash // Schema hash
hash_nbytes(eip712_context->schema_hash, hash_nbytes(eip712_context->schema_hash,
sizeof(eip712_context->schema_hash), sizeof(eip712_context->schema_hash),
(cx_hash_t*)&hash_ctx); (cx_hash_t *) &hash_ctx);
if (type == FILTERING_STRUCT_FIELD) if (type == FILTERING_STRUCT_FIELD) {
{ hash_filtering_path((cx_hash_t *) &hash_ctx);
hash_filtering_path((cx_hash_t*)&hash_ctx);
} }
// Display name // Display name
hash_nbytes((uint8_t*)dname, hash_nbytes((uint8_t *) dname, sizeof(char) * dname_length, (cx_hash_t *) &hash_ctx);
sizeof(char) * dname_length,
(cx_hash_t*)&hash_ctx);
// Finalize hash // Finalize hash
cx_hash((cx_hash_t*)&hash_ctx, cx_hash((cx_hash_t *) &hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH);
CX_LAST,
NULL,
0,
hash,
INT256_LENGTH);
cx_ecfp_init_public_key(CX_CURVE_256K1, cx_ecfp_init_public_key(CX_CURVE_256K1,
#ifdef HAVE_EIP712_TESTING_KEY #ifdef HAVE_EIP712_TESTING_KEY
@@ -126,14 +107,7 @@ static bool verify_filtering_signature(uint8_t dname_length,
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
#endif #endif
&verifying_key); &verifying_key);
if (!cx_ecdsa_verify(&verifying_key, if (!cx_ecdsa_verify(&verifying_key, CX_LAST, CX_SHA256, hash, sizeof(hash), sig, sig_length)) {
CX_LAST,
CX_SHA256,
hash,
sizeof(hash),
sig,
sig_length))
{
#ifndef HAVE_BYPASS_SIGNATURES #ifndef HAVE_BYPASS_SIGNATURES
PRINTF("Invalid EIP-712 filtering signature\n"); PRINTF("Invalid EIP-712 filtering signature\n");
return false; return false;
@@ -150,56 +124,42 @@ static bool verify_filtering_signature(uint8_t dname_length,
* @param[in] type the type of filtering * @param[in] type the type of filtering
* @return if everything went well or not * @return if everything went well or not
*/ */
bool provide_filtering_info(const uint8_t *const payload, bool provide_filtering_info(const uint8_t *const payload, uint8_t length, e_filtering_type type) {
uint8_t length,
e_filtering_type type)
{
bool ret = false; bool ret = false;
uint8_t dname_len; uint8_t dname_len;
const char *dname; const char *dname;
uint8_t sig_len; uint8_t sig_len;
const uint8_t *sig; const uint8_t *sig;
if (type == FILTERING_CONTRACT_NAME) if (type == FILTERING_CONTRACT_NAME) {
if (path_get_root_type() != ROOT_DOMAIN) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
} else // FILTERING_STRUCT_FIELD
{ {
if (path_get_root_type() != ROOT_DOMAIN) if (path_get_root_type() != ROOT_MESSAGE) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
} }
else // FILTERING_STRUCT_FIELD if (length > 0) {
{
if (path_get_root_type() != ROOT_MESSAGE)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
}
if (length > 0)
{
dname_len = payload[0]; dname_len = payload[0];
if ((1 + dname_len) < length) if ((1 + dname_len) < length) {
{ dname = (char *) &payload[1];
dname = (char*)&payload[1];
sig_len = payload[1 + dname_len]; sig_len = payload[1 + dname_len];
sig = &payload[1 + dname_len + 1]; sig = &payload[1 + dname_len + 1];
if ((sig_len > 0) && ((1 + dname_len + 1 + sig_len) == length)) if ((sig_len > 0) && ((1 + dname_len + 1 + sig_len) == length)) {
{ if ((ret = verify_filtering_signature(dname_len, dname, sig_len, sig, type))) {
if ((ret = verify_filtering_signature(dname_len, dname, sig_len, sig, type))) if (type == FILTERING_CONTRACT_NAME) {
{ if (!N_storage.verbose_eip712) {
if (type == FILTERING_CONTRACT_NAME)
{
if (!N_storage.verbose_eip712)
{
ui_712_set_title("Contract", 8); ui_712_set_title("Contract", 8);
ui_712_set_value(dname, dname_len); ui_712_set_value(dname, dname_len);
ui_712_redraw_generic_step(); ui_712_redraw_generic_step();
} }
} } else // FILTERING_STRUCT_FIELD
else // FILTERING_STRUCT_FIELD
{ {
if (dname_len > 0) // don't substitute for an empty name if (dname_len > 0) // don't substitute for an empty name
{ {
ui_712_set_title(dname, dname_len); ui_712_set_title(dname, dname_len);
} }
@@ -212,4 +172,4 @@ bool provide_filtering_info(const uint8_t *const payload,
return ret; return ret;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,16 +6,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
typedef enum typedef enum { FILTERING_CONTRACT_NAME, FILTERING_STRUCT_FIELD } e_filtering_type;
{
FILTERING_CONTRACT_NAME,
FILTERING_STRUCT_FIELD
} e_filtering_type;
bool provide_filtering_info(const uint8_t *const payload, bool provide_filtering_info(const uint8_t *const payload, uint8_t length, e_filtering_type type);
uint8_t length,
e_filtering_type type);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // FILTERING_H_ #endif // FILTERING_H_

View File

@@ -5,7 +5,7 @@
#include "mem_utils.h" #include "mem_utils.h"
#include "commands_712.h" #include "commands_712.h"
#include "hash_bytes.h" #include "hash_bytes.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
/** /**
@@ -15,18 +15,16 @@
* @param[in] hash_ctx pointer to the hashing context * @param[in] hash_ctx pointer to the hashing context
* @return whether the formatting & hashing were successful or not * @return whether the formatting & hashing were successful or not
*/ */
static bool format_hash_field_type_size(const void *const field_ptr, cx_hash_t *hash_ctx) static bool format_hash_field_type_size(const void *const field_ptr, cx_hash_t *hash_ctx) {
{
uint16_t field_size; uint16_t field_size;
char *uint_str_ptr; char *uint_str_ptr;
uint8_t uint_str_len; uint8_t uint_str_len;
field_size = get_struct_field_typesize(field_ptr); field_size = get_struct_field_typesize(field_ptr);
switch (struct_field_type(field_ptr)) switch (struct_field_type(field_ptr)) {
{
case TYPE_SOL_INT: case TYPE_SOL_INT:
case TYPE_SOL_UINT: case TYPE_SOL_UINT:
field_size *= 8; // bytes -> bits field_size *= 8; // bytes -> bits
break; break;
case TYPE_SOL_BYTES_FIX: case TYPE_SOL_BYTES_FIX:
break; break;
@@ -35,12 +33,11 @@ static bool format_hash_field_type_size(const void *const field_ptr, cx_hash_t *
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((uint_str_ptr = mem_alloc_and_format_uint(field_size, &uint_str_len)) == NULL) if ((uint_str_ptr = mem_alloc_and_format_uint(field_size, &uint_str_len)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
hash_nbytes((uint8_t*)uint_str_ptr, uint_str_len, hash_ctx); hash_nbytes((uint8_t *) uint_str_ptr, uint_str_len, hash_ctx);
mem_dealloc(uint_str_len); mem_dealloc(uint_str_len);
return true; return true;
} }
@@ -52,8 +49,7 @@ static bool format_hash_field_type_size(const void *const field_ptr, cx_hash_t *
* @param[in] hash_ctx pointer to the hashing context * @param[in] hash_ctx pointer to the hashing context
* @return whether the formatting & hashing were successful or not * @return whether the formatting & hashing were successful or not
*/ */
static bool format_hash_field_type_array_levels(const void *const field_ptr, cx_hash_t *hash_ctx) static bool format_hash_field_type_array_levels(const void *const field_ptr, cx_hash_t *hash_ctx) {
{
uint8_t array_size; uint8_t array_size;
char *uint_str_ptr; char *uint_str_ptr;
uint8_t uint_str_len; uint8_t uint_str_len;
@@ -61,21 +57,18 @@ static bool format_hash_field_type_array_levels(const void *const field_ptr, cx_
uint8_t lvls_count; uint8_t lvls_count;
lvl_ptr = get_struct_field_array_lvls_array(field_ptr, &lvls_count); lvl_ptr = get_struct_field_array_lvls_array(field_ptr, &lvls_count);
while (lvls_count-- > 0) while (lvls_count-- > 0) {
{
hash_byte('[', hash_ctx); hash_byte('[', hash_ctx);
switch (struct_field_array_depth(lvl_ptr, &array_size)) switch (struct_field_array_depth(lvl_ptr, &array_size)) {
{
case ARRAY_DYNAMIC: case ARRAY_DYNAMIC:
break; break;
case ARRAY_FIXED_SIZE: case ARRAY_FIXED_SIZE:
if ((uint_str_ptr = mem_alloc_and_format_uint(array_size, &uint_str_len)) == NULL) if ((uint_str_ptr = mem_alloc_and_format_uint(array_size, &uint_str_len)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
hash_nbytes((uint8_t*)uint_str_ptr, uint_str_len, hash_ctx); hash_nbytes((uint8_t *) uint_str_ptr, uint_str_len, hash_ctx);
mem_dealloc(uint_str_len); mem_dealloc(uint_str_len);
break; break;
default: default:
@@ -96,33 +89,28 @@ static bool format_hash_field_type_array_levels(const void *const field_ptr, cx_
* @param[in] hash_ctx pointer to the hashing context * @param[in] hash_ctx pointer to the hashing context
* @return whether the formatting & hashing were successful or not * @return whether the formatting & hashing were successful or not
*/ */
bool format_hash_field_type(const void *const field_ptr, cx_hash_t *hash_ctx) bool format_hash_field_type(const void *const field_ptr, cx_hash_t *hash_ctx) {
{
const char *name; const char *name;
uint8_t length; uint8_t length;
// field type name // field type name
name = get_struct_field_typename(field_ptr, &length); name = get_struct_field_typename(field_ptr, &length);
hash_nbytes((uint8_t*)name, length, hash_ctx); hash_nbytes((uint8_t *) name, length, hash_ctx);
// field type size // field type size
if (struct_field_has_typesize(field_ptr)) if (struct_field_has_typesize(field_ptr)) {
{ if (!format_hash_field_type_size(field_ptr, hash_ctx)) {
if (!format_hash_field_type_size(field_ptr, hash_ctx))
{
return false; return false;
} }
} }
// field type array levels // field type array levels
if (struct_field_is_array(field_ptr)) if (struct_field_is_array(field_ptr)) {
{ if (!format_hash_field_type_array_levels(field_ptr, hash_ctx)) {
if (!format_hash_field_type_array_levels(field_ptr, hash_ctx))
{
return false; return false;
} }
} }
return true; return true;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -5,8 +5,8 @@
#include "cx.h" #include "cx.h"
bool format_hash_field_type(const void *const field_ptr, cx_hash_t *hash_ctx); bool format_hash_field_type(const void *const field_ptr, cx_hash_t *hash_ctx);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // FORMAT_HASH_FIELD_TYPE_H_ #endif // FORMAT_HASH_FIELD_TYPE_H_

View File

@@ -9,14 +9,8 @@
* @param[in] n number of bytes to hash * @param[in] n number of bytes to hash
* @param[in] hash_ctx pointer to the hashing context * @param[in] hash_ctx pointer to the hashing context
*/ */
void hash_nbytes(const uint8_t *const bytes_ptr, uint8_t n, cx_hash_t *const hash_ctx) void hash_nbytes(const uint8_t *const bytes_ptr, uint8_t n, cx_hash_t *const hash_ctx) {
{ cx_hash(hash_ctx, 0, bytes_ptr, n, NULL, 0);
cx_hash(hash_ctx,
0,
bytes_ptr,
n,
NULL,
0);
} }
/** /**
@@ -25,9 +19,8 @@ void hash_nbytes(const uint8_t *const bytes_ptr, uint8_t n, cx_hash_t *const has
* @param[in] byte byte to hash * @param[in] byte byte to hash
* @param[in] hash_ctx pointer to the hashing context * @param[in] hash_ctx pointer to the hashing context
*/ */
void hash_byte(uint8_t byte, cx_hash_t *const hash_ctx) void hash_byte(uint8_t byte, cx_hash_t *const hash_ctx) {
{
hash_nbytes(&byte, 1, hash_ctx); hash_nbytes(&byte, 1, hash_ctx);
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -8,6 +8,6 @@
void hash_nbytes(const uint8_t *const bytes_ptr, uint8_t n, cx_hash_t *hash_ctx); void hash_nbytes(const uint8_t *const bytes_ptr, uint8_t n, cx_hash_t *hash_ctx);
void hash_byte(uint8_t byte, cx_hash_t *hash_ctx); void hash_byte(uint8_t byte, cx_hash_t *hash_ctx);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // HASH_BYTES_H_ #endif // HASH_BYTES_H_

View File

@@ -11,7 +11,7 @@
#include "ethUtils.h" #include "ethUtils.h"
#include "mem_utils.h" #include "mem_utils.h"
#include "ui_logic.h" #include "ui_logic.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
static s_path *path_struct = NULL; static s_path *path_struct = NULL;
@@ -23,46 +23,37 @@ static s_path *path_struct = NULL;
* @param[in] n the number of depths to evaluate * @param[in] n the number of depths to evaluate
* @return the feld which the first Nth depths points to * @return the feld which the first Nth depths points to
*/ */
static const void *get_nth_field(uint8_t *const fields_count_ptr, static const void *get_nth_field(uint8_t *const fields_count_ptr, uint8_t n) {
uint8_t n)
{
const void *struct_ptr = path_struct->root_struct; const void *struct_ptr = path_struct->root_struct;
const void *field_ptr = NULL; const void *field_ptr = NULL;
const char *typename; const char *typename;
uint8_t length; uint8_t length;
uint8_t fields_count; uint8_t fields_count;
if (path_struct == NULL) if (path_struct == NULL) {
return NULL;
}
if (n > path_struct->depth_count) // sanity check
{ {
return NULL; return NULL;
} }
if (n > path_struct->depth_count) // sanity check for (uint8_t depth = 0; depth < n; ++depth) {
{
return NULL;
}
for (uint8_t depth = 0; depth < n; ++depth)
{
field_ptr = get_struct_fields_array(struct_ptr, &fields_count); field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
if (fields_count_ptr != NULL) if (fields_count_ptr != NULL) {
{
*fields_count_ptr = fields_count; *fields_count_ptr = fields_count;
} }
// check if the index at this depth makes sense // check if the index at this depth makes sense
if (path_struct->depths[depth] > fields_count) if (path_struct->depths[depth] > fields_count) {
{
return NULL; return NULL;
} }
for (uint8_t index = 0; index < path_struct->depths[depth]; ++index) for (uint8_t index = 0; index < path_struct->depths[depth]; ++index) {
{
field_ptr = get_next_struct_field(field_ptr); field_ptr = get_next_struct_field(field_ptr);
} }
if (struct_field_type(field_ptr) == TYPE_CUSTOM) if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
{
typename = get_struct_field_typename(field_ptr, &length); typename = get_struct_field_typename(field_ptr, &length);
if ((struct_ptr = get_structn(typename, length)) == NULL) if ((struct_ptr = get_structn(typename, length)) == NULL) {
{
return NULL; return NULL;
} }
} }
@@ -76,8 +67,7 @@ static const void *get_nth_field(uint8_t *const fields_count_ptr,
* @param[out] the number of fields in the depth of the returned field * @param[out] the number of fields in the depth of the returned field
* @return the field which the path points to * @return the field which the path points to
*/ */
static inline const void *get_field(uint8_t *const fields_count) static inline const void *get_field(uint8_t *const fields_count) {
{
return get_nth_field(fields_count, path_struct->depth_count); return get_nth_field(fields_count, path_struct->depth_count);
} }
@@ -87,8 +77,7 @@ static inline const void *get_field(uint8_t *const fields_count)
* @param[in] n nth depth requested * @param[in] n nth depth requested
* @return pointer to the matching field, \ref NULL otherwise * @return pointer to the matching field, \ref NULL otherwise
*/ */
const void *path_get_nth_field(uint8_t n) const void *path_get_nth_field(uint8_t n) {
{
return get_nth_field(NULL, n); return get_nth_field(NULL, n);
} }
@@ -98,16 +87,14 @@ const void *path_get_nth_field(uint8_t n)
* @param[in] n nth to last depth requested * @param[in] n nth to last depth requested
* @return pointer to the matching field, \ref NULL otherwise * @return pointer to the matching field, \ref NULL otherwise
*/ */
const void *path_get_nth_field_to_last(uint8_t n) const void *path_get_nth_field_to_last(uint8_t n) {
{
const char *typename; const char *typename;
uint8_t typename_len; uint8_t typename_len;
const void *field_ptr; const void *field_ptr;
const void *struct_ptr = NULL; const void *struct_ptr = NULL;
field_ptr = get_nth_field(NULL, path_struct->depth_count - n); field_ptr = get_nth_field(NULL, path_struct->depth_count - n);
if (field_ptr != NULL) if (field_ptr != NULL) {
{
typename = get_struct_field_typename(field_ptr, &typename_len); typename = get_struct_field_typename(field_ptr, &typename_len);
struct_ptr = get_structn(typename, typename_len); struct_ptr = get_structn(typename, typename_len);
} }
@@ -119,8 +106,7 @@ const void *path_get_nth_field_to_last(uint8_t n)
* *
* @return the field which the path points to * @return the field which the path points to
*/ */
const void *path_get_field(void) const void *path_get_field(void) {
{
return get_field(NULL); return get_field(NULL);
} }
@@ -129,14 +115,11 @@ const void *path_get_field(void)
* *
* @return whether the push was succesful * @return whether the push was succesful
*/ */
static bool path_depth_list_push(void) static bool path_depth_list_push(void) {
{ if (path_struct == NULL) {
if (path_struct == NULL)
{
return false; return false;
} }
if (path_struct->depth_count == MAX_PATH_DEPTH) if (path_struct->depth_count == MAX_PATH_DEPTH) {
{
return false; return false;
} }
path_struct->depths[path_struct->depth_count] = 0; path_struct->depths[path_struct->depth_count] = 0;
@@ -149,9 +132,8 @@ static bool path_depth_list_push(void)
* *
* @return pointer to the hashing context * @return pointer to the hashing context
*/ */
static cx_sha3_t *get_last_hash_ctx(void) static cx_sha3_t *get_last_hash_ctx(void) {
{ return (cx_sha3_t *) mem_alloc(0) - 1;
return (cx_sha3_t*)mem_alloc(0) - 1;
} }
/** /**
@@ -159,19 +141,13 @@ static cx_sha3_t *get_last_hash_ctx(void)
* *
* @param[out] hash pointer to buffer where the hash will be stored * @param[out] hash pointer to buffer where the hash will be stored
*/ */
static void finalize_hash_depth(uint8_t *hash) static void finalize_hash_depth(uint8_t *hash) {
{
const cx_sha3_t *hash_ctx; const cx_sha3_t *hash_ctx;
hash_ctx = get_last_hash_ctx(); hash_ctx = get_last_hash_ctx();
// finalize hash // finalize hash
cx_hash((cx_hash_t*)hash_ctx, cx_hash((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE);
CX_LAST, mem_dealloc(sizeof(*hash_ctx)); // remove hash context
NULL,
0,
hash,
KECCAK256_HASH_BYTESIZE);
mem_dealloc(sizeof(*hash_ctx)); // remove hash context
} }
/** /**
@@ -179,18 +155,12 @@ static void finalize_hash_depth(uint8_t *hash)
* *
* @param[in] hash pointer to given hash * @param[in] hash pointer to given hash
*/ */
static void feed_last_hash_depth(const uint8_t *const hash) static void feed_last_hash_depth(const uint8_t *const hash) {
{
const cx_sha3_t *hash_ctx; const cx_sha3_t *hash_ctx;
hash_ctx = get_last_hash_ctx(); hash_ctx = get_last_hash_ctx();
// continue progressive hash with the array hash // continue progressive hash with the array hash
cx_hash((cx_hash_t*)hash_ctx, cx_hash((cx_hash_t *) hash_ctx, 0, hash, KECCAK256_HASH_BYTESIZE, NULL, 0);
0,
hash,
KECCAK256_HASH_BYTESIZE,
NULL,
0);
} }
/** /**
@@ -199,18 +169,15 @@ static void feed_last_hash_depth(const uint8_t *const hash)
* @param[in] init if the hashing context should be initialized * @param[in] init if the hashing context should be initialized
* @return whether the memory allocation of the hashing context was successful * @return whether the memory allocation of the hashing context was successful
*/ */
static bool push_new_hash_depth(bool init) static bool push_new_hash_depth(bool init) {
{
cx_sha3_t *hash_ctx; cx_sha3_t *hash_ctx;
// allocate new hash context // allocate new hash context
if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*hash_ctx)) == NULL) if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*hash_ctx)) == NULL) {
{
return false; return false;
} }
if (init) if (init) {
{ cx_keccak_init(hash_ctx, 256); // initialize it
cx_keccak_init(hash_ctx, 256); // initialize it
} }
return true; return true;
} }
@@ -220,38 +187,27 @@ static bool push_new_hash_depth(bool init)
* *
* @return whether the pop was successful * @return whether the pop was successful
*/ */
static bool path_depth_list_pop(void) static bool path_depth_list_pop(void) {
{
uint8_t hash[KECCAK256_HASH_BYTESIZE]; uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL) if (path_struct == NULL) {
{
return false; return false;
} }
if (path_struct->depth_count == 0) if (path_struct->depth_count == 0) {
{
return false; return false;
} }
path_struct->depth_count -= 1; path_struct->depth_count -= 1;
finalize_hash_depth(hash); finalize_hash_depth(hash);
if (path_struct->depth_count > 0) if (path_struct->depth_count > 0) {
{
feed_last_hash_depth(hash); feed_last_hash_depth(hash);
} } else {
else switch (path_struct->root_type) {
{
switch (path_struct->root_type)
{
case ROOT_DOMAIN: case ROOT_DOMAIN:
memcpy(tmpCtx.messageSigningContext712.domainHash, memcpy(tmpCtx.messageSigningContext712.domainHash, hash, KECCAK256_HASH_BYTESIZE);
hash,
KECCAK256_HASH_BYTESIZE);
break; break;
case ROOT_MESSAGE: case ROOT_MESSAGE:
memcpy(tmpCtx.messageSigningContext712.messageHash, memcpy(tmpCtx.messageSigningContext712.messageHash, hash, KECCAK256_HASH_BYTESIZE);
hash,
KECCAK256_HASH_BYTESIZE);
break; break;
default: default:
break; break;
@@ -268,17 +224,14 @@ static bool path_depth_list_pop(void)
* @param[in] the number of elements contained in that depth * @param[in] the number of elements contained in that depth
* @return whether the push was successful * @return whether the push was successful
*/ */
static bool array_depth_list_push(uint8_t path_idx, uint8_t size) static bool array_depth_list_push(uint8_t path_idx, uint8_t size) {
{
s_array_depth *arr; s_array_depth *arr;
if (path_struct == NULL) if (path_struct == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
if (path_struct->array_depth_count == MAX_ARRAY_DEPTH) if (path_struct->array_depth_count == MAX_ARRAY_DEPTH) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
@@ -295,16 +248,13 @@ static bool array_depth_list_push(uint8_t path_idx, uint8_t size)
* *
* @return whether the pop was successful * @return whether the pop was successful
*/ */
static bool array_depth_list_pop(void) static bool array_depth_list_pop(void) {
{
uint8_t hash[KECCAK256_HASH_BYTESIZE]; uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL) if (path_struct == NULL) {
{
return false; return false;
} }
if (path_struct->array_depth_count == 0) if (path_struct->array_depth_count == 0) {
{
return false; return false;
} }
@@ -321,8 +271,7 @@ static bool array_depth_list_pop(void)
* *
* @return whether the path update worked or not * @return whether the path update worked or not
*/ */
static bool path_update(void) static bool path_update(void) {
{
uint8_t fields_count; uint8_t fields_count;
const void *struct_ptr; const void *struct_ptr;
const void *field_ptr; const void *field_ptr;
@@ -330,34 +279,27 @@ static bool path_update(void)
uint8_t typename_len; uint8_t typename_len;
uint8_t hash[KECCAK256_HASH_BYTESIZE]; uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL) if (path_struct == NULL) {
{
return false; return false;
} }
if ((field_ptr = get_field(NULL)) == NULL) if ((field_ptr = get_field(NULL)) == NULL) {
{
return false; return false;
} }
struct_ptr = path_struct->root_struct; struct_ptr = path_struct->root_struct;
while (struct_field_type(field_ptr) == TYPE_CUSTOM) while (struct_field_type(field_ptr) == TYPE_CUSTOM) {
{
typename = get_struct_field_typename(field_ptr, &typename_len); typename = get_struct_field_typename(field_ptr, &typename_len);
if ((struct_ptr = get_structn(typename, typename_len)) == NULL) if ((struct_ptr = get_structn(typename, typename_len)) == NULL) {
{
return false; return false;
} }
if ((field_ptr = get_struct_fields_array(struct_ptr, &fields_count)) == NULL) if ((field_ptr = get_struct_fields_array(struct_ptr, &fields_count)) == NULL) {
{
return false; return false;
} }
if (push_new_hash_depth(true) == false) if (push_new_hash_depth(true) == false) {
{
return false; return false;
} }
// get the struct typehash // get the struct typehash
if (type_hash(typename, typename_len, hash) == false) if (type_hash(typename, typename_len, hash) == false) {
{
return false; return false;
} }
feed_last_hash_depth(hash); feed_last_hash_depth(hash);
@@ -375,23 +317,19 @@ static bool path_update(void)
* @param[in] name_length the root struct name length * @param[in] name_length the root struct name length
* @return boolean indicating if it was successful or not * @return boolean indicating if it was successful or not
*/ */
bool path_set_root(const char *const struct_name, uint8_t name_length) bool path_set_root(const char *const struct_name, uint8_t name_length) {
{
uint8_t hash[KECCAK256_HASH_BYTESIZE]; uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL) if (path_struct == NULL) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
path_struct->root_struct = get_structn(struct_name, name_length); path_struct->root_struct = get_structn(struct_name, name_length);
if (path_struct->root_struct == NULL) if (path_struct->root_struct == NULL) {
{
PRINTF("Struct name not found ("); PRINTF("Struct name not found (");
for (int i = 0; i < name_length; ++i) for (int i = 0; i < name_length; ++i) {
{
PRINTF("%c", struct_name[i]); PRINTF("%c", struct_name[i]);
} }
PRINTF(")!\n"); PRINTF(")!\n");
@@ -399,12 +337,10 @@ bool path_set_root(const char *const struct_name, uint8_t name_length)
return false; return false;
} }
if (push_new_hash_depth(true) == false) if (push_new_hash_depth(true) == false) {
{
return false; return false;
} }
if (type_hash(struct_name, name_length, hash) == false) if (type_hash(struct_name, name_length, hash) == false) {
{
return false; return false;
} }
feed_last_hash_depth(hash); feed_last_hash_depth(hash);
@@ -418,12 +354,9 @@ bool path_set_root(const char *const struct_name, uint8_t name_length)
path_struct->array_depth_count = 0; path_struct->array_depth_count = 0;
if ((name_length == strlen(DOMAIN_STRUCT_NAME)) && if ((name_length == strlen(DOMAIN_STRUCT_NAME)) &&
(strncmp(struct_name, DOMAIN_STRUCT_NAME, name_length) == 0)) (strncmp(struct_name, DOMAIN_STRUCT_NAME, name_length) == 0)) {
{
path_struct->root_type = ROOT_DOMAIN; path_struct->root_type = ROOT_DOMAIN;
} } else {
else
{
path_struct->root_type = ROOT_MESSAGE; path_struct->root_type = ROOT_MESSAGE;
} }
@@ -444,32 +377,26 @@ bool path_set_root(const char *const struct_name, uint8_t name_length)
static bool check_and_add_array_depth(const void *depth, static bool check_and_add_array_depth(const void *depth,
uint8_t total_count, uint8_t total_count,
uint8_t pidx, uint8_t pidx,
uint8_t size) uint8_t size) {
{
uint8_t expected_size; uint8_t expected_size;
uint8_t arr_idx; uint8_t arr_idx;
e_array_type expected_type; e_array_type expected_type;
arr_idx = (total_count - path_struct->array_depth_count) - 1; arr_idx = (total_count - path_struct->array_depth_count) - 1;
// we skip index 0, since we already have it // we skip index 0, since we already have it
for (uint8_t idx = 1; idx < (arr_idx + 1); ++idx) for (uint8_t idx = 1; idx < (arr_idx + 1); ++idx) {
{ if ((depth = get_next_struct_field_array_lvl(depth)) == NULL) {
if ((depth = get_next_struct_field_array_lvl(depth)) == NULL)
{
return false; return false;
} }
} }
expected_type = struct_field_array_depth(depth, &expected_size); expected_type = struct_field_array_depth(depth, &expected_size);
if ((expected_type == ARRAY_FIXED_SIZE) && (expected_size != size)) if ((expected_type == ARRAY_FIXED_SIZE) && (expected_size != size)) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
PRINTF("Unexpected array depth size. (expected %d, got %d)\n", PRINTF("Unexpected array depth size. (expected %d, got %d)\n", expected_size, size);
expected_size, size);
return false; return false;
} }
// add it // add it
if (!array_depth_list_push(pidx, size)) if (!array_depth_list_push(pidx, size)) {
{
return false; return false;
} }
return true; return true;
@@ -482,9 +409,7 @@ static bool check_and_add_array_depth(const void *depth,
* @param[in] length length of data * @param[in] length length of data
* @return whether the add was successful or not * @return whether the add was successful or not
*/ */
bool path_new_array_depth(const uint8_t *const data, bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
uint8_t length)
{
const void *field_ptr = NULL; const void *field_ptr = NULL;
const void *depth = NULL; const void *depth = NULL;
uint8_t depth_count; uint8_t depth_count;
@@ -492,36 +417,27 @@ bool path_new_array_depth(const uint8_t *const data,
uint8_t pidx; uint8_t pidx;
bool is_custom; bool is_custom;
if (path_struct == NULL) if (path_struct == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} } else if (length != 1) {
else if (length != 1)
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
for (pidx = 0; pidx < path_struct->depth_count; ++pidx) for (pidx = 0; pidx < path_struct->depth_count; ++pidx) {
{ if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) {
if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
if (struct_field_is_array(field_ptr)) if (struct_field_is_array(field_ptr)) {
{ if ((depth = get_struct_field_array_lvls_array(field_ptr, &depth_count)) == NULL) {
if ((depth = get_struct_field_array_lvls_array(field_ptr, &depth_count)) == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
total_count += depth_count; total_count += depth_count;
if (total_count > path_struct->array_depth_count) if (total_count > path_struct->array_depth_count) {
{ if (!check_and_add_array_depth(depth, total_count, pidx, *data)) {
if (!check_and_add_array_depth(depth, total_count, pidx, *data))
{
return false; return false;
} }
break; break;
@@ -529,24 +445,21 @@ bool path_new_array_depth(const uint8_t *const data,
} }
} }
if (pidx == path_struct->depth_count) if (pidx == path_struct->depth_count) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
PRINTF("Did not find a matching array type.\n"); PRINTF("Did not find a matching array type.\n");
return false; return false;
} }
is_custom = struct_field_type(field_ptr) == TYPE_CUSTOM; is_custom = struct_field_type(field_ptr) == TYPE_CUSTOM;
if (push_new_hash_depth(!is_custom) == false) if (push_new_hash_depth(!is_custom) == false) {
{
return false; return false;
} }
if (is_custom) if (is_custom) {
{
cx_sha3_t *hash_ctx = get_last_hash_ctx(); cx_sha3_t *hash_ctx = get_last_hash_ctx();
cx_sha3_t *old_ctx = hash_ctx - 1; cx_sha3_t *old_ctx = hash_ctx - 1;
memcpy(hash_ctx, old_ctx, sizeof(*old_ctx)); memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
cx_keccak_init(old_ctx, 256); // init hash cx_keccak_init(old_ctx, 256); // init hash
} }
return true; return true;
@@ -557,27 +470,22 @@ bool path_new_array_depth(const uint8_t *const data,
* *
* @return whether the end of the struct has been reached. * @return whether the end of the struct has been reached.
*/ */
static bool path_advance_in_struct(void) static bool path_advance_in_struct(void) {
{
bool end_reached = true; bool end_reached = true;
uint8_t *depth = &path_struct->depths[path_struct->depth_count - 1]; uint8_t *depth = &path_struct->depths[path_struct->depth_count - 1];
uint8_t fields_count; uint8_t fields_count;
if (path_struct == NULL) if (path_struct == NULL) {
{
return false; return false;
} }
if ((get_field(&fields_count)) == NULL) if ((get_field(&fields_count)) == NULL) {
{
return false; return false;
} }
if (path_struct->depth_count > 0) if (path_struct->depth_count > 0) {
{
*depth += 1; *depth += 1;
end_reached = (*depth == fields_count); end_reached = (*depth == fields_count);
} }
if (end_reached) if (end_reached) {
{
path_depth_list_pop(); path_depth_list_pop();
} }
return end_reached; return end_reached;
@@ -588,36 +496,28 @@ static bool path_advance_in_struct(void)
* *
* @return whether the end of the array levels has been reached. * @return whether the end of the array levels has been reached.
*/ */
static bool path_advance_in_array(void) static bool path_advance_in_array(void) {
{
bool end_reached; bool end_reached;
s_array_depth *arr_depth; s_array_depth *arr_depth;
if (path_struct == NULL) if (path_struct == NULL) {
{
return false; return false;
} }
do do {
{
end_reached = false; end_reached = false;
arr_depth = &path_struct->array_depths[path_struct->array_depth_count - 1]; arr_depth = &path_struct->array_depths[path_struct->array_depth_count - 1];
if ((path_struct->array_depth_count > 0) && if ((path_struct->array_depth_count > 0) &&
(arr_depth->path_index == (path_struct->depth_count - 1))) (arr_depth->path_index == (path_struct->depth_count - 1))) {
{
arr_depth->size -= 1; arr_depth->size -= 1;
if (arr_depth->size == 0) if (arr_depth->size == 0) {
{
array_depth_list_pop(); array_depth_list_pop();
end_reached = true; end_reached = true;
} } else {
else
{
return false; return false;
} }
} }
} } while (end_reached);
while (end_reached);
return true; return true;
} }
@@ -626,22 +526,16 @@ static bool path_advance_in_array(void)
* *
* @return whether the advancement was successful or not * @return whether the advancement was successful or not
*/ */
bool path_advance(void) bool path_advance(void) {
{
bool end_reached; bool end_reached;
do do {
{ if (path_advance_in_array()) {
if (path_advance_in_array())
{
end_reached = path_advance_in_struct(); end_reached = path_advance_in_struct();
} } else {
else
{
end_reached = false; end_reached = false;
} }
} } while (end_reached);
while (end_reached);
path_update(); path_update();
return true; return true;
} }
@@ -651,10 +545,8 @@ bool path_advance(void)
* *
* @return enum representing root type * @return enum representing root type
*/ */
e_root_type path_get_root_type(void) e_root_type path_get_root_type(void) {
{ if (path_struct == NULL) {
if (path_struct == NULL)
{
return ROOT_DOMAIN; return ROOT_DOMAIN;
} }
return path_struct->root_type; return path_struct->root_type;
@@ -665,10 +557,8 @@ e_root_type path_get_root_type(void)
* *
* @return pointer to the root structure definition * @return pointer to the root structure definition
*/ */
const void *path_get_root(void) const void *path_get_root(void) {
{ if (path_struct == NULL) {
if (path_struct == NULL)
{
return NULL; return NULL;
} }
return path_struct->root_struct; return path_struct->root_struct;
@@ -679,10 +569,8 @@ const void *path_get_root(void)
* *
* @return depth count * @return depth count
*/ */
uint8_t path_get_depth_count(void) uint8_t path_get_depth_count(void) {
{ if (path_struct == NULL) {
if (path_struct == NULL)
{
return 0; return 0;
} }
return path_struct->depth_count; return path_struct->depth_count;
@@ -693,16 +581,11 @@ uint8_t path_get_depth_count(void)
* *
* @return whether the memory allocation were successful. * @return whether the memory allocation were successful.
*/ */
bool path_init(void) bool path_init(void) {
{ if (path_struct == NULL) {
if (path_struct == NULL) if ((path_struct = MEM_ALLOC_AND_ALIGN_TYPE(*path_struct)) == NULL) {
{
if ((path_struct = MEM_ALLOC_AND_ALIGN_TYPE(*path_struct)) == NULL)
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
} } else {
else
{
path_struct->depth_count = 0; path_struct->depth_count = 0;
} }
} }
@@ -712,9 +595,8 @@ bool path_init(void)
/** /**
* De-initialize the path context * De-initialize the path context
*/ */
void path_deinit(void) void path_deinit(void) {
{
path_struct = NULL; path_struct = NULL;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -9,41 +9,34 @@
#define MAX_PATH_DEPTH 16 #define MAX_PATH_DEPTH 16
#define MAX_ARRAY_DEPTH 4 #define MAX_ARRAY_DEPTH 4
typedef struct typedef struct {
{
uint8_t path_index; uint8_t path_index;
uint8_t size; uint8_t size;
} s_array_depth; } s_array_depth;
typedef enum typedef enum { ROOT_DOMAIN, ROOT_MESSAGE } e_root_type;
{
ROOT_DOMAIN,
ROOT_MESSAGE
} e_root_type;
typedef struct typedef struct {
{
uint8_t depth_count; uint8_t depth_count;
uint8_t depths[MAX_PATH_DEPTH]; uint8_t depths[MAX_PATH_DEPTH];
uint8_t array_depth_count; uint8_t array_depth_count;
s_array_depth array_depths[MAX_ARRAY_DEPTH]; s_array_depth array_depths[MAX_ARRAY_DEPTH];
const void *root_struct; const void *root_struct;
e_root_type root_type; e_root_type root_type;
} s_path; } s_path;
bool path_set_root(const char *const struct_name, uint8_t length); bool path_set_root(const char *const struct_name, uint8_t length);
const void *path_get_field(void); const void *path_get_field(void);
bool path_advance(void); bool path_advance(void);
bool path_init(void); bool path_init(void);
void path_deinit(void); void path_deinit(void);
bool path_new_array_depth(const uint8_t *const data, bool path_new_array_depth(const uint8_t *const data, uint8_t length);
uint8_t length);
e_root_type path_get_root_type(void); e_root_type path_get_root_type(void);
const void *path_get_root(void); const void *path_get_root(void);
const void *path_get_nth_field(uint8_t n); const void *path_get_nth_field(uint8_t n);
const void *path_get_nth_field_to_last(uint8_t n); const void *path_get_nth_field_to_last(uint8_t n);
uint8_t path_get_depth_count(void); uint8_t path_get_depth_count(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // PATH_H_ #endif // PATH_H_

View File

@@ -19,8 +19,7 @@ typedef cx_sha256_t cx_sha224_t;
* *
* @return whether the schema hash was successful or not * @return whether the schema hash was successful or not
*/ */
bool compute_schema_hash(void) bool compute_schema_hash(void) {
{
const void *struct_ptr; const void *struct_ptr;
uint8_t structs_count; uint8_t structs_count;
const void *field_ptr; const void *field_ptr;
@@ -32,42 +31,37 @@ bool compute_schema_hash(void)
cx_sha224_init(&hash_ctx); cx_sha224_init(&hash_ctx);
struct_ptr = get_structs_array(&structs_count); struct_ptr = get_structs_array(&structs_count);
hash_byte('{', (cx_hash_t*)&hash_ctx); hash_byte('{', (cx_hash_t *) &hash_ctx);
while (structs_count-- > 0) while (structs_count-- > 0) {
{
name = get_struct_name(struct_ptr, &name_length); name = get_struct_name(struct_ptr, &name_length);
hash_byte('"', (cx_hash_t*)&hash_ctx); hash_byte('"', (cx_hash_t *) &hash_ctx);
hash_nbytes((uint8_t*)name, name_length, (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) name, name_length, (cx_hash_t *) &hash_ctx);
hash_nbytes((uint8_t*)"\":[", 3, (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) "\":[", 3, (cx_hash_t *) &hash_ctx);
field_ptr = get_struct_fields_array(struct_ptr, &fields_count); field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
while (fields_count-- > 0) while (fields_count-- > 0) {
{ hash_nbytes((uint8_t *) "{\"name\":\"", 9, (cx_hash_t *) &hash_ctx);
hash_nbytes((uint8_t*)"{\"name\":\"", 9, (cx_hash_t*)&hash_ctx);
name = get_struct_field_keyname(field_ptr, &name_length); name = get_struct_field_keyname(field_ptr, &name_length);
hash_nbytes((uint8_t*)name, name_length, (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) name, name_length, (cx_hash_t *) &hash_ctx);
hash_nbytes((uint8_t*)"\",\"type\":\"", 10, (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) "\",\"type\":\"", 10, (cx_hash_t *) &hash_ctx);
if (!format_hash_field_type(field_ptr, (cx_hash_t*)&hash_ctx)) if (!format_hash_field_type(field_ptr, (cx_hash_t *) &hash_ctx)) {
{
return false; return false;
} }
hash_nbytes((uint8_t*)"\"}", 2, (cx_hash_t*)&hash_ctx); hash_nbytes((uint8_t *) "\"}", 2, (cx_hash_t *) &hash_ctx);
if (fields_count > 0) if (fields_count > 0) {
{ hash_byte(',', (cx_hash_t *) &hash_ctx);
hash_byte(',', (cx_hash_t*)&hash_ctx);
} }
field_ptr = get_next_struct_field(field_ptr); field_ptr = get_next_struct_field(field_ptr);
} }
hash_byte(']', (cx_hash_t*)&hash_ctx); hash_byte(']', (cx_hash_t *) &hash_ctx);
if (structs_count > 0) if (structs_count > 0) {
{ hash_byte(',', (cx_hash_t *) &hash_ctx);
hash_byte(',', (cx_hash_t*)&hash_ctx);
} }
struct_ptr = get_next_struct(struct_ptr); struct_ptr = get_next_struct(struct_ptr);
} }
hash_byte('}', (cx_hash_t*)&hash_ctx); hash_byte('}', (cx_hash_t *) &hash_ctx);
// copy hash into context struct // copy hash into context struct
cx_hash((cx_hash_t*)&hash_ctx, cx_hash((cx_hash_t *) &hash_ctx,
CX_LAST, CX_LAST,
NULL, NULL,
0, 0,
@@ -76,4 +70,4 @@ bool compute_schema_hash(void)
return true; return true;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -5,8 +5,8 @@
#include <stdbool.h> #include <stdbool.h>
bool compute_schema_hash(void); bool compute_schema_hash(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // SCHEMA_HASH_H_ #endif // SCHEMA_HASH_H_

View File

@@ -5,21 +5,16 @@
#include "sol_typenames.h" #include "sol_typenames.h"
#include "mem.h" #include "mem.h"
#include "os_pic.h" #include "os_pic.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
#include "utils.h" // ARRAY_SIZE #include "utils.h" // ARRAY_SIZE
// Bit indicating they are more types associated to this typename // Bit indicating they are more types associated to this typename
#define TYPENAME_MORE_TYPE (1 << 7) #define TYPENAME_MORE_TYPE (1 << 7)
static uint8_t *sol_typenames = NULL; static uint8_t *sol_typenames = NULL;
enum enum { IDX_ENUM = 0, IDX_STR_IDX, IDX_COUNT };
{
IDX_ENUM = 0,
IDX_STR_IDX,
IDX_COUNT
};
/** /**
* Find a match between a typename index and all the type enums associated to it * Find a match between a typename index and all the type enums associated to it
@@ -28,21 +23,19 @@ enum
* @param[in] t_idx typename index * @param[in] t_idx typename index
* @return whether at least one match was found * @return whether at least one match was found
*/ */
static bool find_enum_matches(const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT], uint8_t t_idx) static bool find_enum_matches(const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT],
{ uint8_t t_idx) {
uint8_t *enum_match = NULL; uint8_t *enum_match = NULL;
// loop over enum/typename pairs // loop over enum/typename pairs
for (uint8_t e_idx = 0; e_idx < (TYPES_COUNT - 1); ++e_idx) for (uint8_t e_idx = 0; e_idx < (TYPES_COUNT - 1); ++e_idx) {
{ if (t_idx == enum_to_idx[e_idx][IDX_STR_IDX]) // match
if (t_idx == enum_to_idx[e_idx][IDX_STR_IDX]) // match
{ {
if (enum_match != NULL) // in case of a previous match, mark it if (enum_match != NULL) // in case of a previous match, mark it
{ {
*enum_match |= TYPENAME_MORE_TYPE; *enum_match |= TYPENAME_MORE_TYPE;
} }
if ((enum_match = mem_alloc(sizeof(uint8_t))) == NULL) if ((enum_match = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -57,8 +50,7 @@ static bool find_enum_matches(const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COU
* *
* @return whether the initialization went well or not * @return whether the initialization went well or not
*/ */
bool sol_typenames_init(void) bool sol_typenames_init(void) {
{
const char *const typenames[] = { const char *const typenames[] = {
"int", // 0 "int", // 0
"uint", // 1 "uint", // 1
@@ -68,39 +60,32 @@ bool sol_typenames_init(void)
"bytes" // 5 "bytes" // 5
}; };
// \ref TYPES_COUNT - 1 since we don't include \ref TYPE_CUSTOM // \ref TYPES_COUNT - 1 since we don't include \ref TYPE_CUSTOM
const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT] = { const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT] = {{TYPE_SOL_INT, 0},
{ TYPE_SOL_INT, 0 }, {TYPE_SOL_UINT, 1},
{ TYPE_SOL_UINT, 1 }, {TYPE_SOL_ADDRESS, 2},
{ TYPE_SOL_ADDRESS, 2 }, {TYPE_SOL_BOOL, 3},
{ TYPE_SOL_BOOL, 3 }, {TYPE_SOL_STRING, 4},
{ TYPE_SOL_STRING, 4 }, {TYPE_SOL_BYTES_FIX, 5},
{ TYPE_SOL_BYTES_FIX, 5 }, {TYPE_SOL_BYTES_DYN, 5}};
{ TYPE_SOL_BYTES_DYN, 5 }
};
uint8_t *typename_len_ptr; uint8_t *typename_len_ptr;
char *typename_ptr; char *typename_ptr;
if ((sol_typenames = mem_alloc(sizeof(uint8_t))) == NULL) if ((sol_typenames = mem_alloc(sizeof(uint8_t))) == NULL) {
{
return false; return false;
} }
*(sol_typenames) = 0; *(sol_typenames) = 0;
// loop over typenames // loop over typenames
for (uint8_t t_idx = 0; t_idx < ARRAY_SIZE(typenames); ++t_idx) for (uint8_t t_idx = 0; t_idx < ARRAY_SIZE(typenames); ++t_idx) {
{
// if at least one match was found // if at least one match was found
if (find_enum_matches(enum_to_idx, t_idx)) if (find_enum_matches(enum_to_idx, t_idx)) {
{ if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL)
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
// get pointer to the allocated space just above // get pointer to the allocated space just above
*typename_len_ptr = strlen(PIC(typenames[t_idx])); *typename_len_ptr = strlen(PIC(typenames[t_idx]));
if ((typename_ptr = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) if ((typename_ptr = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -120,9 +105,7 @@ bool sol_typenames_init(void)
* @param[out] length length of the returned typename * @param[out] length length of the returned typename
* @return typename or \ref NULL in case it wasn't found * @return typename or \ref NULL in case it wasn't found
*/ */
const char *get_struct_field_sol_typename(const uint8_t *field_ptr, const char *get_struct_field_sol_typename(const uint8_t *field_ptr, uint8_t *const length) {
uint8_t *const length)
{
e_type field_type; e_type field_type;
const uint8_t *typename_ptr; const uint8_t *typename_ptr;
uint8_t typenames_count; uint8_t typenames_count;
@@ -132,25 +115,22 @@ const char *get_struct_field_sol_typename(const uint8_t *field_ptr,
field_type = struct_field_type(field_ptr); field_type = struct_field_type(field_ptr);
typename_ptr = get_array_in_mem(sol_typenames, &typenames_count); typename_ptr = get_array_in_mem(sol_typenames, &typenames_count);
typename_found = false; typename_found = false;
while (typenames_count-- > 0) while (typenames_count-- > 0) {
{
more_type = true; more_type = true;
while (more_type) while (more_type) {
{
more_type = *typename_ptr & TYPENAME_MORE_TYPE; more_type = *typename_ptr & TYPENAME_MORE_TYPE;
e_type type_enum = *typename_ptr & TYPENAME_ENUM; e_type type_enum = *typename_ptr & TYPENAME_ENUM;
if (type_enum == field_type) if (type_enum == field_type) {
{
typename_found = true; typename_found = true;
} }
typename_ptr += 1; typename_ptr += 1;
} }
typename_ptr = (uint8_t*)get_string_in_mem(typename_ptr, length); typename_ptr = (uint8_t *) get_string_in_mem(typename_ptr, length);
if (typename_found) return (char*)typename_ptr; if (typename_found) return (char *) typename_ptr;
typename_ptr += *length; typename_ptr += *length;
} }
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return NULL; // Not found return NULL; // Not found
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -8,9 +8,8 @@
bool sol_typenames_init(void); bool sol_typenames_init(void);
const char *get_struct_field_sol_typename(const uint8_t *ptr, const char *get_struct_field_sol_typename(const uint8_t *ptr, uint8_t *const length);
uint8_t *const length);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // SOL_TYPENAMES_H_ #endif // SOL_TYPENAMES_H_

View File

@@ -7,10 +7,10 @@
#include "mem_utils.h" #include "mem_utils.h"
#include "type_hash.h" #include "type_hash.h"
#include "shared_context.h" #include "shared_context.h"
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "format_hash_field_type.h" #include "format_hash_field_type.h"
#include "hash_bytes.h" #include "hash_bytes.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
/** /**
@@ -19,21 +19,19 @@
* @param[in] field_ptr pointer to the struct field * @param[in] field_ptr pointer to the struct field
* @return \ref true it finished correctly, \ref false if it didn't (memory allocation) * @return \ref true it finished correctly, \ref false if it didn't (memory allocation)
*/ */
static bool encode_and_hash_field(const void *const field_ptr) static bool encode_and_hash_field(const void *const field_ptr) {
{
const char *name; const char *name;
uint8_t length; uint8_t length;
if (!format_hash_field_type(field_ptr, (cx_hash_t*)&global_sha3)) if (!format_hash_field_type(field_ptr, (cx_hash_t *) &global_sha3)) {
{
return false; return false;
} }
// space between field type name and field name // space between field type name and field name
hash_byte(' ', (cx_hash_t*)&global_sha3); hash_byte(' ', (cx_hash_t *) &global_sha3);
// field name // field name
name = get_struct_field_keyname(field_ptr, &length); name = get_struct_field_keyname(field_ptr, &length);
hash_nbytes((uint8_t*)name, length, (cx_hash_t*)&global_sha3); hash_nbytes((uint8_t *) name, length, (cx_hash_t *) &global_sha3);
return true; return true;
} }
@@ -44,8 +42,7 @@ static bool encode_and_hash_field(const void *const field_ptr)
* @param[in] str_length length of the formatted string in memory * @param[in] str_length length of the formatted string in memory
* @return pointer of the string in memory, \ref NULL in case of an error * @return pointer of the string in memory, \ref NULL in case of an error
*/ */
static bool encode_and_hash_type(const void *const struct_ptr) static bool encode_and_hash_type(const void *const struct_ptr) {
{
const char *struct_name; const char *struct_name;
uint8_t struct_name_length; uint8_t struct_name_length;
const uint8_t *field_ptr; const uint8_t *field_ptr;
@@ -53,29 +50,26 @@ static bool encode_and_hash_type(const void *const struct_ptr)
// struct name // struct name
struct_name = get_struct_name(struct_ptr, &struct_name_length); struct_name = get_struct_name(struct_ptr, &struct_name_length);
hash_nbytes((uint8_t*)struct_name, struct_name_length, (cx_hash_t*)&global_sha3); hash_nbytes((uint8_t *) struct_name, struct_name_length, (cx_hash_t *) &global_sha3);
// opening struct parenthese // opening struct parenthese
hash_byte('(', (cx_hash_t*)&global_sha3); hash_byte('(', (cx_hash_t *) &global_sha3);
field_ptr = get_struct_fields_array(struct_ptr, &fields_count); field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
for (uint8_t idx = 0; idx < fields_count; ++idx) for (uint8_t idx = 0; idx < fields_count; ++idx) {
{
// comma separating struct fields // comma separating struct fields
if (idx > 0) if (idx > 0) {
{ hash_byte(',', (cx_hash_t *) &global_sha3);
hash_byte(',', (cx_hash_t*)&global_sha3);
} }
if (encode_and_hash_field(field_ptr) == false) if (encode_and_hash_field(field_ptr) == false) {
{
return NULL; return NULL;
} }
field_ptr = get_next_struct_field(field_ptr); field_ptr = get_next_struct_field(field_ptr);
} }
// closing struct parenthese // closing struct parenthese
hash_byte(')', (cx_hash_t*)&global_sha3); hash_byte(')', (cx_hash_t *) &global_sha3);
return true; return true;
} }
@@ -86,26 +80,21 @@ static bool encode_and_hash_type(const void *const struct_ptr)
* @param[in] deps_count count of how many struct dependencies pointers * @param[in] deps_count count of how many struct dependencies pointers
* @param[in,out] deps pointer to the first dependency pointer * @param[in,out] deps pointer to the first dependency pointer
*/ */
static void sort_dependencies(uint8_t deps_count, static void sort_dependencies(uint8_t deps_count, const void **deps) {
const void **deps)
{
bool changed; bool changed;
const void *tmp_ptr; const void *tmp_ptr;
const char *name1, *name2; const char *name1, *name2;
uint8_t namelen1, namelen2; uint8_t namelen1, namelen2;
int str_cmp_result; int str_cmp_result;
do do {
{
changed = false; changed = false;
for (size_t idx = 0; (idx + 1) < deps_count; ++idx) for (size_t idx = 0; (idx + 1) < deps_count; ++idx) {
{
name1 = get_struct_name(*(deps + idx), &namelen1); name1 = get_struct_name(*(deps + idx), &namelen1);
name2 = get_struct_name(*(deps + idx + 1), &namelen2); name2 = get_struct_name(*(deps + idx + 1), &namelen2);
str_cmp_result = strncmp(name1, name2, MIN(namelen1, namelen2)); str_cmp_result = strncmp(name1, name2, MIN(namelen1, namelen2));
if ((str_cmp_result > 0) || ((str_cmp_result == 0) && (namelen1 > namelen2))) if ((str_cmp_result > 0) || ((str_cmp_result == 0) && (namelen1 > namelen2))) {
{
tmp_ptr = *(deps + idx); tmp_ptr = *(deps + idx);
*(deps + idx) = *(deps + idx + 1); *(deps + idx) = *(deps + idx + 1);
*(deps + idx + 1) = tmp_ptr; *(deps + idx + 1) = tmp_ptr;
@@ -113,8 +102,7 @@ static void sort_dependencies(uint8_t deps_count,
changed = true; changed = true;
} }
} }
} } while (changed);
while (changed);
} }
/** /**
@@ -127,8 +115,7 @@ static void sort_dependencies(uint8_t deps_count,
*/ */
static const void **get_struct_dependencies(uint8_t *const deps_count, static const void **get_struct_dependencies(uint8_t *const deps_count,
const void **first_dep, const void **first_dep,
const void *const struct_ptr) const void *const struct_ptr) {
{
uint8_t fields_count; uint8_t fields_count;
const void *field_ptr; const void *field_ptr;
const char *arg_structname; const char *arg_structname;
@@ -138,35 +125,28 @@ static const void **get_struct_dependencies(uint8_t *const deps_count,
const void **new_dep; const void **new_dep;
field_ptr = get_struct_fields_array(struct_ptr, &fields_count); field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
for (uint8_t idx = 0; idx < fields_count; ++idx) for (uint8_t idx = 0; idx < fields_count; ++idx) {
{ if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
if (struct_field_type(field_ptr) == TYPE_CUSTOM)
{
// get struct name // get struct name
arg_structname = get_struct_field_typename(field_ptr, &arg_structname_length); arg_structname = get_struct_field_typename(field_ptr, &arg_structname_length);
// from its name, get the pointer to its definition // from its name, get the pointer to its definition
arg_struct_ptr = get_structn(arg_structname, arg_structname_length); arg_struct_ptr = get_structn(arg_structname, arg_structname_length);
// check if it is not already present in the dependencies array // check if it is not already present in the dependencies array
for (dep_idx = 0; dep_idx < *deps_count; ++dep_idx) for (dep_idx = 0; dep_idx < *deps_count; ++dep_idx) {
{
// it's a match! // it's a match!
if (*(first_dep + dep_idx) == arg_struct_ptr) if (*(first_dep + dep_idx) == arg_struct_ptr) {
{
break; break;
} }
} }
// if it's not present in the array, add it and recurse into it // if it's not present in the array, add it and recurse into it
if (dep_idx == *deps_count) if (dep_idx == *deps_count) {
{
*deps_count += 1; *deps_count += 1;
if ((new_dep = MEM_ALLOC_AND_ALIGN_TYPE(void*)) == NULL) if ((new_dep = MEM_ALLOC_AND_ALIGN_TYPE(void *)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return NULL; return NULL;
} }
if (*deps_count == 1) if (*deps_count == 1) {
{
first_dep = new_dep; first_dep = new_dep;
} }
*new_dep = arg_struct_ptr; *new_dep = arg_struct_ptr;
@@ -187,32 +167,24 @@ static const void **get_struct_dependencies(uint8_t *const deps_count,
* @param[in] with_deps if hashed typestring should include struct dependencies * @param[in] with_deps if hashed typestring should include struct dependencies
* @return pointer to encoded string or \ref NULL in case of a memory allocation error * @return pointer to encoded string or \ref NULL in case of a memory allocation error
*/ */
bool type_hash(const char *const struct_name, bool type_hash(const char *const struct_name, const uint8_t struct_name_length, uint8_t *hash_buf) {
const uint8_t struct_name_length, const void *const struct_ptr = get_structn(struct_name, struct_name_length);
uint8_t *hash_buf)
{
const void *const struct_ptr = get_structn(struct_name,
struct_name_length);
uint8_t deps_count = 0; uint8_t deps_count = 0;
const void **deps; const void **deps;
void *mem_loc_bak = mem_alloc(0); void *mem_loc_bak = mem_alloc(0);
cx_keccak_init(&global_sha3, 256); // init hash cx_keccak_init(&global_sha3, 256); // init hash
deps = get_struct_dependencies(&deps_count, NULL, struct_ptr); deps = get_struct_dependencies(&deps_count, NULL, struct_ptr);
if ((deps_count > 0) && (deps == NULL)) if ((deps_count > 0) && (deps == NULL)) {
{
return false; return false;
} }
sort_dependencies(deps_count, deps); sort_dependencies(deps_count, deps);
if (encode_and_hash_type(struct_ptr) == false) if (encode_and_hash_type(struct_ptr) == false) {
{
return false; return false;
} }
// loop over each struct and generate string // loop over each struct and generate string
for (int idx = 0; idx < deps_count; ++idx) for (int idx = 0; idx < deps_count; ++idx) {
{ if (encode_and_hash_type(*deps) == false) {
if (encode_and_hash_type(*deps) == false)
{
return false; return false;
} }
deps += 1; deps += 1;
@@ -220,13 +192,8 @@ bool type_hash(const char *const struct_name,
mem_dealloc(mem_alloc(0) - mem_loc_bak); mem_dealloc(mem_alloc(0) - mem_loc_bak);
// copy hash into memory // copy hash into memory
cx_hash((cx_hash_t*)&global_sha3, cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, hash_buf, KECCAK256_HASH_BYTESIZE);
CX_LAST,
NULL,
0,
hash_buf,
KECCAK256_HASH_BYTESIZE);
return true; return true;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,10 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
bool type_hash(const char *const struct_name, bool type_hash(const char *const struct_name, const uint8_t struct_name_length, uint8_t *hash_buf);
const uint8_t struct_name_length,
uint8_t *hash_buf);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // TYPE_HASH_H_ #endif // TYPE_HASH_H_

View File

@@ -4,7 +4,7 @@
#include <string.h> #include <string.h>
#include "typed_data.h" #include "typed_data.h"
#include "sol_typenames.h" #include "sol_typenames.h"
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "context.h" #include "context.h"
#include "mem.h" #include "mem.h"
#include "mem_utils.h" #include "mem_utils.h"
@@ -16,18 +16,14 @@ static s_typed_data *typed_data = NULL;
* *
* @return whether the memory allocation was successful * @return whether the memory allocation was successful
*/ */
bool typed_data_init(void) bool typed_data_init(void) {
{ if (typed_data == NULL) {
if (typed_data == NULL) if ((typed_data = MEM_ALLOC_AND_ALIGN_TYPE(*typed_data)) == NULL) {
{
if ((typed_data = MEM_ALLOC_AND_ALIGN_TYPE(*typed_data)) == NULL)
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
// set types pointer // set types pointer
if ((typed_data->structs_array = mem_alloc(sizeof(uint8_t))) == NULL) if ((typed_data->structs_array = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -38,8 +34,7 @@ bool typed_data_init(void)
return true; return true;
} }
void typed_data_deinit(void) void typed_data_deinit(void) {
{
typed_data = NULL; typed_data = NULL;
} }
@@ -50,10 +45,8 @@ void typed_data_deinit(void)
* @param[in] ptr pointer to the current location within the struct field * @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after * @return pointer to the data right after
*/ */
static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr, static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr, const uint8_t *ptr) {
const uint8_t *ptr) (void) ptr;
{
(void)ptr;
return field_ptr + sizeof(typedesc_t); return field_ptr + sizeof(typedesc_t);
} }
@@ -64,13 +57,10 @@ static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr,
* @param[in] ptr pointer to the current location within the struct field * @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after * @return pointer to the data right after
*/ */
static const uint8_t *field_skip_typename(const uint8_t *field_ptr, static const uint8_t *field_skip_typename(const uint8_t *field_ptr, const uint8_t *ptr) {
const uint8_t *ptr)
{
uint8_t size; uint8_t size;
if (struct_field_type(field_ptr) == TYPE_CUSTOM) if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
{
get_string_in_mem(ptr, &size); get_string_in_mem(ptr, &size);
ptr += (sizeof(size) + size); ptr += (sizeof(size) + size);
} }
@@ -84,11 +74,8 @@ static const uint8_t *field_skip_typename(const uint8_t *field_ptr,
* @param[in] ptr pointer to the current location within the struct field * @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after * @return pointer to the data right after
*/ */
static const uint8_t *field_skip_typesize(const uint8_t *field_ptr, static const uint8_t *field_skip_typesize(const uint8_t *field_ptr, const uint8_t *ptr) {
const uint8_t *ptr) if (struct_field_has_typesize(field_ptr)) {
{
if (struct_field_has_typesize(field_ptr))
{
ptr += sizeof(typesize_t); ptr += sizeof(typesize_t);
} }
return ptr; return ptr;
@@ -101,16 +88,12 @@ static const uint8_t *field_skip_typesize(const uint8_t *field_ptr,
* @param[in] ptr pointer to the current location within the struct field * @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after * @return pointer to the data right after
*/ */
static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr, static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr, const uint8_t *ptr) {
const uint8_t *ptr)
{
uint8_t size; uint8_t size;
if (struct_field_is_array(field_ptr)) if (struct_field_is_array(field_ptr)) {
{
ptr = get_array_in_mem(ptr, &size); ptr = get_array_in_mem(ptr, &size);
while (size-- > 0) while (size-- > 0) {
{
ptr = get_next_struct_field_array_lvl(ptr); ptr = get_next_struct_field_array_lvl(ptr);
} }
} }
@@ -124,12 +107,10 @@ static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr,
* @param[in] ptr pointer to the current location within the struct field * @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after * @return pointer to the data right after
*/ */
static const uint8_t *field_skip_keyname(const uint8_t *field_ptr, static const uint8_t *field_skip_keyname(const uint8_t *field_ptr, const uint8_t *ptr) {
const uint8_t *ptr)
{
uint8_t size; uint8_t size;
(void)field_ptr; (void) field_ptr;
ptr = get_array_in_mem(ptr, &size); ptr = get_array_in_mem(ptr, &size);
return ptr + size; return ptr + size;
} }
@@ -141,15 +122,12 @@ static const uint8_t *field_skip_keyname(const uint8_t *field_ptr,
* @param[out] array_size pointer to array size * @param[out] array_size pointer to array size
* @return pointer to data * @return pointer to data
*/ */
const void *get_array_in_mem(const void *ptr, uint8_t *const array_size) const void *get_array_in_mem(const void *ptr, uint8_t *const array_size) {
{ if (ptr == NULL) {
if (ptr == NULL)
{
return NULL; return NULL;
} }
if (array_size) if (array_size) {
{ *array_size = *(uint8_t *) ptr;
*array_size = *(uint8_t*)ptr;
} }
return (ptr + sizeof(*array_size)); return (ptr + sizeof(*array_size));
} }
@@ -161,9 +139,8 @@ const void *get_array_in_mem(const void *ptr, uint8_t *const array_size)
* @param[out] string_length pointer to string length * @param[out] string_length pointer to string length
* @return pointer to beginning of the string * @return pointer to beginning of the string
*/ */
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);
return (char*)get_array_in_mem(ptr, string_length);
} }
/** /**
@@ -172,10 +149,8 @@ const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length)
* @param[in] field_ptr struct field pointer * @param[in] field_ptr struct field pointer
* @return TypeDesc * @return TypeDesc
*/ */
static inline typedesc_t get_struct_field_typedesc(const uint8_t *const field_ptr) static inline typedesc_t get_struct_field_typedesc(const uint8_t *const field_ptr) {
{ if (field_ptr == NULL) {
if (field_ptr == NULL)
{
return 0; return 0;
} }
return *field_ptr; return *field_ptr;
@@ -187,8 +162,7 @@ static inline typedesc_t get_struct_field_typedesc(const uint8_t *const field_pt
* @param[in] field_ptr struct field pointer * @param[in] field_ptr struct field pointer
* @return bool whether it is the case * @return bool whether it is the case
*/ */
bool struct_field_is_array(const uint8_t *const field_ptr) bool struct_field_is_array(const uint8_t *const field_ptr) {
{
return (get_struct_field_typedesc(field_ptr) & ARRAY_MASK); return (get_struct_field_typedesc(field_ptr) & ARRAY_MASK);
} }
@@ -198,8 +172,7 @@ bool struct_field_is_array(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer * @param[in] field_ptr struct field pointer
* @return bool whether it is the case * @return bool whether it is the case
*/ */
bool struct_field_has_typesize(const uint8_t *const field_ptr) bool struct_field_has_typesize(const uint8_t *const field_ptr) {
{
return (get_struct_field_typedesc(field_ptr) & TYPESIZE_MASK); return (get_struct_field_typedesc(field_ptr) & TYPESIZE_MASK);
} }
@@ -209,8 +182,7 @@ bool struct_field_has_typesize(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer * @param[in] field_ptr struct field pointer
* @return its type enum * @return its type enum
*/ */
e_type struct_field_type(const uint8_t *const field_ptr) e_type struct_field_type(const uint8_t *const field_ptr) {
{
return (get_struct_field_typedesc(field_ptr) & TYPE_MASK); return (get_struct_field_typedesc(field_ptr) & TYPE_MASK);
} }
@@ -220,10 +192,8 @@ e_type struct_field_type(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer * @param[in] field_ptr struct field pointer
* @return its type size * @return its type size
*/ */
uint8_t get_struct_field_typesize(const uint8_t *const field_ptr) uint8_t get_struct_field_typesize(const uint8_t *const field_ptr) {
{ if (field_ptr == NULL) {
if (field_ptr == NULL)
{
return 0; return 0;
} }
return *field_skip_typedesc(field_ptr, NULL); return *field_skip_typedesc(field_ptr, NULL);
@@ -236,13 +206,10 @@ uint8_t get_struct_field_typesize(const uint8_t *const field_ptr)
* @param[out] length the type name length * @param[out] length the type name length
* @return type name pointer * @return type name pointer
*/ */
const char *get_struct_field_custom_typename(const uint8_t *field_ptr, const char *get_struct_field_custom_typename(const uint8_t *field_ptr, uint8_t *const length) {
uint8_t *const length)
{
const uint8_t *ptr; const uint8_t *ptr;
if (field_ptr == NULL) if (field_ptr == NULL) {
{
return NULL; return NULL;
} }
ptr = field_skip_typedesc(field_ptr, NULL); ptr = field_skip_typedesc(field_ptr, NULL);
@@ -256,15 +223,11 @@ const char *get_struct_field_custom_typename(const uint8_t *field_ptr,
* @param[out] length the type name length * @param[out] length the type name length
* @return type name pointer * @return type name pointer
*/ */
const char *get_struct_field_typename(const uint8_t *field_ptr, const char *get_struct_field_typename(const uint8_t *field_ptr, uint8_t *const length) {
uint8_t *const length) if (field_ptr == NULL) {
{
if (field_ptr == NULL)
{
return NULL; return NULL;
} }
if (struct_field_type(field_ptr) == TYPE_CUSTOM) if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
{
return get_struct_field_custom_typename(field_ptr, length); return get_struct_field_custom_typename(field_ptr, length);
} }
return get_struct_field_sol_typename(field_ptr, length); return get_struct_field_sol_typename(field_ptr, length);
@@ -277,17 +240,12 @@ const char *get_struct_field_typename(const uint8_t *field_ptr,
* @param[out] array_size pointer to array size * @param[out] array_size pointer to array size
* @return array type of that depth * @return array type of that depth
*/ */
e_array_type struct_field_array_depth(const uint8_t *array_depth_ptr, e_array_type struct_field_array_depth(const uint8_t *array_depth_ptr, uint8_t *const array_size) {
uint8_t *const array_size) if (array_depth_ptr == NULL) {
{
if (array_depth_ptr == NULL)
{
return 0; return 0;
} }
if (*array_depth_ptr == ARRAY_FIXED_SIZE) if (*array_depth_ptr == ARRAY_FIXED_SIZE) {
{ if (array_size != NULL) {
if (array_size != NULL)
{
*array_size = *(array_depth_ptr + sizeof(uint8_t)); *array_size = *(array_depth_ptr + sizeof(uint8_t));
} }
} }
@@ -300,16 +258,13 @@ e_array_type struct_field_array_depth(const uint8_t *array_depth_ptr,
* @param[in] array_depth_ptr given array depth * @param[in] array_depth_ptr given array depth
* @return next array depth * @return next array depth
*/ */
const uint8_t *get_next_struct_field_array_lvl(const uint8_t *const array_depth_ptr) const uint8_t *get_next_struct_field_array_lvl(const uint8_t *const array_depth_ptr) {
{
const uint8_t *ptr; const uint8_t *ptr;
if (array_depth_ptr == NULL) if (array_depth_ptr == NULL) {
{
return NULL; return NULL;
} }
switch (*array_depth_ptr) switch (*array_depth_ptr) {
{
case ARRAY_DYNAMIC: case ARRAY_DYNAMIC:
ptr = array_depth_ptr; ptr = array_depth_ptr;
break; break;
@@ -332,12 +287,10 @@ const uint8_t *get_next_struct_field_array_lvl(const uint8_t *const array_depth_
* @return pointer to the first array level * @return pointer to the first array level
*/ */
const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const field_ptr, const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const field_ptr,
uint8_t *const length) uint8_t *const length) {
{
const uint8_t *ptr; const uint8_t *ptr;
if (field_ptr == NULL) if (field_ptr == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
@@ -354,13 +307,10 @@ const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const field_ptr,
* @param[out] length name length * @param[out] length name length
* @return key name * @return key name
*/ */
const char *get_struct_field_keyname(const uint8_t *field_ptr, const char *get_struct_field_keyname(const uint8_t *field_ptr, uint8_t *const length) {
uint8_t *const length)
{
const uint8_t *ptr; const uint8_t *ptr;
if (field_ptr == NULL) if (field_ptr == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
@@ -377,12 +327,10 @@ const char *get_struct_field_keyname(const uint8_t *field_ptr,
* @param[in] field_ptr given struct field * @param[in] field_ptr given struct field
* @return pointer to the next field * @return pointer to the next field
*/ */
const uint8_t *get_next_struct_field(const void *const field_ptr) const uint8_t *get_next_struct_field(const void *const field_ptr) {
{
const void *ptr; const void *ptr;
if (field_ptr == NULL) if (field_ptr == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
@@ -400,14 +348,12 @@ const uint8_t *get_next_struct_field(const void *const field_ptr)
* @param[out] length name length * @param[out] length name length
* @return struct name * @return struct name
*/ */
const char *get_struct_name(const uint8_t *const struct_ptr, uint8_t *const length) const char *get_struct_name(const uint8_t *const struct_ptr, uint8_t *const length) {
{ if (struct_ptr == NULL) {
if (struct_ptr == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
return (char*)get_string_in_mem(struct_ptr, length); return (char *) get_string_in_mem(struct_ptr, length);
} }
/** /**
@@ -417,20 +363,17 @@ const char *get_struct_name(const uint8_t *const struct_ptr, uint8_t *const leng
* @param[out] length name length * @param[out] length name length
* @return struct name * @return struct name
*/ */
const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr, const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr, uint8_t *const length) {
uint8_t *const length)
{
const void *ptr; const void *ptr;
uint8_t name_length; uint8_t name_length;
if (struct_ptr == NULL) if (struct_ptr == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
ptr = struct_ptr; ptr = struct_ptr;
get_struct_name(struct_ptr, &name_length); get_struct_name(struct_ptr, &name_length);
ptr += (sizeof(name_length) + name_length); // skip length ptr += (sizeof(name_length) + name_length); // skip length
return get_array_in_mem(ptr, length); return get_array_in_mem(ptr, length);
} }
@@ -440,19 +383,16 @@ const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr,
* @param[in] struct_ptr given struct * @param[in] struct_ptr given struct
* @return pointer to next struct * @return pointer to next struct
*/ */
const uint8_t *get_next_struct(const uint8_t *const struct_ptr) const uint8_t *get_next_struct(const uint8_t *const struct_ptr) {
{
uint8_t fields_count; uint8_t fields_count;
const void *ptr; const void *ptr;
if (struct_ptr == NULL) if (struct_ptr == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
ptr = get_struct_fields_array(struct_ptr, &fields_count); ptr = get_struct_fields_array(struct_ptr, &fields_count);
while (fields_count-- > 0) while (fields_count-- > 0) {
{
ptr = get_next_struct_field(ptr); ptr = get_next_struct_field(ptr);
} }
return ptr; return ptr;
@@ -464,8 +404,7 @@ const uint8_t *get_next_struct(const uint8_t *const struct_ptr)
* @param[out] length number of structs * @param[out] length number of structs
* @return pointer to the first struct * @return pointer to the first struct
*/ */
const uint8_t *get_structs_array(uint8_t *const length) const uint8_t *get_structs_array(uint8_t *const length) {
{
return get_array_in_mem(typed_data->structs_array, length); return get_array_in_mem(typed_data->structs_array, length);
} }
@@ -476,25 +415,20 @@ const uint8_t *get_structs_array(uint8_t *const length)
* @param[in] length name length * @param[in] length name length
* @return pointer to struct * @return pointer to struct
*/ */
const uint8_t *get_structn(const char *const name, const uint8_t *get_structn(const char *const name, const uint8_t length) {
const uint8_t length)
{
uint8_t structs_count; uint8_t structs_count;
const uint8_t *struct_ptr; const uint8_t *struct_ptr;
const char *struct_name; const char *struct_name;
uint8_t name_length; uint8_t name_length;
if (name == NULL) if (name == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL; return NULL;
} }
struct_ptr = get_structs_array(&structs_count); struct_ptr = get_structs_array(&structs_count);
while (structs_count-- > 0) while (structs_count-- > 0) {
{
struct_name = get_struct_name(struct_ptr, &name_length); struct_name = get_struct_name(struct_ptr, &name_length);
if ((length == name_length) && (memcmp(name, struct_name, length) == 0)) if ((length == name_length) && (memcmp(name, struct_name, length) == 0)) {
{
return struct_ptr; return struct_ptr;
} }
struct_ptr = get_next_struct(struct_ptr); struct_ptr = get_next_struct(struct_ptr);
@@ -510,13 +444,11 @@ const uint8_t *get_structn(const char *const name,
* @param[in] name name * @param[in] name name
* @return whether it was successful * @return whether it was successful
*/ */
bool set_struct_name(uint8_t length, const uint8_t *const name) bool set_struct_name(uint8_t length, const uint8_t *const name) {
{
uint8_t *length_ptr; uint8_t *length_ptr;
char *name_ptr; char *name_ptr;
if ((name == NULL) || (typed_data == NULL)) if ((name == NULL) || (typed_data == NULL)) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
@@ -524,24 +456,21 @@ bool set_struct_name(uint8_t length, const uint8_t *const name)
*(typed_data->structs_array) += 1; *(typed_data->structs_array) += 1;
// copy length // copy length
if ((length_ptr = mem_alloc(sizeof(uint8_t))) == NULL) if ((length_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
*length_ptr = length; *length_ptr = length;
// copy name // copy name
if ((name_ptr = mem_alloc(sizeof(char) * length)) == NULL) if ((name_ptr = mem_alloc(sizeof(char) * length)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
memmove(name_ptr, name, length); memmove(name_ptr, name, length);
// initialize number of fields // initialize number of fields
if ((typed_data->current_struct_fields_array = mem_alloc(sizeof(uint8_t))) == NULL) if ((typed_data->current_struct_fields_array = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -558,18 +487,16 @@ bool set_struct_name(uint8_t length, const uint8_t *const name)
*/ */
static const typedesc_t *set_struct_field_typedesc(const uint8_t *const data, static const typedesc_t *set_struct_field_typedesc(const uint8_t *const data,
uint8_t *data_idx, uint8_t *data_idx,
uint8_t length) uint8_t length) {
{
typedesc_t *typedesc_ptr; typedesc_t *typedesc_ptr;
// copy TypeDesc // copy TypeDesc
if ((*data_idx + sizeof(*typedesc_ptr)) > length) // check buffer bound if ((*data_idx + sizeof(*typedesc_ptr)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((typedesc_ptr = mem_alloc(sizeof(uint8_t))) == NULL) if ((typedesc_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return NULL; return NULL;
} }
@@ -586,32 +513,29 @@ static const typedesc_t *set_struct_field_typedesc(const uint8_t *const data,
*/ */
static bool set_struct_field_custom_typename(const uint8_t *const data, static bool set_struct_field_custom_typename(const uint8_t *const data,
uint8_t *data_idx, uint8_t *data_idx,
uint8_t length) uint8_t length) {
{
uint8_t *typename_len_ptr; uint8_t *typename_len_ptr;
char *typename; char *typename;
// copy custom struct name length // copy custom struct name length
if ((*data_idx + sizeof(*typename_len_ptr)) > length) // check buffer bound if ((*data_idx + sizeof(*typename_len_ptr)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
*typename_len_ptr = data[(*data_idx)++]; *typename_len_ptr = data[(*data_idx)++];
// copy name // copy name
if ((*data_idx + *typename_len_ptr) > length) // check buffer bound if ((*data_idx + *typename_len_ptr) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((typename = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) if ((typename = mem_alloc(sizeof(char) * *typename_len_ptr)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -627,55 +551,46 @@ static bool set_struct_field_custom_typename(const uint8_t *const data,
* @param[in] data_idx the data index * @param[in] data_idx the data index
* @return whether it was successful * @return whether it was successful
*/ */
static bool set_struct_field_array(const uint8_t *const data, static bool set_struct_field_array(const uint8_t *const data, uint8_t *data_idx, uint8_t length) {
uint8_t *data_idx,
uint8_t length)
{
uint8_t *array_levels_count; uint8_t *array_levels_count;
e_array_type *array_level; e_array_type *array_level;
uint8_t *array_level_size; uint8_t *array_level_size;
if ((*data_idx + sizeof(*array_levels_count)) > length) // check buffer bound if ((*data_idx + sizeof(*array_levels_count)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((array_levels_count = mem_alloc(sizeof(uint8_t))) == NULL) if ((array_levels_count = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
*array_levels_count = data[(*data_idx)++]; *array_levels_count = data[(*data_idx)++];
for (int idx = 0; idx < *array_levels_count; ++idx) for (int idx = 0; idx < *array_levels_count; ++idx) {
{ if ((*data_idx + sizeof(*array_level)) > length) // check buffer bound
if ((*data_idx + sizeof(*array_level)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((array_level = mem_alloc(sizeof(uint8_t))) == NULL) if ((array_level = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
*array_level = data[(*data_idx)++]; *array_level = data[(*data_idx)++];
if (*array_level > ARRAY_TYPES_COUNT) if (*array_level > ARRAY_TYPES_COUNT) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
switch (*array_level) switch (*array_level) {
{ case ARRAY_DYNAMIC: // nothing to do
case ARRAY_DYNAMIC: // nothing to do
break; break;
case ARRAY_FIXED_SIZE: case ARRAY_FIXED_SIZE:
if ((*data_idx + sizeof(*array_level_size)) > length) // check buffer bound if ((*data_idx + sizeof(*array_level_size)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((array_level_size = mem_alloc(sizeof(uint8_t))) == NULL) if ((array_level_size = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -699,18 +614,16 @@ static bool set_struct_field_array(const uint8_t *const data,
*/ */
static bool set_struct_field_typesize(const uint8_t *const data, static bool set_struct_field_typesize(const uint8_t *const data,
uint8_t *data_idx, uint8_t *data_idx,
uint8_t length) uint8_t length) {
{
uint8_t *typesize_ptr; uint8_t *typesize_ptr;
// copy TypeSize // copy TypeSize
if ((*data_idx + sizeof(*typesize_ptr)) > length) // check buffer bound if ((*data_idx + sizeof(*typesize_ptr)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((typesize_ptr = mem_alloc(sizeof(uint8_t))) == NULL) if ((typesize_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -725,34 +638,29 @@ static bool set_struct_field_typesize(const uint8_t *const data,
* @param[in,out] data_idx the data index * @param[in,out] data_idx the data index
* @return whether it was successful * @return whether it was successful
*/ */
static bool set_struct_field_keyname(const uint8_t *const data, static bool set_struct_field_keyname(const uint8_t *const data, uint8_t *data_idx, uint8_t length) {
uint8_t *data_idx,
uint8_t length)
{
uint8_t *keyname_len_ptr; uint8_t *keyname_len_ptr;
char *keyname_ptr; char *keyname_ptr;
// copy length // copy length
if ((*data_idx + sizeof(*keyname_len_ptr)) > length) // check buffer bound if ((*data_idx + sizeof(*keyname_len_ptr)) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((keyname_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) if ((keyname_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
*keyname_len_ptr = data[(*data_idx)++]; *keyname_len_ptr = data[(*data_idx)++];
// copy name // copy name
if ((*data_idx + *keyname_len_ptr) > length) // check buffer bound if ((*data_idx + *keyname_len_ptr) > length) // check buffer bound
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if ((keyname_ptr = mem_alloc(sizeof(char) * *keyname_len_ptr)) == NULL) if ((keyname_ptr = mem_alloc(sizeof(char) * *keyname_len_ptr)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false; return false;
} }
@@ -768,58 +676,45 @@ static bool set_struct_field_keyname(const uint8_t *const data,
* @param[in] data the field data * @param[in] data the field data
* @return whether it was successful * @return whether it was successful
*/ */
bool set_struct_field(uint8_t length, const uint8_t *const data) bool set_struct_field(uint8_t length, const uint8_t *const data) {
{
const typedesc_t *typedesc_ptr; const typedesc_t *typedesc_ptr;
uint8_t data_idx = 0; uint8_t data_idx = 0;
if ((data == NULL) || (length == 0)) if ((data == NULL) || (length == 0)) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} } else if (typed_data == NULL) {
else if (typed_data == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
// increment number of struct fields // increment number of struct fields
*(typed_data->current_struct_fields_array) += 1; *(typed_data->current_struct_fields_array) += 1;
if ((typedesc_ptr = set_struct_field_typedesc(data, &data_idx, length)) == NULL) if ((typedesc_ptr = set_struct_field_typedesc(data, &data_idx, length)) == NULL) {
{
return false; return false;
} }
// check TypeSize flag in TypeDesc // check TypeSize flag in TypeDesc
if (*typedesc_ptr & TYPESIZE_MASK) if (*typedesc_ptr & TYPESIZE_MASK) {
{ if (set_struct_field_typesize(data, &data_idx, length) == false) {
if (set_struct_field_typesize(data, &data_idx, length) == false) return false;
{ }
} else if ((*typedesc_ptr & TYPE_MASK) == TYPE_CUSTOM) {
if (set_struct_field_custom_typename(data, &data_idx, length) == false) {
return false; return false;
} }
} }
else if ((*typedesc_ptr & TYPE_MASK) == TYPE_CUSTOM) if (*typedesc_ptr & ARRAY_MASK) {
{ if (set_struct_field_array(data, &data_idx, length) == false) {
if (set_struct_field_custom_typename(data, &data_idx, length) == false)
{
return false;
}
}
if (*typedesc_ptr & ARRAY_MASK)
{
if (set_struct_field_array(data, &data_idx, length) == false)
{
return false; return false;
} }
} }
if (set_struct_field_keyname(data, &data_idx, length) == false) if (set_struct_field_keyname(data, &data_idx, length) == false) {
{
return false; return false;
} }
if (data_idx != length) // check that there is no more if (data_idx != length) // check that there is no more
{ {
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
@@ -827,4 +722,4 @@ bool set_struct_field(uint8_t length, const uint8_t *const data)
return true; return true;
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -7,21 +7,14 @@
#include <stdbool.h> #include <stdbool.h>
// TypeDesc masks // TypeDesc masks
#define TYPE_MASK (0xF) #define TYPE_MASK (0xF)
#define ARRAY_MASK (1 << 7) #define ARRAY_MASK (1 << 7)
#define TYPESIZE_MASK (1 << 6) #define TYPESIZE_MASK (1 << 6)
#define TYPENAME_ENUM (0xF) #define TYPENAME_ENUM (0xF)
typedef enum { ARRAY_DYNAMIC = 0, ARRAY_FIXED_SIZE, ARRAY_TYPES_COUNT } e_array_type;
typedef enum typedef enum {
{
ARRAY_DYNAMIC = 0,
ARRAY_FIXED_SIZE,
ARRAY_TYPES_COUNT
} e_array_type;
typedef enum
{
// contract defined struct // contract defined struct
TYPE_CUSTOM = 0, TYPE_CUSTOM = 0,
// native types // native types
@@ -33,48 +26,40 @@ typedef enum
TYPE_SOL_BYTES_FIX, TYPE_SOL_BYTES_FIX,
TYPE_SOL_BYTES_DYN, TYPE_SOL_BYTES_DYN,
TYPES_COUNT TYPES_COUNT
} e_type; } e_type;
typedef struct typedef struct {
{
uint8_t *structs_array; uint8_t *structs_array;
uint8_t *current_struct_fields_array; uint8_t *current_struct_fields_array;
} s_typed_data; } s_typed_data;
typedef uint8_t typedesc_t; typedef uint8_t typedesc_t;
typedef uint8_t typesize_t; typedef uint8_t typesize_t;
const void *get_array_in_mem(const void *ptr, uint8_t *const array_size); 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); const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length);
bool struct_field_is_array(const uint8_t *ptr); bool struct_field_is_array(const uint8_t *ptr);
bool struct_field_has_typesize(const uint8_t *ptr); bool struct_field_has_typesize(const uint8_t *ptr);
e_type struct_field_type(const uint8_t *ptr); e_type struct_field_type(const uint8_t *ptr);
uint8_t get_struct_field_typesize(const uint8_t *ptr); uint8_t get_struct_field_typesize(const uint8_t *ptr);
const char *get_struct_field_custom_typename(const uint8_t *ptr, const char *get_struct_field_custom_typename(const uint8_t *ptr, uint8_t *const length);
uint8_t *const length); const char *get_struct_field_typename(const uint8_t *ptr, uint8_t *const length);
const char *get_struct_field_typename(const uint8_t *ptr, e_array_type struct_field_array_depth(const uint8_t *ptr, uint8_t *const array_size);
uint8_t *const length);
e_array_type struct_field_array_depth(const uint8_t *ptr,
uint8_t *const array_size);
const uint8_t *get_next_struct_field_array_lvl(const uint8_t *const ptr); const uint8_t *get_next_struct_field_array_lvl(const uint8_t *const ptr);
const uint8_t *struct_field_half_skip(const uint8_t *ptr); const uint8_t *struct_field_half_skip(const uint8_t *ptr);
const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const ptr, const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const ptr, uint8_t *const length);
uint8_t *const length); const char *get_struct_field_keyname(const uint8_t *ptr, uint8_t *const length);
const char *get_struct_field_keyname(const uint8_t *ptr,
uint8_t *const length);
const uint8_t *get_next_struct_field(const void *ptr); const uint8_t *get_next_struct_field(const void *ptr);
const char *get_struct_name(const uint8_t *ptr, uint8_t *const length); const char *get_struct_name(const uint8_t *ptr, uint8_t *const length);
const uint8_t *get_struct_fields_array(const uint8_t *ptr, const uint8_t *get_struct_fields_array(const uint8_t *ptr, uint8_t *const length);
uint8_t *const length);
const uint8_t *get_next_struct(const uint8_t *ptr); const uint8_t *get_next_struct(const uint8_t *ptr);
const uint8_t *get_structs_array(uint8_t *const length); const uint8_t *get_structs_array(uint8_t *const length);
const uint8_t *get_structn(const char *const name_ptr, const uint8_t *get_structn(const char *const name_ptr, const uint8_t name_length);
const uint8_t name_length); bool set_struct_name(uint8_t length, const uint8_t *const name);
bool set_struct_name(uint8_t length, const uint8_t *const name); bool set_struct_field(uint8_t length, const uint8_t *const data);
bool set_struct_field(uint8_t length, const uint8_t *const data); bool typed_data_init(void);
bool typed_data_init(void); void typed_data_deinit(void);
void typed_data_deinit(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // TYPED_DATA_H_ #endif // TYPED_DATA_H_

View File

@@ -2,7 +2,7 @@
#include "ui_flow_712.h" #include "ui_flow_712.h"
#include "ui_logic.h" #include "ui_logic.h"
#include "shared_context.h" // strings #include "shared_context.h" // strings
// clang-format off // clang-format off
UX_STEP_NOCB( UX_STEP_NOCB(
@@ -54,4 +54,4 @@ UX_FLOW(ux_712_flow,
&ux_712_step_approve, &ux_712_step_approve,
&ux_712_step_reject); &ux_712_step_reject);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -7,6 +7,6 @@
extern const ux_flow_step_t* const ux_712_flow[]; extern const ux_flow_step_t* const ux_712_flow[];
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // UI_FLOW_712_H_ #endif // UI_FLOW_712_H_

View File

@@ -9,40 +9,33 @@
#include "ux_flow_engine.h" #include "ux_flow_engine.h"
#include "ui_flow_712.h" #include "ui_flow_712.h"
#include "shared_context.h" #include "shared_context.h"
#include "ethUtils.h" // getEthDisplayableAddress #include "ethUtils.h" // getEthDisplayableAddress
#include "utils.h" // uint256_to_decimal #include "utils.h" // uint256_to_decimal
#include "common_712.h" #include "common_712.h"
#include "context.h" // eip712_context_deinit #include "context.h" // eip712_context_deinit
#include "uint256.h" // tostring256 && tostring256_signed #include "uint256.h" // tostring256 && tostring256_signed
#include "path.h" // path_get_root_type #include "path.h" // path_get_root_type
#include "apdu_constants.h" // APDU response codes #include "apdu_constants.h" // APDU response codes
#include "typed_data.h" #include "typed_data.h"
#include "commands_712.h" #include "commands_712.h"
static t_ui_context *ui_ctx = NULL; static t_ui_context *ui_ctx = NULL;
/** /**
* Checks on the UI context to determine if the next EIP 712 field should be shown * Checks on the UI context to determine if the next EIP 712 field should be shown
* *
* @return whether the next field should be shown * @return whether the next field should be shown
*/ */
static bool ui_712_field_shown(void) static bool ui_712_field_shown(void) {
{
bool ret = false; bool ret = false;
if (ui_ctx->filtering_mode == EIP712_FILTERING_BASIC) if (ui_ctx->filtering_mode == EIP712_FILTERING_BASIC) {
{ if (N_storage.verbose_eip712 || (path_get_root_type() == ROOT_DOMAIN)) {
if (N_storage.verbose_eip712 || (path_get_root_type() == ROOT_DOMAIN))
{
ret = true; ret = true;
} }
} } else // EIP712_FILTERING_FULL
else // EIP712_FILTERING_FULL
{ {
if (ui_ctx->field_flags & UI_712_FIELD_SHOWN) if (ui_ctx->field_flags & UI_712_FIELD_SHOWN) {
{
ret = true; ret = true;
} }
} }
@@ -62,22 +55,17 @@ static void ui_712_set_buf(const char *const src,
size_t src_length, size_t src_length,
char *const dst, char *const dst,
size_t dst_length, size_t dst_length,
bool explicit_trunc) bool explicit_trunc) {
{
uint8_t cpy_length; uint8_t cpy_length;
if (src_length < dst_length) if (src_length < dst_length) {
{
cpy_length = src_length; cpy_length = src_length;
} } else {
else
{
cpy_length = dst_length - 1; cpy_length = dst_length - 1;
} }
memcpy(dst, src, cpy_length); memcpy(dst, src, cpy_length);
dst[cpy_length] = '\0'; dst[cpy_length] = '\0';
if (explicit_trunc && (src_length > dst_length)) if (explicit_trunc && (src_length > dst_length)) {
{
memcpy(dst + cpy_length - 3, "...", 3); memcpy(dst + cpy_length - 3, "...", 3);
} }
} }
@@ -85,10 +73,8 @@ static void ui_712_set_buf(const char *const src,
/** /**
* Skip the field if needed and reset its UI flags * Skip the field if needed and reset its UI flags
*/ */
void ui_712_finalize_field(void) void ui_712_finalize_field(void) {
{ if (!ui_712_field_shown()) {
if (!ui_712_field_shown())
{
ui_712_next_field(); ui_712_next_field();
} }
ui_712_field_flags_reset(); ui_712_field_flags_reset();
@@ -100,8 +86,7 @@ void ui_712_finalize_field(void)
* @param[in] str the new title * @param[in] str the new title
* @param[in] length its length * @param[in] length its length
*/ */
void ui_712_set_title(const char *const str, uint8_t length) void ui_712_set_title(const char *const str, uint8_t length) {
{
ui_712_set_buf(str, length, strings.tmp.tmp2, sizeof(strings.tmp.tmp2), false); ui_712_set_buf(str, length, strings.tmp.tmp2, sizeof(strings.tmp.tmp2), false);
} }
@@ -111,23 +96,19 @@ void ui_712_set_title(const char *const str, uint8_t length)
* @param[in] str the new value * @param[in] str the new value
* @param[in] length its length * @param[in] length its length
*/ */
void ui_712_set_value(const char *const str, uint8_t length) void ui_712_set_value(const char *const str, uint8_t length) {
{
ui_712_set_buf(str, length, strings.tmp.tmp, sizeof(strings.tmp.tmp), true); ui_712_set_buf(str, length, strings.tmp.tmp, sizeof(strings.tmp.tmp), true);
} }
/** /**
* Redraw the dynamic UI step that shows EIP712 information * Redraw the dynamic UI step that shows EIP712 information
*/ */
void ui_712_redraw_generic_step(void) void ui_712_redraw_generic_step(void) {
{ if (!ui_ctx->shown) // Initialize if it is not already
if (!ui_ctx->shown) // Initialize if it is not already
{ {
ux_flow_init(0, ux_712_flow, NULL); ux_flow_init(0, ux_712_flow, NULL);
ui_ctx->shown = true; ui_ctx->shown = true;
} } else {
else
{
// not pretty, manually changes the internal state of the UX flow // not pretty, manually changes the internal state of the UX flow
// so that we always land on the first screen of a paging step without any visible // so that we always land on the first screen of a paging step without any visible
// screen glitching (quick screen switching) // screen glitching (quick screen switching)
@@ -141,33 +122,22 @@ void ui_712_redraw_generic_step(void)
* Called on the intermediate dummy screen between the dynamic step * Called on the intermediate dummy screen between the dynamic step
* && the approve/reject screen * && the approve/reject screen
*/ */
void ui_712_next_field(void) void ui_712_next_field(void) {
{ if (ui_ctx == NULL) {
if (ui_ctx == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return; return;
} }
if (ui_ctx->structs_to_review > 0) if (ui_ctx->structs_to_review > 0) {
{
ui_712_review_struct(path_get_nth_field_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; ui_ctx->structs_to_review -= 1;
} } else {
else if (!ui_ctx->end_reached) {
{
if (!ui_ctx->end_reached)
{
handle_eip712_return_code(true); handle_eip712_return_code(true);
} } else {
else if (ui_ctx->pos == UI_712_POS_REVIEW) {
{
if (ui_ctx->pos == UI_712_POS_REVIEW)
{
ux_flow_next(); ux_flow_next();
ui_ctx->pos = UI_712_POS_END; ui_ctx->pos = UI_712_POS_END;
} } else {
else
{
ux_flow_prev(); ux_flow_prev();
ui_ctx->pos = UI_712_POS_REVIEW; ui_ctx->pos = UI_712_POS_REVIEW;
} }
@@ -180,20 +150,17 @@ void ui_712_next_field(void)
* *
* @param[in] struct_ptr pointer to the structure to be shown * @param[in] struct_ptr pointer to the structure to be shown
*/ */
void ui_712_review_struct(const void *const struct_ptr) void ui_712_review_struct(const void *const struct_ptr) {
{
const char *struct_name; const char *struct_name;
uint8_t struct_name_length; uint8_t struct_name_length;
const char *const title = "Review struct"; const char *const title = "Review struct";
if (ui_ctx == NULL) if (ui_ctx == NULL) {
{
return; return;
} }
ui_712_set_title(title, strlen(title)); ui_712_set_title(title, strlen(title));
if ((struct_name = get_struct_name(struct_ptr, &struct_name_length)) != NULL) if ((struct_name = get_struct_name(struct_ptr, &struct_name_length)) != NULL) {
{
ui_712_set_value(struct_name, struct_name_length); ui_712_set_value(struct_name, struct_name_length);
} }
ui_712_redraw_generic_step(); ui_712_redraw_generic_step();
@@ -202,8 +169,7 @@ void ui_712_review_struct(const void *const struct_ptr)
/** /**
* Show the hash of the message on the generic UI step * Show the hash of the message on the generic UI step
*/ */
void ui_712_message_hash(void) void ui_712_message_hash(void) {
{
const char *const title = "Message hash"; const char *const title = "Message hash";
ui_712_set_title(title, strlen(title)); ui_712_set_title(title, strlen(title));
@@ -221,11 +187,9 @@ void ui_712_message_hash(void)
* @param[in] data the data that needs formatting * @param[in] data the data that needs formatting
* @param[in] length its length * @param[in] length its length
*/ */
static void ui_712_format_str(const uint8_t *const data, uint8_t length) static void ui_712_format_str(const uint8_t *const data, uint8_t length) {
{ if (ui_712_field_shown()) {
if (ui_712_field_shown()) ui_712_set_value((char *) data, length);
{
ui_712_set_value((char*)data, length);
} }
} }
@@ -236,16 +200,13 @@ static void ui_712_format_str(const uint8_t *const data, uint8_t length)
* @param[in] length its length * @param[in] length its length
* @return if the formatting was successful * @return if the formatting was successful
*/ */
static bool ui_712_format_addr(const uint8_t *const data, uint8_t length) static bool ui_712_format_addr(const uint8_t *const data, uint8_t length) {
{ if (length != ADDRESS_LENGTH) {
if (length != ADDRESS_LENGTH)
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{ getEthDisplayableAddress((uint8_t *) data,
getEthDisplayableAddress((uint8_t*)data,
strings.tmp.tmp, strings.tmp.tmp,
sizeof(strings.tmp.tmp), sizeof(strings.tmp.tmp),
&global_sha3, &global_sha3,
@@ -261,20 +222,17 @@ static bool ui_712_format_addr(const uint8_t *const data, uint8_t length)
* @param[in] length its length * @param[in] length its length
* @return if the formatting was successful * @return if the formatting was successful
*/ */
static bool ui_712_format_bool(const uint8_t *const data, uint8_t length) static bool ui_712_format_bool(const uint8_t *const data, uint8_t length) {
{
const char *const true_str = "true"; const char *const true_str = "true";
const char *const false_str = "false"; const char *const false_str = "false";
const char *str; const char *str;
if (length != 1) if (length != 1) {
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA; apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false; return false;
} }
str = *data ? true_str : false_str; str = *data ? true_str : false_str;
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
ui_712_set_value(str, strlen(str)); ui_712_set_value(str, strlen(str));
} }
return true; return true;
@@ -286,19 +244,12 @@ static bool ui_712_format_bool(const uint8_t *const data, uint8_t length)
* @param[in] data the data that needs formatting * @param[in] data the data that needs formatting
* @param[in] length its length * @param[in] length its length
*/ */
static void ui_712_format_bytes(const uint8_t *const data, uint8_t length) static void ui_712_format_bytes(const uint8_t *const data, uint8_t length) {
{ if (ui_712_field_shown()) {
if (ui_712_field_shown()) snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", length, data);
{
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"0x%.*H",
length,
data);
// +2 for the "0x" // +2 for the "0x"
// x2 for each byte value is represented by 2 ASCII characters // x2 for each byte value is represented by 2 ASCII characters
if ((2 + (length * 2)) > (sizeof(strings.tmp.tmp) - 1)) if ((2 + (length * 2)) > (sizeof(strings.tmp.tmp) - 1)) {
{
strings.tmp.tmp[sizeof(strings.tmp.tmp) - 1 - 3] = '\0'; strings.tmp.tmp[sizeof(strings.tmp.tmp) - 1 - 3] = '\0';
strcat(strings.tmp.tmp, "..."); strcat(strings.tmp.tmp, "...");
} }
@@ -314,71 +265,58 @@ static void ui_712_format_bytes(const uint8_t *const data, uint8_t length)
*/ */
static bool ui_712_format_int(const uint8_t *const data, static bool ui_712_format_int(const uint8_t *const data,
uint8_t length, uint8_t length,
const void *const field_ptr) const void *const field_ptr) {
{
uint256_t value256; uint256_t value256;
uint128_t value128; uint128_t value128;
int32_t value32; int32_t value32;
int16_t value16; int16_t value16;
switch (get_struct_field_typesize(field_ptr) * 8) switch (get_struct_field_typesize(field_ptr) * 8) {
{
case 256: case 256:
convertUint256BE(data, length, &value256); convertUint256BE(data, length, &value256);
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
tostring256_signed(&value256, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp)); tostring256_signed(&value256, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
} }
break; break;
case 128: case 128:
convertUint128BE(data, length, &value128); convertUint128BE(data, length, &value128);
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp)); tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
} }
break; break;
case 64: case 64:
convertUint64BEto128(data, length, &value128); convertUint64BEto128(data, length, &value128);
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp)); tostring128_signed(&value128, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
} }
break; break;
case 32: case 32:
value32 = 0; value32 = 0;
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i) {
{ ((uint8_t *) &value32)[length - 1 - i] = data[i];
((uint8_t*)&value32)[length - 1 - i] = data[i];
} }
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{ snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "%d", value32);
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"%d",
value32);
} }
break; break;
case 16: case 16:
value16 = 0; value16 = 0;
for (int i = 0; i < length; ++i) for (int i = 0; i < length; ++i) {
{ ((uint8_t *) &value16)[length - 1 - i] = data[i];
((uint8_t*)&value16)[length - 1 - i] = data[i];
} }
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
snprintf(strings.tmp.tmp, snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp), sizeof(strings.tmp.tmp),
"%d", "%d",
value16); // expanded to 32 bits value16); // expanded to 32 bits
} }
break; break;
case 8: case 8:
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
snprintf(strings.tmp.tmp, snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp), sizeof(strings.tmp.tmp),
"%d", "%d",
((int8_t*)data)[0]); // expanded to 32 bits ((int8_t *) data)[0]); // expanded to 32 bits
} }
break; break;
default: default:
@@ -395,13 +333,11 @@ static bool ui_712_format_int(const uint8_t *const data,
* @param[in] data the data that needs formatting * @param[in] data the data that needs formatting
* @param[in] length its length * @param[in] length its length
*/ */
static void ui_712_format_uint(const uint8_t *const data, uint8_t length) static void ui_712_format_uint(const uint8_t *const data, uint8_t length) {
{
uint256_t value256; uint256_t value256;
convertUint256BE(data, length, &value256); convertUint256BE(data, length, &value256);
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
tostring256(&value256, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp)); tostring256(&value256, 10, strings.tmp.tmp, sizeof(strings.tmp.tmp));
} }
} }
@@ -413,44 +349,37 @@ static void ui_712_format_uint(const uint8_t *const data, uint8_t length)
* @param[in] data pointer to the field's raw value * @param[in] data pointer to the field's raw value
* @param[in] length field's raw value byte-length * @param[in] length field's raw value byte-length
*/ */
bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data, uint8_t length) bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data, uint8_t length) {
{
const char *key; const char *key;
uint8_t key_len; uint8_t key_len;
if (ui_ctx == NULL) if (ui_ctx == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
// Key // Key
if ((key = get_struct_field_keyname(field_ptr, &key_len)) == NULL) if ((key = get_struct_field_keyname(field_ptr, &key_len)) == NULL) {
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false; return false;
} }
if (ui_712_field_shown() && !(ui_ctx->field_flags & UI_712_FIELD_NAME_PROVIDED)) if (ui_712_field_shown() && !(ui_ctx->field_flags & UI_712_FIELD_NAME_PROVIDED)) {
{
ui_712_set_title(key, key_len); ui_712_set_title(key, key_len);
} }
// Value // Value
switch (struct_field_type(field_ptr)) switch (struct_field_type(field_ptr)) {
{
case TYPE_SOL_STRING: case TYPE_SOL_STRING:
ui_712_format_str(data, length); ui_712_format_str(data, length);
break; break;
case TYPE_SOL_ADDRESS: case TYPE_SOL_ADDRESS:
if (ui_712_format_addr(data, length) == false) if (ui_712_format_addr(data, length) == false) {
{
return false; return false;
} }
break; break;
case TYPE_SOL_BOOL: case TYPE_SOL_BOOL:
if (ui_712_format_bool(data, length) == false) if (ui_712_format_bool(data, length) == false) {
{
return false; return false;
} }
break; break;
@@ -459,8 +388,7 @@ bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data,
ui_712_format_bytes(data, length); ui_712_format_bytes(data, length);
break; break;
case TYPE_SOL_INT: case TYPE_SOL_INT:
if (ui_712_format_int(data, length, field_ptr) == false) if (ui_712_format_int(data, length, field_ptr) == false) {
{
return false; return false;
} }
break; break;
@@ -473,8 +401,7 @@ bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data,
} }
// Check if this field is supposed to be displayed // Check if this field is supposed to be displayed
if (ui_712_field_shown()) if (ui_712_field_shown()) {
{
ui_712_redraw_generic_step(); ui_712_redraw_generic_step();
} }
return true; return true;
@@ -484,17 +411,14 @@ bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data,
* Used to signal that we are done with reviewing the structs and we can now have * Used to signal that we are done with reviewing the structs and we can now have
* the option to approve or reject the signature * the option to approve or reject the signature
*/ */
void ui_712_end_sign(void) void ui_712_end_sign(void) {
{ if (ui_ctx == NULL) {
if (ui_ctx == NULL)
{
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return; return;
} }
ui_ctx->end_reached = true; ui_ctx->end_reached = true;
if (N_storage.verbose_eip712 || (ui_ctx->filtering_mode == EIP712_FILTERING_FULL)) if (N_storage.verbose_eip712 || (ui_ctx->filtering_mode == EIP712_FILTERING_FULL)) {
{
ui_712_next_field(); ui_712_next_field();
} }
} }
@@ -502,17 +426,13 @@ void ui_712_end_sign(void)
/** /**
* Initializes the UI context structure in memory * Initializes the UI context structure in memory
*/ */
bool ui_712_init(void) bool ui_712_init(void) {
{ if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx))) {
if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx)))
{
ui_ctx->shown = false; ui_ctx->shown = false;
ui_ctx->end_reached = false; ui_ctx->end_reached = false;
ui_ctx->pos = UI_712_POS_REVIEW; ui_ctx->pos = UI_712_POS_REVIEW;
ui_ctx->filtering_mode = EIP712_FILTERING_BASIC; ui_ctx->filtering_mode = EIP712_FILTERING_BASIC;
} } else {
else
{
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
} }
return ui_ctx != NULL; return ui_ctx != NULL;
@@ -521,8 +441,7 @@ bool ui_712_init(void)
/** /**
* Deinit function that simply unsets the struct pointer to NULL * Deinit function that simply unsets the struct pointer to NULL
*/ */
void ui_712_deinit(void) void ui_712_deinit(void) {
{
ui_ctx = NULL; ui_ctx = NULL;
} }
@@ -532,8 +451,7 @@ void ui_712_deinit(void)
* @param[in] e unused here, just needed to match the UI function signature * @param[in] e unused here, just needed to match the UI function signature
* @return unused here, just needed to match the UI function signature * @return unused here, just needed to match the UI function signature
*/ */
unsigned int ui_712_approve(const bagl_element_t *e) unsigned int ui_712_approve(const bagl_element_t *e) {
{
ui_712_approve_cb(e); ui_712_approve_cb(e);
eip712_context_deinit(); eip712_context_deinit();
return 0; return 0;
@@ -546,8 +464,7 @@ unsigned int ui_712_approve(const bagl_element_t *e)
* @param[in] e unused here, just needed to match the UI function signature * @param[in] e unused here, just needed to match the UI function signature
* @return unused here, just needed to match the UI function signature * @return unused here, just needed to match the UI function signature
*/ */
unsigned int ui_712_reject(const bagl_element_t *e) unsigned int ui_712_reject(const bagl_element_t *e) {
{
ui_712_reject_cb(e); ui_712_reject_cb(e);
eip712_context_deinit(); eip712_context_deinit();
return 0; return 0;
@@ -559,14 +476,11 @@ unsigned int ui_712_reject(const bagl_element_t *e)
* @param[in] show if this field should be shown on the device * @param[in] show if this field should be shown on the device
* @param[in] name_provided if a substitution name has been provided * @param[in] name_provided if a substitution name has been provided
*/ */
void ui_712_flag_field(bool show, bool name_provided) void ui_712_flag_field(bool show, bool name_provided) {
{ if (show) {
if (show)
{
ui_ctx->field_flags |= UI_712_FIELD_SHOWN; ui_ctx->field_flags |= UI_712_FIELD_SHOWN;
} }
if (name_provided) if (name_provided) {
{
ui_ctx->field_flags |= UI_712_FIELD_NAME_PROVIDED; ui_ctx->field_flags |= UI_712_FIELD_NAME_PROVIDED;
} }
} }
@@ -576,8 +490,7 @@ void ui_712_flag_field(bool show, bool name_provided)
* *
* @param[in] the new filtering mode * @param[in] the new filtering mode
*/ */
void ui_712_set_filtering_mode(e_eip712_filtering_mode mode) void ui_712_set_filtering_mode(e_eip712_filtering_mode mode) {
{
ui_ctx->filtering_mode = mode; ui_ctx->filtering_mode = mode;
} }
@@ -586,16 +499,14 @@ void ui_712_set_filtering_mode(e_eip712_filtering_mode mode)
* *
* @return current filtering mode * @return current filtering mode
*/ */
e_eip712_filtering_mode ui_712_get_filtering_mode(void) e_eip712_filtering_mode ui_712_get_filtering_mode(void) {
{
return ui_ctx->filtering_mode; return ui_ctx->filtering_mode;
} }
/** /**
* Reset all the UI struct field flags * Reset all the UI struct field flags
*/ */
void ui_712_field_flags_reset(void) void ui_712_field_flags_reset(void) {
{
ui_ctx->field_flags = 0; ui_ctx->field_flags = 0;
} }
@@ -604,12 +515,10 @@ void ui_712_field_flags_reset(void)
* *
* Makes it so the user will have to go through a "Review struct" screen * Makes it so the user will have to go through a "Review struct" screen
*/ */
void ui_712_queue_struct_to_review(void) void ui_712_queue_struct_to_review(void) {
{ if (N_storage.verbose_eip712) {
if (N_storage.verbose_eip712)
{
ui_ctx->structs_to_review += 1; ui_ctx->structs_to_review += 1;
} }
} }
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,30 +6,21 @@
#include <stdint.h> #include <stdint.h>
#include "ux.h" #include "ux.h"
#define UI_712_FIELD_SHOWN (1 << 0) #define UI_712_FIELD_SHOWN (1 << 0)
#define UI_712_FIELD_NAME_PROVIDED (1 << 1) #define UI_712_FIELD_NAME_PROVIDED (1 << 1)
typedef enum typedef enum { EIP712_FILTERING_BASIC, EIP712_FILTERING_FULL } e_eip712_filtering_mode;
{
EIP712_FILTERING_BASIC,
EIP712_FILTERING_FULL
} e_eip712_filtering_mode;
typedef enum typedef enum { UI_712_POS_REVIEW, UI_712_POS_END } e_ui_position;
{
UI_712_POS_REVIEW,
UI_712_POS_END
} e_ui_position;
typedef struct typedef struct {
{
bool shown; bool shown;
bool end_reached; bool end_reached;
e_ui_position pos; e_ui_position pos;
uint8_t filtering_mode; uint8_t filtering_mode;
uint8_t field_flags; uint8_t field_flags;
uint8_t structs_to_review; uint8_t structs_to_review;
} t_ui_context; } t_ui_context;
bool ui_712_init(void); bool ui_712_init(void);
void ui_712_deinit(void); void ui_712_deinit(void);
@@ -41,15 +32,15 @@ unsigned int ui_712_approve(const bagl_element_t *e);
unsigned int ui_712_reject(const bagl_element_t *e); unsigned int ui_712_reject(const bagl_element_t *e);
void ui_712_set_title(const char *const str, uint8_t length); void ui_712_set_title(const char *const str, uint8_t length);
void ui_712_set_value(const char *const str, uint8_t length); void ui_712_set_value(const char *const str, uint8_t length);
void ui_712_message_hash(void); void ui_712_message_hash(void);
void ui_712_redraw_generic_step(void); void ui_712_redraw_generic_step(void);
void ui_712_flag_field(bool show, bool name_provided); void ui_712_flag_field(bool show, bool name_provided);
void ui_712_field_flags_reset(void); void ui_712_field_flags_reset(void);
void ui_712_finalize_field(void); void ui_712_finalize_field(void);
void ui_712_set_filtering_mode(e_eip712_filtering_mode mode); void ui_712_set_filtering_mode(e_eip712_filtering_mode mode);
e_eip712_filtering_mode ui_712_get_filtering_mode(void); e_eip712_filtering_mode ui_712_get_filtering_mode(void);
void ui_712_queue_struct_to_review(void); void ui_712_queue_struct_to_review(void);
#endif // HAVE_EIP712_FULL_SUPPORT #endif // HAVE_EIP712_FULL_SUPPORT
#endif // UI_LOGIC_712_H_ #endif // UI_LOGIC_712_H_

View File

@@ -5,15 +5,14 @@
static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01}; static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01};
unsigned int ui_712_approve_cb(const bagl_element_t *e) unsigned int ui_712_approve_cb(const bagl_element_t *e) {
{
uint8_t privateKeyData[INT256_LENGTH]; uint8_t privateKeyData[INT256_LENGTH];
uint8_t hash[INT256_LENGTH]; uint8_t hash[INT256_LENGTH];
uint8_t signature[100]; uint8_t signature[100];
cx_ecfp_private_key_t privateKey; cx_ecfp_private_key_t privateKey;
uint32_t tx = 0; uint32_t tx = 0;
(void)e; (void) e;
io_seproxyhal_io_heartbeat(); io_seproxyhal_io_heartbeat();
cx_keccak_init(&global_sha3, 256); cx_keccak_init(&global_sha3, 256);
cx_hash((cx_hash_t *) &global_sha3, cx_hash((cx_hash_t *) &global_sha3,
@@ -57,12 +56,10 @@ unsigned int ui_712_approve_cb(const bagl_element_t *e)
&info); &info);
explicit_bzero(&privateKey, sizeof(privateKey)); explicit_bzero(&privateKey, sizeof(privateKey));
G_io_apdu_buffer[0] = 27; G_io_apdu_buffer[0] = 27;
if (info & CX_ECCINFO_PARITY_ODD) if (info & CX_ECCINFO_PARITY_ODD) {
{
G_io_apdu_buffer[0]++; G_io_apdu_buffer[0]++;
} }
if (info & CX_ECCINFO_xGTn) if (info & CX_ECCINFO_xGTn) {
{
G_io_apdu_buffer[0] += 2; G_io_apdu_buffer[0] += 2;
} }
format_signature_out(signature); format_signature_out(signature);
@@ -77,9 +74,8 @@ unsigned int ui_712_approve_cb(const bagl_element_t *e)
return 0; // do not redraw the widget return 0; // do not redraw the widget
} }
unsigned int ui_712_reject_cb(const bagl_element_t *e) unsigned int ui_712_reject_cb(const bagl_element_t *e) {
{ (void) e;
(void)e;
reset_app_context(); reset_app_context();
G_io_apdu_buffer[0] = 0x69; G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85; G_io_apdu_buffer[1] = 0x85;

View File

@@ -7,4 +7,4 @@
unsigned int ui_712_approve_cb(const bagl_element_t *e); unsigned int ui_712_approve_cb(const bagl_element_t *e);
unsigned int ui_712_reject_cb(const bagl_element_t *e); unsigned int ui_712_reject_cb(const bagl_element_t *e);
#endif // COMMON_EIP712_H_ #endif // COMMON_EIP712_H_

View File

@@ -11,8 +11,8 @@ void handleSignEIP712Message_v0(uint8_t p1,
uint8_t dataLength, uint8_t dataLength,
unsigned int *flags, unsigned int *flags,
unsigned int *tx) { unsigned int *tx) {
(void)tx; (void) tx;
(void)p2; (void) p2;
if (p1 != 00) { if (p1 != 00) {
THROW(0x6B00); THROW(0x6B00);
} }
@@ -25,9 +25,7 @@ void handleSignEIP712Message_v0(uint8_t p1,
if ((workBuffer == NULL) || (dataLength < (KECCAK256_HASH_BYTESIZE * 2))) { if ((workBuffer == NULL) || (dataLength < (KECCAK256_HASH_BYTESIZE * 2))) {
THROW(0x6a80); THROW(0x6a80);
} }
memmove(tmpCtx.messageSigningContext712.domainHash, memmove(tmpCtx.messageSigningContext712.domainHash, workBuffer, KECCAK256_HASH_BYTESIZE);
workBuffer,
KECCAK256_HASH_BYTESIZE);
memmove(tmpCtx.messageSigningContext712.messageHash, memmove(tmpCtx.messageSigningContext712.messageHash,
workBuffer + KECCAK256_HASH_BYTESIZE, workBuffer + KECCAK256_HASH_BYTESIZE,
KECCAK256_HASH_BYTESIZE); KECCAK256_HASH_BYTESIZE);