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_INS_GET_WALLET_ID 0x04
#define APDU_RESPONSE_OK 0x9000
#define APDU_RESPONSE_INVALID_DATA 0x6a80
#define APDU_RESPONSE_INSUFFICIENT_MEMORY 0x6a84
#define APDU_RESPONSE_INVALID_INS 0x6d00
#define APDU_RESPONSE_INVALID_P1_P2 0x6b00
#define APDU_RESPONSE_CONDITION_NOT_SATISFIED 0x6985
#define APDU_RESPONSE_REF_DATA_NOT_USABLE 0x6a88
#define APDU_RESPONSE_OK 0x9000
#define APDU_RESPONSE_INVALID_DATA 0x6a80
#define APDU_RESPONSE_INSUFFICIENT_MEMORY 0x6a84
#define APDU_RESPONSE_INVALID_INS 0x6d00
#define APDU_RESPONSE_INVALID_P1_P2 0x6b00
#define APDU_RESPONSE_CONDITION_NOT_SATISFIED 0x6985
#define APDU_RESPONSE_REF_DATA_NOT_USABLE 0x6a88
#ifdef HAVE_STARKWARE
@@ -63,14 +62,7 @@
#endif
enum {
OFFSET_CLA = 0,
OFFSET_INS,
OFFSET_P1,
OFFSET_P2,
OFFSET_LC,
OFFSET_CDATA
};
enum { OFFSET_CLA = 0, OFFSET_INS, OFFSET_P1, OFFSET_P2, OFFSET_LC, OFFSET_CDATA };
void handleGetPublicKey(uint8_t p1,
uint8_t p2,

View File

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

View File

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

View File

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

View File

@@ -22,14 +22,13 @@
#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 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 convertUint64BEto128(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 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);

View File

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

View File

@@ -5,11 +5,11 @@
#include <stdlib.h>
void mem_init(void);
void mem_reset(void);
void *mem_alloc(size_t size);
void mem_dealloc(size_t size);
void mem_init(void);
void mem_reset(void);
void *mem_alloc(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
*/
char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length)
{
char *mem_ptr;
uint32_t value_copy;
uint8_t size;
char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
char *mem_ptr;
uint32_t value_copy;
uint8_t size;
size = 1; // minimum size, even if 0
size = 1; // minimum size, even if 0
value_copy = value;
while (value_copy >= 10)
{
while (value_copy >= 10) {
value_copy /= 10;
size += 1;
}
// +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);
mem_dealloc(sizeof(char)); // to skip the null character
if (length != NULL)
{
mem_dealloc(sizeof(char)); // to skip the null character
if (length != NULL) {
*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
*/
void *mem_alloc_and_align(size_t size, size_t alignment)
{
uint8_t align_diff = (uintptr_t)mem_alloc(0) % alignment;
void *mem_alloc_and_align(size_t size, size_t 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 mem_alloc(size);
}
#endif // HAVE_DYN_MEM_ALLOC
#endif // HAVE_DYN_MEM_ALLOC

View File

@@ -6,11 +6,11 @@
#include <stdint.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);
void *mem_alloc_and_align(size_t size, size_t alignment);
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);
#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 "uint128.h"
#include "uint_common.h"
#include "ethUtils.h" // HEXDIGITS
#include "ethUtils.h" // HEXDIGITS
void readu128BE(const uint8_t *const buffer, uint128_t *const target) {
UPPER_P(target) = readUint64BE(buffer);

View File

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

View File

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

View File

@@ -7,27 +7,27 @@
#include <stdint.h>
// APDUs P1
#define P1_COMPLETE 0x00
#define P1_PARTIAL 0xFF
#define P1_ACTIVATE 0x00
#define P1_CONTRACT_NAME 0x0F
#define P1_FIELD_NAME 0xFF
#define P1_COMPLETE 0x00
#define P1_PARTIAL 0xFF
#define P1_ACTIVATE 0x00
#define P1_CONTRACT_NAME 0x0F
#define P1_FIELD_NAME 0xFF
// APDUs P2
#define P2_NAME 0x00
#define P2_ARRAY 0x0F
#define P2_FIELD 0xFF
#define P2_KEY 0x00
#define P2_VALUE 0xFF
#define P2_NAME 0x00
#define P2_ARRAY 0x0F
#define P2_FIELD 0xFF
#define P2_KEY 0x00
#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_impl(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);
void handle_eip712_return_code(bool success);
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_sign(const uint8_t *const apdu_buf);
bool handle_eip712_filtering(const uint8_t *const apdu_buf);
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 "ui_logic.h"
#include "typed_data.h"
#include "apdu_constants.h" // APDU response codes
#include "shared_context.h" // reset_app_context
#include "ui_callbacks.h" // ui_idle
#include "apdu_constants.h" // APDU response codes
#include "shared_context.h" // reset_app_context
#include "ui_callbacks.h" // ui_idle
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
*/
bool eip712_context_init(void)
{
bool eip712_context_init(void) {
// init global variables
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;
return false;
}
if (sol_typenames_init() == false)
{
if (sol_typenames_init() == false) {
return false;
}
if (path_init() == false)
{
if (path_init() == false) {
return false;
}
if (field_hash_init() == false)
{
if (field_hash_init() == false) {
return false;
}
if (ui_712_init() == false)
{
if (ui_712_init() == 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;
}
@@ -63,8 +57,7 @@ bool eip712_context_init(void)
/**
* De-initialize the EIP712 context
*/
void eip712_context_deinit(void)
{
void eip712_context_deinit(void) {
typed_data_deinit();
path_deinit();
field_hash_deinit();

View File

@@ -4,19 +4,18 @@
#ifdef HAVE_EIP712_FULL_SUPPORT
#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 schema_hash[224 / 8];
} s_eip712_context;
} s_eip712_context;
extern s_eip712_context *eip712_context;
bool eip712_context_init(void);
void eip712_context_deinit(void);
bool eip712_context_init(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 "mem.h"
#include "shared_context.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
typedef enum
{
MSB,
LSB
} e_padding_type;
typedef enum { MSB, LSB } e_padding_type;
/**
* Encode a field value to 32 bytes (padded)
@@ -25,20 +21,17 @@ typedef enum
static void *field_encode(const uint8_t *const value,
uint8_t length,
e_padding_type ptype,
uint8_t pval)
{
uint8_t pval) {
uint8_t *padded_value;
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;
return NULL;
}
if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL)
{
switch (ptype)
{
if ((padded_value = mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) {
switch (ptype) {
case MSB:
memset(padded_value, pval, 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;
default:
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);
}
else
{
} else {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
}
return padded_value;
@@ -67,8 +58,7 @@ static void *field_encode(const uint8_t *const value,
* @param[in] length its byte-length
* @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
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
* @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;
if ((length == typesize) && (value[0] & (1 << 7))) // negative number
if ((length == typesize) && (value[0] & (1 << 7))) // negative number
{
padding_value = 0xFF;
}
else
{
} else {
padding_value = 0x00;
}
// 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
* @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
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
* @return the encoded value
*/
void *encode_boolean(const bool *const value, uint8_t length)
{
if (length != 1) // sanity check
void *encode_boolean(const bool *const value, uint8_t length) {
if (length != 1) // sanity check
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
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
* @return the encoded value
*/
void *encode_address(const uint8_t *const value, uint8_t length)
{
if (length != ADDRESS_LENGTH) // sanity check
void *encode_address(const uint8_t *const value, uint8_t length) {
if (length != ADDRESS_LENGTH) // sanity check
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return NULL;
@@ -144,4 +128,4 @@ void *encode_address(const uint8_t *const value, uint8_t 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 <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_int(const uint8_t *const value, uint8_t length, uint8_t typesize);
void *encode_boolean(const bool *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_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_boolean(const bool *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);
#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 "shared_context.h"
#include "ui_logic.h"
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "context.h" // contract_addr
#include "utils.h" // u64_from_BE
#include "apdu_constants.h" // APDU response codes
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "context.h" // contract_addr
#include "utils.h" // u64_from_BE
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
#include "commands_712.h"
#include "hash_bytes.h"
@@ -23,12 +23,9 @@ static s_field_hashing *fh = NULL;
*
* @return whether the initialization was successful or not
*/
bool field_hash_init(void)
{
if (fh == NULL)
{
if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL)
{
bool field_hash_init(void) {
if (fh == NULL) {
if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL) {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false;
}
@@ -40,8 +37,7 @@ bool field_hash_init(void)
/**
* Deinitialize the field hash context
*/
void field_hash_deinit(void)
{
void field_hash_deinit(void) {
fh = NULL;
}
@@ -55,18 +51,16 @@ void field_hash_deinit(void)
*/
static const uint8_t *field_hash_prepare(const void *const field_ptr,
const uint8_t *data,
uint8_t *data_length)
{
uint8_t *data_length) {
e_type field_type;
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_length -= sizeof(uint16_t);
fh->state = FHS_WAITING_FOR_MORE;
if (IS_DYN(field_type))
{
cx_keccak_init(&global_sha3, 256); // init hash
if (IS_DYN(field_type)) {
cx_keccak_init(&global_sha3, 256); // init hash
ui_712_new_field(field_ptr, data, *data_length);
}
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,
const uint8_t *const data,
uint8_t data_length)
{
uint8_t data_length) {
uint8_t *value = NULL;
e_type field_type;
field_type = struct_field_type(field_ptr);
switch (field_type)
{
switch (field_type) {
case TYPE_SOL_INT:
value = encode_int(data, data_length, get_struct_field_typesize(field_ptr));
break;
@@ -105,7 +97,7 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
value = encode_address(data, data_length);
break;
case TYPE_SOL_BOOL:
value = encode_boolean((bool*)data, data_length);
value = encode_boolean((bool *) data, data_length);
break;
case TYPE_CUSTOM:
default:
@@ -113,8 +105,7 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
PRINTF("Unknown solidity type!\n");
}
if (value == NULL)
{
if (value == NULL) {
return NULL;
}
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
*/
static uint8_t *field_hash_finalize_dynamic(void)
{
static uint8_t *field_hash_finalize_dynamic(void) {
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;
return NULL;
}
// copy hash into memory
cx_hash((cx_hash_t*)&global_sha3,
CX_LAST,
NULL,
0,
value,
KECCAK256_HASH_BYTESIZE);
cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, value, KECCAK256_HASH_BYTESIZE);
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] 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;
if (IS_DYN(field_type))
{
if (IS_DYN(field_type)) {
len = KECCAK256_HASH_BYTESIZE;
}
else
{
} else {
len = EIP_712_ENCODED_FIELD_LENGTH;
}
// last thing in mem is the hash of the previous field
// and just before it is the current hash context
cx_sha3_t *hash_ctx = (cx_sha3_t*)(hash - sizeof(cx_sha3_t));
cx_sha3_t *hash_ctx = (cx_sha3_t *) (hash - sizeof(cx_sha3_t));
// 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
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,
const uint8_t *const data,
uint8_t data_length)
{
uint8_t data_length) {
const char *key;
uint8_t keylen;
key = get_struct_field_keyname(field_ptr, &keylen);
// copy contract address into context
if (strncmp(key, "verifyingContract", keylen) == 0)
{
if (data_length != sizeof(eip712_context->contract_addr))
{
if (strncmp(key, "verifyingContract", keylen) == 0) {
if (data_length != sizeof(eip712_context->contract_addr)) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
PRINTF("Unexpected verifyingContract length!\n");
return false;
}
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);
if (chainId != chainConfig->chainId)
{
if (chainId != chainConfig->chainId) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
PRINTF("EIP712Domain chain ID mismatch, expected 0x%.*h, got 0x%.*h !\n",
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,
const uint8_t *const data,
uint8_t data_length)
{
uint8_t data_length) {
const uint8_t *value = NULL;
e_type field_type;
field_type = struct_field_type(field_ptr);
if (!IS_DYN(field_type))
{
if ((value = field_hash_finalize_static(field_ptr,
data,
data_length)) == NULL)
{
if (!IS_DYN(field_type)) {
if ((value = field_hash_finalize_static(field_ptr, data, data_length)) == NULL) {
return false;
}
}
else
{
if ((value = field_hash_finalize_dynamic()) == NULL)
{
} else {
if ((value = field_hash_finalize_dynamic()) == NULL) {
return false;
}
}
field_hash_feed_parent(field_type, value);
if (path_get_root_type() == ROOT_DOMAIN)
{
if (field_hash_domain_special_fields(field_ptr, data, data_length) == false)
{
if (path_get_root_type() == ROOT_DOMAIN) {
if (field_hash_domain_special_fields(field_ptr, data, data_length) == 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
* @return whether the data hashing was successful or not
*/
bool field_hash(const uint8_t *data,
uint8_t data_length,
bool partial)
{
bool field_hash(const uint8_t *data, uint8_t data_length, bool partial) {
const void *field_ptr;
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;
return false;
}
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);
}
if (data_length > fh->remaining_size)
{
if (data_length > fh->remaining_size) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
fh->remaining_size -= data_length;
// if a dynamic type -> continue progressive hash
if (IS_DYN(field_type))
{
hash_nbytes(data, data_length, (cx_hash_t*)&global_sha3);
if (IS_DYN(field_type)) {
hash_nbytes(data, data_length, (cx_hash_t *) &global_sha3);
}
if (fh->remaining_size == 0)
{
if (partial) // only makes sense if marked as complete
if (fh->remaining_size == 0) {
if (partial) // only makes sense if marked as complete
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
if (field_hash_finalize(field_ptr, data, data_length) == false)
{
if (field_hash_finalize(field_ptr, data, data_length) == false) {
return false;
}
}
else
{
if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
} else {
if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
@@ -332,4 +286,4 @@ bool field_hash(const uint8_t *data,
return true;
}
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

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

View File

@@ -6,16 +6,10 @@
#include <stdbool.h>
#include <stdint.h>
typedef enum
{
FILTERING_CONTRACT_NAME,
FILTERING_STRUCT_FIELD
} e_filtering_type;
typedef enum { FILTERING_CONTRACT_NAME, FILTERING_STRUCT_FIELD } e_filtering_type;
bool provide_filtering_info(const uint8_t *const payload,
uint8_t length,
e_filtering_type type);
bool provide_filtering_info(const uint8_t *const payload, 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 "commands_712.h"
#include "hash_bytes.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
/**
@@ -15,18 +15,16 @@
* @param[in] hash_ctx pointer to the hashing context
* @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;
char *uint_str_ptr;
uint8_t uint_str_len;
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_UINT:
field_size *= 8; // bytes -> bits
field_size *= 8; // bytes -> bits
break;
case TYPE_SOL_BYTES_FIX:
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;
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;
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);
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
* @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;
char *uint_str_ptr;
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;
lvl_ptr = get_struct_field_array_lvls_array(field_ptr, &lvls_count);
while (lvls_count-- > 0)
{
while (lvls_count-- > 0) {
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:
break;
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;
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);
break;
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
* @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;
uint8_t length;
// field type name
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
if (struct_field_has_typesize(field_ptr))
{
if (!format_hash_field_type_size(field_ptr, hash_ctx))
{
if (struct_field_has_typesize(field_ptr)) {
if (!format_hash_field_type_size(field_ptr, hash_ctx)) {
return false;
}
}
// field type array levels
if (struct_field_is_array(field_ptr))
{
if (!format_hash_field_type_array_levels(field_ptr, hash_ctx))
{
if (struct_field_is_array(field_ptr)) {
if (!format_hash_field_type_array_levels(field_ptr, hash_ctx)) {
return false;
}
}
return true;
}
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -5,8 +5,8 @@
#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] 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)
{
cx_hash(hash_ctx,
0,
bytes_ptr,
n,
NULL,
0);
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);
}
/**
@@ -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] 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);
}
#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_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 "mem_utils.h"
#include "ui_logic.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
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
* @return the feld which the first Nth depths points to
*/
static const void *get_nth_field(uint8_t *const fields_count_ptr,
uint8_t n)
{
static const void *get_nth_field(uint8_t *const fields_count_ptr, uint8_t n) {
const void *struct_ptr = path_struct->root_struct;
const void *field_ptr = NULL;
const char *typename;
uint8_t length;
uint8_t fields_count;
if (path_struct == NULL)
if (path_struct == NULL) {
return NULL;
}
if (n > path_struct->depth_count) // sanity check
{
return NULL;
}
if (n > path_struct->depth_count) // sanity check
{
return NULL;
}
for (uint8_t depth = 0; depth < n; ++depth)
{
for (uint8_t depth = 0; depth < n; ++depth) {
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;
}
// 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;
}
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);
}
if (struct_field_type(field_ptr) == TYPE_CUSTOM)
{
if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
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;
}
}
@@ -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
* @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);
}
@@ -87,8 +77,7 @@ static inline const void *get_field(uint8_t *const fields_count)
* @param[in] n nth depth requested
* @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);
}
@@ -98,16 +87,14 @@ const void *path_get_nth_field(uint8_t n)
* @param[in] n nth to last depth requested
* @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;
uint8_t typename_len;
const void *field_ptr;
const void *struct_ptr = NULL;
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);
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
*/
const void *path_get_field(void)
{
const void *path_get_field(void) {
return get_field(NULL);
}
@@ -129,14 +115,11 @@ const void *path_get_field(void)
*
* @return whether the push was succesful
*/
static bool path_depth_list_push(void)
{
if (path_struct == NULL)
{
static bool path_depth_list_push(void) {
if (path_struct == NULL) {
return false;
}
if (path_struct->depth_count == MAX_PATH_DEPTH)
{
if (path_struct->depth_count == MAX_PATH_DEPTH) {
return false;
}
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
*/
static cx_sha3_t *get_last_hash_ctx(void)
{
return (cx_sha3_t*)mem_alloc(0) - 1;
static cx_sha3_t *get_last_hash_ctx(void) {
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
*/
static void finalize_hash_depth(uint8_t *hash)
{
static void finalize_hash_depth(uint8_t *hash) {
const cx_sha3_t *hash_ctx;
hash_ctx = get_last_hash_ctx();
// finalize hash
cx_hash((cx_hash_t*)hash_ctx,
CX_LAST,
NULL,
0,
hash,
KECCAK256_HASH_BYTESIZE);
mem_dealloc(sizeof(*hash_ctx)); // remove hash context
cx_hash((cx_hash_t *) hash_ctx, CX_LAST, 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
*/
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;
hash_ctx = get_last_hash_ctx();
// continue progressive hash with the array hash
cx_hash((cx_hash_t*)hash_ctx,
0,
hash,
KECCAK256_HASH_BYTESIZE,
NULL,
0);
cx_hash((cx_hash_t *) hash_ctx, 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
* @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;
// 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;
}
if (init)
{
cx_keccak_init(hash_ctx, 256); // initialize it
if (init) {
cx_keccak_init(hash_ctx, 256); // initialize it
}
return true;
}
@@ -220,38 +187,27 @@ static bool push_new_hash_depth(bool init)
*
* @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];
if (path_struct == NULL)
{
if (path_struct == NULL) {
return false;
}
if (path_struct->depth_count == 0)
{
if (path_struct->depth_count == 0) {
return false;
}
path_struct->depth_count -= 1;
finalize_hash_depth(hash);
if (path_struct->depth_count > 0)
{
if (path_struct->depth_count > 0) {
feed_last_hash_depth(hash);
}
else
{
switch (path_struct->root_type)
{
} else {
switch (path_struct->root_type) {
case ROOT_DOMAIN:
memcpy(tmpCtx.messageSigningContext712.domainHash,
hash,
KECCAK256_HASH_BYTESIZE);
memcpy(tmpCtx.messageSigningContext712.domainHash, hash, KECCAK256_HASH_BYTESIZE);
break;
case ROOT_MESSAGE:
memcpy(tmpCtx.messageSigningContext712.messageHash,
hash,
KECCAK256_HASH_BYTESIZE);
memcpy(tmpCtx.messageSigningContext712.messageHash, hash, KECCAK256_HASH_BYTESIZE);
break;
default:
break;
@@ -268,17 +224,14 @@ static bool path_depth_list_pop(void)
* @param[in] the number of elements contained in that depth
* @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;
if (path_struct == NULL)
{
if (path_struct == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
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;
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
*/
static bool array_depth_list_pop(void)
{
static bool array_depth_list_pop(void) {
uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL)
{
if (path_struct == NULL) {
return false;
}
if (path_struct->array_depth_count == 0)
{
if (path_struct->array_depth_count == 0) {
return false;
}
@@ -321,8 +271,7 @@ static bool array_depth_list_pop(void)
*
* @return whether the path update worked or not
*/
static bool path_update(void)
{
static bool path_update(void) {
uint8_t fields_count;
const void *struct_ptr;
const void *field_ptr;
@@ -330,34 +279,27 @@ static bool path_update(void)
uint8_t typename_len;
uint8_t hash[KECCAK256_HASH_BYTESIZE];
if (path_struct == NULL)
{
if (path_struct == NULL) {
return false;
}
if ((field_ptr = get_field(NULL)) == NULL)
{
if ((field_ptr = get_field(NULL)) == NULL) {
return false;
}
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);
if ((struct_ptr = get_structn(typename, typename_len)) == NULL)
{
if ((struct_ptr = get_structn(typename, typename_len)) == NULL) {
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;
}
if (push_new_hash_depth(true) == false)
{
if (push_new_hash_depth(true) == false) {
return false;
}
// get the struct typehash
if (type_hash(typename, typename_len, hash) == false)
{
if (type_hash(typename, typename_len, hash) == false) {
return false;
}
feed_last_hash_depth(hash);
@@ -375,23 +317,19 @@ static bool path_update(void)
* @param[in] name_length the root struct name length
* @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];
if (path_struct == NULL)
{
if (path_struct == NULL) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
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 (");
for (int i = 0; i < name_length; ++i)
{
for (int i = 0; i < name_length; ++i) {
PRINTF("%c", struct_name[i]);
}
PRINTF(")!\n");
@@ -399,12 +337,10 @@ bool path_set_root(const char *const struct_name, uint8_t name_length)
return false;
}
if (push_new_hash_depth(true) == false)
{
if (push_new_hash_depth(true) == false) {
return false;
}
if (type_hash(struct_name, name_length, hash) == false)
{
if (type_hash(struct_name, name_length, hash) == false) {
return false;
}
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;
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;
}
else
{
} else {
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,
uint8_t total_count,
uint8_t pidx,
uint8_t size)
{
uint8_t size) {
uint8_t expected_size;
uint8_t arr_idx;
e_array_type expected_type;
arr_idx = (total_count - path_struct->array_depth_count) - 1;
// we skip index 0, since we already have it
for (uint8_t idx = 1; idx < (arr_idx + 1); ++idx)
{
if ((depth = get_next_struct_field_array_lvl(depth)) == NULL)
{
for (uint8_t idx = 1; idx < (arr_idx + 1); ++idx) {
if ((depth = get_next_struct_field_array_lvl(depth)) == NULL) {
return false;
}
}
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;
PRINTF("Unexpected array depth size. (expected %d, got %d)\n",
expected_size, size);
PRINTF("Unexpected array depth size. (expected %d, got %d)\n", expected_size, size);
return false;
}
// add it
if (!array_depth_list_push(pidx, size))
{
if (!array_depth_list_push(pidx, size)) {
return false;
}
return true;
@@ -482,9 +409,7 @@ static bool check_and_add_array_depth(const void *depth,
* @param[in] length length of data
* @return whether the add was successful or not
*/
bool path_new_array_depth(const uint8_t *const data,
uint8_t length)
{
bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
const void *field_ptr = NULL;
const void *depth = NULL;
uint8_t depth_count;
@@ -492,36 +417,27 @@ bool path_new_array_depth(const uint8_t *const data,
uint8_t pidx;
bool is_custom;
if (path_struct == NULL)
{
if (path_struct == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
else if (length != 1)
{
} else if (length != 1) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
for (pidx = 0; pidx < path_struct->depth_count; ++pidx)
{
if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL)
{
for (pidx = 0; pidx < path_struct->depth_count; ++pidx) {
if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
if (struct_field_is_array(field_ptr))
{
if ((depth = get_struct_field_array_lvls_array(field_ptr, &depth_count)) == NULL)
{
if (struct_field_is_array(field_ptr)) {
if ((depth = get_struct_field_array_lvls_array(field_ptr, &depth_count)) == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
total_count += depth_count;
if (total_count > path_struct->array_depth_count)
{
if (!check_and_add_array_depth(depth, total_count, pidx, *data))
{
if (total_count > path_struct->array_depth_count) {
if (!check_and_add_array_depth(depth, total_count, pidx, *data)) {
return false;
}
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;
PRINTF("Did not find a matching array type.\n");
return false;
}
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;
}
if (is_custom)
{
if (is_custom) {
cx_sha3_t *hash_ctx = get_last_hash_ctx();
cx_sha3_t *old_ctx = hash_ctx - 1;
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;
@@ -557,27 +470,22 @@ bool path_new_array_depth(const uint8_t *const data,
*
* @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;
uint8_t *depth = &path_struct->depths[path_struct->depth_count - 1];
uint8_t fields_count;
if (path_struct == NULL)
{
if (path_struct == NULL) {
return false;
}
if ((get_field(&fields_count)) == NULL)
{
if ((get_field(&fields_count)) == NULL) {
return false;
}
if (path_struct->depth_count > 0)
{
if (path_struct->depth_count > 0) {
*depth += 1;
end_reached = (*depth == fields_count);
}
if (end_reached)
{
if (end_reached) {
path_depth_list_pop();
}
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.
*/
static bool path_advance_in_array(void)
{
static bool path_advance_in_array(void) {
bool end_reached;
s_array_depth *arr_depth;
if (path_struct == NULL)
{
if (path_struct == NULL) {
return false;
}
do
{
do {
end_reached = false;
arr_depth = &path_struct->array_depths[path_struct->array_depth_count - 1];
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;
if (arr_depth->size == 0)
{
if (arr_depth->size == 0) {
array_depth_list_pop();
end_reached = true;
}
else
{
} else {
return false;
}
}
}
while (end_reached);
} while (end_reached);
return true;
}
@@ -626,22 +526,16 @@ static bool path_advance_in_array(void)
*
* @return whether the advancement was successful or not
*/
bool path_advance(void)
{
bool path_advance(void) {
bool end_reached;
do
{
if (path_advance_in_array())
{
do {
if (path_advance_in_array()) {
end_reached = path_advance_in_struct();
}
else
{
} else {
end_reached = false;
}
}
while (end_reached);
} while (end_reached);
path_update();
return true;
}
@@ -651,10 +545,8 @@ bool path_advance(void)
*
* @return enum representing root type
*/
e_root_type path_get_root_type(void)
{
if (path_struct == NULL)
{
e_root_type path_get_root_type(void) {
if (path_struct == NULL) {
return ROOT_DOMAIN;
}
return path_struct->root_type;
@@ -665,10 +557,8 @@ e_root_type path_get_root_type(void)
*
* @return pointer to the root structure definition
*/
const void *path_get_root(void)
{
if (path_struct == NULL)
{
const void *path_get_root(void) {
if (path_struct == NULL) {
return NULL;
}
return path_struct->root_struct;
@@ -679,10 +569,8 @@ const void *path_get_root(void)
*
* @return depth count
*/
uint8_t path_get_depth_count(void)
{
if (path_struct == NULL)
{
uint8_t path_get_depth_count(void) {
if (path_struct == NULL) {
return 0;
}
return path_struct->depth_count;
@@ -693,16 +581,11 @@ uint8_t path_get_depth_count(void)
*
* @return whether the memory allocation were successful.
*/
bool path_init(void)
{
if (path_struct == NULL)
{
if ((path_struct = MEM_ALLOC_AND_ALIGN_TYPE(*path_struct)) == NULL)
{
bool path_init(void) {
if (path_struct == NULL) {
if ((path_struct = MEM_ALLOC_AND_ALIGN_TYPE(*path_struct)) == NULL) {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
}
else
{
} else {
path_struct->depth_count = 0;
}
}
@@ -712,9 +595,8 @@ bool path_init(void)
/**
* De-initialize the path context
*/
void path_deinit(void)
{
void path_deinit(void) {
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_ARRAY_DEPTH 4
typedef struct
{
typedef struct {
uint8_t path_index;
uint8_t size;
} s_array_depth;
} s_array_depth;
typedef enum
{
ROOT_DOMAIN,
ROOT_MESSAGE
} e_root_type;
typedef enum { ROOT_DOMAIN, ROOT_MESSAGE } e_root_type;
typedef struct
{
typedef struct {
uint8_t depth_count;
uint8_t depths[MAX_PATH_DEPTH];
uint8_t array_depth_count;
s_array_depth array_depths[MAX_ARRAY_DEPTH];
const void *root_struct;
e_root_type root_type;
} s_path;
} s_path;
bool path_set_root(const char *const struct_name, uint8_t length);
const void *path_get_field(void);
bool path_advance(void);
bool path_init(void);
void path_deinit(void);
bool path_new_array_depth(const uint8_t *const data,
uint8_t length);
bool path_set_root(const char *const struct_name, uint8_t length);
const void *path_get_field(void);
bool path_advance(void);
bool path_init(void);
void path_deinit(void);
bool path_new_array_depth(const uint8_t *const data, uint8_t length);
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_to_last(uint8_t n);
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
*/
bool compute_schema_hash(void)
{
bool compute_schema_hash(void) {
const void *struct_ptr;
uint8_t structs_count;
const void *field_ptr;
@@ -32,42 +31,37 @@ bool compute_schema_hash(void)
cx_sha224_init(&hash_ctx);
struct_ptr = get_structs_array(&structs_count);
hash_byte('{', (cx_hash_t*)&hash_ctx);
while (structs_count-- > 0)
{
hash_byte('{', (cx_hash_t *) &hash_ctx);
while (structs_count-- > 0) {
name = get_struct_name(struct_ptr, &name_length);
hash_byte('"', (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_byte('"', (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);
field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
while (fields_count-- > 0)
{
hash_nbytes((uint8_t*)"{\"name\":\"", 9, (cx_hash_t*)&hash_ctx);
while (fields_count-- > 0) {
hash_nbytes((uint8_t *) "{\"name\":\"", 9, (cx_hash_t *) &hash_ctx);
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*)"\",\"type\":\"", 10, (cx_hash_t*)&hash_ctx);
if (!format_hash_field_type(field_ptr, (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);
if (!format_hash_field_type(field_ptr, (cx_hash_t *) &hash_ctx)) {
return false;
}
hash_nbytes((uint8_t*)"\"}", 2, (cx_hash_t*)&hash_ctx);
if (fields_count > 0)
{
hash_byte(',', (cx_hash_t*)&hash_ctx);
hash_nbytes((uint8_t *) "\"}", 2, (cx_hash_t *) &hash_ctx);
if (fields_count > 0) {
hash_byte(',', (cx_hash_t *) &hash_ctx);
}
field_ptr = get_next_struct_field(field_ptr);
}
hash_byte(']', (cx_hash_t*)&hash_ctx);
if (structs_count > 0)
{
hash_byte(',', (cx_hash_t*)&hash_ctx);
hash_byte(']', (cx_hash_t *) &hash_ctx);
if (structs_count > 0) {
hash_byte(',', (cx_hash_t *) &hash_ctx);
}
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
cx_hash((cx_hash_t*)&hash_ctx,
cx_hash((cx_hash_t *) &hash_ctx,
CX_LAST,
NULL,
0,
@@ -76,4 +70,4 @@ bool compute_schema_hash(void)
return true;
}
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -5,8 +5,8 @@
#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 "mem.h"
#include "os_pic.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
#include "utils.h" // ARRAY_SIZE
#include "utils.h" // ARRAY_SIZE
// 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;
enum
{
IDX_ENUM = 0,
IDX_STR_IDX,
IDX_COUNT
};
enum { IDX_ENUM = 0, IDX_STR_IDX, IDX_COUNT };
/**
* 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
* @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;
// loop over enum/typename pairs
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
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 (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;
}
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;
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
*/
bool sol_typenames_init(void)
{
bool sol_typenames_init(void) {
const char *const typenames[] = {
"int", // 0
"uint", // 1
@@ -68,39 +60,32 @@ bool sol_typenames_init(void)
"bytes" // 5
};
// \ref TYPES_COUNT - 1 since we don't include \ref TYPE_CUSTOM
const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT] = {
{ TYPE_SOL_INT, 0 },
{ TYPE_SOL_UINT, 1 },
{ TYPE_SOL_ADDRESS, 2 },
{ TYPE_SOL_BOOL, 3 },
{ TYPE_SOL_STRING, 4 },
{ TYPE_SOL_BYTES_FIX, 5 },
{ TYPE_SOL_BYTES_DYN, 5 }
};
const uint8_t enum_to_idx[TYPES_COUNT - 1][IDX_COUNT] = {{TYPE_SOL_INT, 0},
{TYPE_SOL_UINT, 1},
{TYPE_SOL_ADDRESS, 2},
{TYPE_SOL_BOOL, 3},
{TYPE_SOL_STRING, 4},
{TYPE_SOL_BYTES_FIX, 5},
{TYPE_SOL_BYTES_DYN, 5}};
uint8_t *typename_len_ptr;
char *typename_ptr;
if ((sol_typenames = mem_alloc(sizeof(uint8_t))) == NULL)
{
if ((sol_typenames = mem_alloc(sizeof(uint8_t))) == NULL) {
return false;
}
*(sol_typenames) = 0;
// 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 (find_enum_matches(enum_to_idx, t_idx))
{
if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL)
{
if (find_enum_matches(enum_to_idx, t_idx)) {
if ((typename_len_ptr = mem_alloc(sizeof(uint8_t))) == NULL) {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false;
}
// get pointer to the allocated space just above
*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;
return false;
}
@@ -120,9 +105,7 @@ bool sol_typenames_init(void)
* @param[out] length length of the returned typename
* @return typename or \ref NULL in case it wasn't found
*/
const char *get_struct_field_sol_typename(const uint8_t *field_ptr,
uint8_t *const length)
{
const char *get_struct_field_sol_typename(const uint8_t *field_ptr, uint8_t *const length) {
e_type field_type;
const uint8_t *typename_ptr;
uint8_t typenames_count;
@@ -132,25 +115,22 @@ const char *get_struct_field_sol_typename(const uint8_t *field_ptr,
field_type = struct_field_type(field_ptr);
typename_ptr = get_array_in_mem(sol_typenames, &typenames_count);
typename_found = false;
while (typenames_count-- > 0)
{
while (typenames_count-- > 0) {
more_type = true;
while (more_type)
{
while (more_type) {
more_type = *typename_ptr & TYPENAME_MORE_TYPE;
e_type type_enum = *typename_ptr & TYPENAME_ENUM;
if (type_enum == field_type)
{
if (type_enum == field_type) {
typename_found = true;
}
typename_ptr += 1;
}
typename_ptr = (uint8_t*)get_string_in_mem(typename_ptr, length);
if (typename_found) return (char*)typename_ptr;
typename_ptr = (uint8_t *) get_string_in_mem(typename_ptr, length);
if (typename_found) return (char *) typename_ptr;
typename_ptr += *length;
}
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);
const char *get_struct_field_sol_typename(const uint8_t *ptr,
uint8_t *const length);
const char *get_struct_field_sol_typename(const uint8_t *ptr, 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 "type_hash.h"
#include "shared_context.h"
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE
#include "format_hash_field_type.h"
#include "hash_bytes.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
/**
@@ -19,21 +19,19 @@
* @param[in] field_ptr pointer to the struct field
* @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;
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;
}
// space between field type name and field name
hash_byte(' ', (cx_hash_t*)&global_sha3);
hash_byte(' ', (cx_hash_t *) &global_sha3);
// field name
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;
}
@@ -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
* @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;
uint8_t struct_name_length;
const uint8_t *field_ptr;
@@ -53,29 +50,26 @@ static bool encode_and_hash_type(const void *const struct_ptr)
// struct name
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
hash_byte('(', (cx_hash_t*)&global_sha3);
hash_byte('(', (cx_hash_t *) &global_sha3);
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
if (idx > 0)
{
hash_byte(',', (cx_hash_t*)&global_sha3);
if (idx > 0) {
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;
}
field_ptr = get_next_struct_field(field_ptr);
}
// closing struct parenthese
hash_byte(')', (cx_hash_t*)&global_sha3);
hash_byte(')', (cx_hash_t *) &global_sha3);
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,out] deps pointer to the first dependency pointer
*/
static void sort_dependencies(uint8_t deps_count,
const void **deps)
{
static void sort_dependencies(uint8_t deps_count, const void **deps) {
bool changed;
const void *tmp_ptr;
const char *name1, *name2;
uint8_t namelen1, namelen2;
int str_cmp_result;
do
{
do {
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);
name2 = get_struct_name(*(deps + idx + 1), &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);
*(deps + idx) = *(deps + idx + 1);
*(deps + idx + 1) = tmp_ptr;
@@ -113,8 +102,7 @@ static void sort_dependencies(uint8_t deps_count,
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,
const void **first_dep,
const void *const struct_ptr)
{
const void *const struct_ptr) {
uint8_t fields_count;
const void *field_ptr;
const char *arg_structname;
@@ -138,35 +125,28 @@ static const void **get_struct_dependencies(uint8_t *const deps_count,
const void **new_dep;
field_ptr = get_struct_fields_array(struct_ptr, &fields_count);
for (uint8_t idx = 0; idx < fields_count; ++idx)
{
if (struct_field_type(field_ptr) == TYPE_CUSTOM)
{
for (uint8_t idx = 0; idx < fields_count; ++idx) {
if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
// get struct name
arg_structname = get_struct_field_typename(field_ptr, &arg_structname_length);
// from its name, get the pointer to its definition
arg_struct_ptr = get_structn(arg_structname, arg_structname_length);
// 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!
if (*(first_dep + dep_idx) == arg_struct_ptr)
{
if (*(first_dep + dep_idx) == arg_struct_ptr) {
break;
}
}
// 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;
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;
return NULL;
}
if (*deps_count == 1)
{
if (*deps_count == 1) {
first_dep = new_dep;
}
*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
* @return pointer to encoded string or \ref NULL in case of a memory allocation error
*/
bool type_hash(const char *const struct_name,
const uint8_t struct_name_length,
uint8_t *hash_buf)
{
const void *const struct_ptr = get_structn(struct_name,
struct_name_length);
bool type_hash(const char *const struct_name, const uint8_t struct_name_length, uint8_t *hash_buf) {
const void *const struct_ptr = get_structn(struct_name, struct_name_length);
uint8_t deps_count = 0;
const void **deps;
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);
if ((deps_count > 0) && (deps == NULL))
{
if ((deps_count > 0) && (deps == NULL)) {
return false;
}
sort_dependencies(deps_count, deps);
if (encode_and_hash_type(struct_ptr) == false)
{
if (encode_and_hash_type(struct_ptr) == false) {
return false;
}
// loop over each struct and generate string
for (int idx = 0; idx < deps_count; ++idx)
{
if (encode_and_hash_type(*deps) == false)
{
for (int idx = 0; idx < deps_count; ++idx) {
if (encode_and_hash_type(*deps) == false) {
return false;
}
deps += 1;
@@ -220,13 +192,8 @@ bool type_hash(const char *const struct_name,
mem_dealloc(mem_alloc(0) - mem_loc_bak);
// copy hash into memory
cx_hash((cx_hash_t*)&global_sha3,
CX_LAST,
NULL,
0,
hash_buf,
KECCAK256_HASH_BYTESIZE);
cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, hash_buf, KECCAK256_HASH_BYTESIZE);
return true;
}
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -6,10 +6,8 @@
#include <stdint.h>
#include <stdbool.h>
bool type_hash(const char *const struct_name,
const uint8_t struct_name_length,
uint8_t *hash_buf);
bool type_hash(const char *const struct_name, 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 "typed_data.h"
#include "sol_typenames.h"
#include "apdu_constants.h" // APDU response codes
#include "apdu_constants.h" // APDU response codes
#include "context.h"
#include "mem.h"
#include "mem_utils.h"
@@ -16,18 +16,14 @@ static s_typed_data *typed_data = NULL;
*
* @return whether the memory allocation was successful
*/
bool typed_data_init(void)
{
if (typed_data == NULL)
{
if ((typed_data = MEM_ALLOC_AND_ALIGN_TYPE(*typed_data)) == NULL)
{
bool typed_data_init(void) {
if (typed_data == NULL) {
if ((typed_data = MEM_ALLOC_AND_ALIGN_TYPE(*typed_data)) == NULL) {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
return false;
}
// 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;
return false;
}
@@ -38,8 +34,7 @@ bool typed_data_init(void)
return true;
}
void typed_data_deinit(void)
{
void typed_data_deinit(void) {
typed_data = NULL;
}
@@ -50,10 +45,8 @@ void typed_data_deinit(void)
* @param[in] ptr pointer to the current location within the struct field
* @return pointer to the data right after
*/
static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr,
const uint8_t *ptr)
{
(void)ptr;
static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr, const uint8_t *ptr) {
(void) ptr;
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
* @return pointer to the data right after
*/
static const uint8_t *field_skip_typename(const uint8_t *field_ptr,
const uint8_t *ptr)
{
static const uint8_t *field_skip_typename(const uint8_t *field_ptr, const uint8_t *ptr) {
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);
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
* @return pointer to the data right after
*/
static const uint8_t *field_skip_typesize(const uint8_t *field_ptr,
const uint8_t *ptr)
{
if (struct_field_has_typesize(field_ptr))
{
static const uint8_t *field_skip_typesize(const uint8_t *field_ptr, const uint8_t *ptr) {
if (struct_field_has_typesize(field_ptr)) {
ptr += sizeof(typesize_t);
}
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
* @return pointer to the data right after
*/
static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr,
const uint8_t *ptr)
{
static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr, const uint8_t *ptr) {
uint8_t size;
if (struct_field_is_array(field_ptr))
{
if (struct_field_is_array(field_ptr)) {
ptr = get_array_in_mem(ptr, &size);
while (size-- > 0)
{
while (size-- > 0) {
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
* @return pointer to the data right after
*/
static const uint8_t *field_skip_keyname(const uint8_t *field_ptr,
const uint8_t *ptr)
{
static const uint8_t *field_skip_keyname(const uint8_t *field_ptr, const uint8_t *ptr) {
uint8_t size;
(void)field_ptr;
(void) field_ptr;
ptr = get_array_in_mem(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
* @return pointer to data
*/
const void *get_array_in_mem(const void *ptr, uint8_t *const array_size)
{
if (ptr == NULL)
{
const void *get_array_in_mem(const void *ptr, uint8_t *const array_size) {
if (ptr == NULL) {
return NULL;
}
if (array_size)
{
*array_size = *(uint8_t*)ptr;
if (array_size) {
*array_size = *(uint8_t *) ptr;
}
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
* @return pointer to beginning of the string
*/
const char *get_string_in_mem(const uint8_t *ptr, uint8_t *const string_length)
{
return (char*)get_array_in_mem(ptr, 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);
}
/**
@@ -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
* @return TypeDesc
*/
static inline typedesc_t get_struct_field_typedesc(const uint8_t *const field_ptr)
{
if (field_ptr == NULL)
{
static inline typedesc_t get_struct_field_typedesc(const uint8_t *const field_ptr) {
if (field_ptr == NULL) {
return 0;
}
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
* @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);
}
@@ -198,8 +172,7 @@ bool struct_field_is_array(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer
* @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);
}
@@ -209,8 +182,7 @@ bool struct_field_has_typesize(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer
* @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);
}
@@ -220,10 +192,8 @@ e_type struct_field_type(const uint8_t *const field_ptr)
* @param[in] field_ptr struct field pointer
* @return its type size
*/
uint8_t get_struct_field_typesize(const uint8_t *const field_ptr)
{
if (field_ptr == NULL)
{
uint8_t get_struct_field_typesize(const uint8_t *const field_ptr) {
if (field_ptr == NULL) {
return 0;
}
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
* @return type name pointer
*/
const char *get_struct_field_custom_typename(const uint8_t *field_ptr,
uint8_t *const length)
{
const char *get_struct_field_custom_typename(const uint8_t *field_ptr, uint8_t *const length) {
const uint8_t *ptr;
if (field_ptr == NULL)
{
if (field_ptr == NULL) {
return 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
* @return type name pointer
*/
const char *get_struct_field_typename(const uint8_t *field_ptr,
uint8_t *const length)
{
if (field_ptr == NULL)
{
const char *get_struct_field_typename(const uint8_t *field_ptr, uint8_t *const length) {
if (field_ptr == 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_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
* @return array type of that depth
*/
e_array_type struct_field_array_depth(const uint8_t *array_depth_ptr,
uint8_t *const array_size)
{
if (array_depth_ptr == NULL)
{
e_array_type struct_field_array_depth(const uint8_t *array_depth_ptr, uint8_t *const array_size) {
if (array_depth_ptr == NULL) {
return 0;
}
if (*array_depth_ptr == ARRAY_FIXED_SIZE)
{
if (array_size != NULL)
{
if (*array_depth_ptr == ARRAY_FIXED_SIZE) {
if (array_size != NULL) {
*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
* @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;
if (array_depth_ptr == NULL)
{
if (array_depth_ptr == NULL) {
return NULL;
}
switch (*array_depth_ptr)
{
switch (*array_depth_ptr) {
case ARRAY_DYNAMIC:
ptr = array_depth_ptr;
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
*/
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;
if (field_ptr == NULL)
{
if (field_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
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
* @return key name
*/
const char *get_struct_field_keyname(const uint8_t *field_ptr,
uint8_t *const length)
{
const char *get_struct_field_keyname(const uint8_t *field_ptr, uint8_t *const length) {
const uint8_t *ptr;
if (field_ptr == NULL)
{
if (field_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL;
}
@@ -377,12 +327,10 @@ const char *get_struct_field_keyname(const uint8_t *field_ptr,
* @param[in] field_ptr given struct 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;
if (field_ptr == NULL)
{
if (field_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL;
}
@@ -400,14 +348,12 @@ const uint8_t *get_next_struct_field(const void *const field_ptr)
* @param[out] length name length
* @return struct name
*/
const char *get_struct_name(const uint8_t *const struct_ptr, uint8_t *const length)
{
if (struct_ptr == NULL)
{
const char *get_struct_name(const uint8_t *const struct_ptr, uint8_t *const length) {
if (struct_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
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
* @return struct name
*/
const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr,
uint8_t *const length)
{
const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr, uint8_t *const length) {
const void *ptr;
uint8_t name_length;
if (struct_ptr == NULL)
{
if (struct_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL;
}
ptr = struct_ptr;
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);
}
@@ -440,19 +383,16 @@ const uint8_t *get_struct_fields_array(const uint8_t *const struct_ptr,
* @param[in] struct_ptr given 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;
const void *ptr;
if (struct_ptr == NULL)
{
if (struct_ptr == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL;
}
ptr = get_struct_fields_array(struct_ptr, &fields_count);
while (fields_count-- > 0)
{
while (fields_count-- > 0) {
ptr = get_next_struct_field(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
* @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);
}
@@ -476,25 +415,20 @@ const uint8_t *get_structs_array(uint8_t *const length)
* @param[in] length name length
* @return pointer to struct
*/
const uint8_t *get_structn(const char *const name,
const uint8_t length)
{
const uint8_t *get_structn(const char *const name, const uint8_t length) {
uint8_t structs_count;
const uint8_t *struct_ptr;
const char *struct_name;
uint8_t name_length;
if (name == NULL)
{
if (name == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return NULL;
}
struct_ptr = get_structs_array(&structs_count);
while (structs_count-- > 0)
{
while (structs_count-- > 0) {
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;
}
struct_ptr = get_next_struct(struct_ptr);
@@ -510,13 +444,11 @@ const uint8_t *get_structn(const char *const name,
* @param[in] name name
* @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;
char *name_ptr;
if ((name == NULL) || (typed_data == NULL))
{
if ((name == NULL) || (typed_data == NULL)) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
@@ -524,24 +456,21 @@ bool set_struct_name(uint8_t length, const uint8_t *const name)
*(typed_data->structs_array) += 1;
// 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;
return false;
}
*length_ptr = length;
// 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;
return false;
}
memmove(name_ptr, name, length);
// 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;
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,
uint8_t *data_idx,
uint8_t length)
{
uint8_t length) {
typedesc_t *typedesc_ptr;
// 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;
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;
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,
uint8_t *data_idx,
uint8_t length)
{
uint8_t length) {
uint8_t *typename_len_ptr;
char *typename;
// 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;
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;
return false;
}
*typename_len_ptr = data[(*data_idx)++];
// 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;
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;
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
* @return whether it was successful
*/
static bool set_struct_field_array(const uint8_t *const data,
uint8_t *data_idx,
uint8_t length)
{
static bool set_struct_field_array(const uint8_t *const data, uint8_t *data_idx, uint8_t length) {
uint8_t *array_levels_count;
e_array_type *array_level;
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;
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;
return false;
}
*array_levels_count = data[(*data_idx)++];
for (int idx = 0; idx < *array_levels_count; ++idx)
{
if ((*data_idx + sizeof(*array_level)) > length) // check buffer bound
for (int idx = 0; idx < *array_levels_count; ++idx) {
if ((*data_idx + sizeof(*array_level)) > length) // check buffer bound
{
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
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;
return false;
}
*array_level = data[(*data_idx)++];
if (*array_level > ARRAY_TYPES_COUNT)
{
if (*array_level > ARRAY_TYPES_COUNT) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
switch (*array_level)
{
case ARRAY_DYNAMIC: // nothing to do
switch (*array_level) {
case ARRAY_DYNAMIC: // nothing to do
break;
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;
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;
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,
uint8_t *data_idx,
uint8_t length)
{
uint8_t length) {
uint8_t *typesize_ptr;
// 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;
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;
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
* @return whether it was successful
*/
static bool set_struct_field_keyname(const uint8_t *const data,
uint8_t *data_idx,
uint8_t length)
{
static bool set_struct_field_keyname(const uint8_t *const data, uint8_t *data_idx, uint8_t length) {
uint8_t *keyname_len_ptr;
char *keyname_ptr;
// 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;
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;
return false;
}
*keyname_len_ptr = data[(*data_idx)++];
// 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;
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;
return false;
}
@@ -768,58 +676,45 @@ static bool set_struct_field_keyname(const uint8_t *const data,
* @param[in] data the field data
* @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;
uint8_t data_idx = 0;
if ((data == NULL) || (length == 0))
{
if ((data == NULL) || (length == 0)) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
else if (typed_data == NULL)
{
} else if (typed_data == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
// increment number of struct fields
*(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;
}
// check TypeSize flag in TypeDesc
if (*typedesc_ptr & TYPESIZE_MASK)
{
if (set_struct_field_typesize(data, &data_idx, length) == false)
{
if (*typedesc_ptr & TYPESIZE_MASK) {
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;
}
}
else if ((*typedesc_ptr & TYPE_MASK) == TYPE_CUSTOM)
{
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)
{
if (*typedesc_ptr & ARRAY_MASK) {
if (set_struct_field_array(data, &data_idx, length) == 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;
}
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;
return false;
@@ -827,4 +722,4 @@ bool set_struct_field(uint8_t length, const uint8_t *const data)
return true;
}
#endif // HAVE_EIP712_FULL_SUPPORT
#endif // HAVE_EIP712_FULL_SUPPORT

View File

@@ -7,21 +7,14 @@
#include <stdbool.h>
// TypeDesc masks
#define TYPE_MASK (0xF)
#define ARRAY_MASK (1 << 7)
#define TYPESIZE_MASK (1 << 6)
#define TYPENAME_ENUM (0xF)
#define TYPE_MASK (0xF)
#define ARRAY_MASK (1 << 7)
#define TYPESIZE_MASK (1 << 6)
#define TYPENAME_ENUM (0xF)
typedef enum { ARRAY_DYNAMIC = 0, ARRAY_FIXED_SIZE, ARRAY_TYPES_COUNT } e_array_type;
typedef enum
{
ARRAY_DYNAMIC = 0,
ARRAY_FIXED_SIZE,
ARRAY_TYPES_COUNT
} e_array_type;
typedef enum
{
typedef enum {
// contract defined struct
TYPE_CUSTOM = 0,
// native types
@@ -33,48 +26,40 @@ typedef enum
TYPE_SOL_BYTES_FIX,
TYPE_SOL_BYTES_DYN,
TYPES_COUNT
} e_type;
} e_type;
typedef struct
{
typedef struct {
uint8_t *structs_array;
uint8_t *current_struct_fields_array;
} s_typed_data;
} s_typed_data;
typedef uint8_t typedesc_t;
typedef uint8_t typesize_t;
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);
bool struct_field_is_array(const uint8_t *ptr);
bool struct_field_has_typesize(const uint8_t *ptr);
e_type struct_field_type(const uint8_t *ptr);
bool struct_field_is_array(const uint8_t *ptr);
bool struct_field_has_typesize(const uint8_t *ptr);
e_type struct_field_type(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,
uint8_t *const length);
const char *get_struct_field_typename(const uint8_t *ptr,
uint8_t *const length);
e_array_type struct_field_array_depth(const uint8_t *ptr,
uint8_t *const array_size);
const char *get_struct_field_custom_typename(const uint8_t *ptr, uint8_t *const length);
const char *get_struct_field_typename(const uint8_t *ptr, 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 *struct_field_half_skip(const uint8_t *ptr);
const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const ptr,
uint8_t *const length);
const char *get_struct_field_keyname(const uint8_t *ptr,
uint8_t *const length);
const uint8_t *get_struct_field_array_lvls_array(const uint8_t *const 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 char *get_struct_name(const uint8_t *ptr, uint8_t *const length);
const uint8_t *get_struct_fields_array(const uint8_t *ptr,
uint8_t *const length);
const uint8_t *get_struct_fields_array(const uint8_t *ptr, uint8_t *const length);
const uint8_t *get_next_struct(const uint8_t *ptr);
const uint8_t *get_structs_array(uint8_t *const length);
const uint8_t *get_structn(const char *const name_ptr,
const uint8_t name_length);
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 typed_data_init(void);
void typed_data_deinit(void);
const uint8_t *get_structn(const char *const name_ptr, const uint8_t name_length);
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 typed_data_init(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_logic.h"
#include "shared_context.h" // strings
#include "shared_context.h" // strings
// clang-format off
UX_STEP_NOCB(
@@ -54,4 +54,4 @@ UX_FLOW(ux_712_flow,
&ux_712_step_approve,
&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[];
#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 "ui_flow_712.h"
#include "shared_context.h"
#include "ethUtils.h" // getEthDisplayableAddress
#include "utils.h" // uint256_to_decimal
#include "ethUtils.h" // getEthDisplayableAddress
#include "utils.h" // uint256_to_decimal
#include "common_712.h"
#include "context.h" // eip712_context_deinit
#include "uint256.h" // tostring256 && tostring256_signed
#include "path.h" // path_get_root_type
#include "apdu_constants.h" // APDU response codes
#include "context.h" // eip712_context_deinit
#include "uint256.h" // tostring256 && tostring256_signed
#include "path.h" // path_get_root_type
#include "apdu_constants.h" // APDU response codes
#include "typed_data.h"
#include "commands_712.h"
static t_ui_context *ui_ctx = NULL;
/**
* Checks on the UI context to determine if the next EIP 712 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;
if (ui_ctx->filtering_mode == EIP712_FILTERING_BASIC)
{
if (N_storage.verbose_eip712 || (path_get_root_type() == ROOT_DOMAIN))
{
if (ui_ctx->filtering_mode == EIP712_FILTERING_BASIC) {
if (N_storage.verbose_eip712 || (path_get_root_type() == ROOT_DOMAIN)) {
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;
}
}
@@ -62,22 +55,17 @@ static void ui_712_set_buf(const char *const src,
size_t src_length,
char *const dst,
size_t dst_length,
bool explicit_trunc)
{
bool explicit_trunc) {
uint8_t cpy_length;
if (src_length < dst_length)
{
if (src_length < dst_length) {
cpy_length = src_length;
}
else
{
} else {
cpy_length = dst_length - 1;
}
memcpy(dst, src, cpy_length);
dst[cpy_length] = '\0';
if (explicit_trunc && (src_length > dst_length))
{
if (explicit_trunc && (src_length > dst_length)) {
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
*/
void ui_712_finalize_field(void)
{
if (!ui_712_field_shown())
{
void ui_712_finalize_field(void) {
if (!ui_712_field_shown()) {
ui_712_next_field();
}
ui_712_field_flags_reset();
@@ -100,8 +86,7 @@ void ui_712_finalize_field(void)
* @param[in] str the new title
* @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);
}
@@ -111,23 +96,19 @@ void ui_712_set_title(const char *const str, uint8_t length)
* @param[in] str the new value
* @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);
}
/**
* Redraw the dynamic UI step that shows EIP712 information
*/
void ui_712_redraw_generic_step(void)
{
if (!ui_ctx->shown) // Initialize if it is not already
void ui_712_redraw_generic_step(void) {
if (!ui_ctx->shown) // Initialize if it is not already
{
ux_flow_init(0, ux_712_flow, NULL);
ui_ctx->shown = true;
}
else
{
} else {
// 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
// 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
* && the approve/reject screen
*/
void ui_712_next_field(void)
{
if (ui_ctx == NULL)
{
void ui_712_next_field(void) {
if (ui_ctx == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
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_ctx->structs_to_review -= 1;
}
else
{
if (!ui_ctx->end_reached)
{
} else {
if (!ui_ctx->end_reached) {
handle_eip712_return_code(true);
}
else
{
if (ui_ctx->pos == UI_712_POS_REVIEW)
{
} else {
if (ui_ctx->pos == UI_712_POS_REVIEW) {
ux_flow_next();
ui_ctx->pos = UI_712_POS_END;
}
else
{
} else {
ux_flow_prev();
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
*/
void ui_712_review_struct(const void *const struct_ptr)
{
void ui_712_review_struct(const void *const struct_ptr) {
const char *struct_name;
uint8_t struct_name_length;
const char *const title = "Review struct";
if (ui_ctx == NULL)
{
if (ui_ctx == NULL) {
return;
}
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_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
*/
void ui_712_message_hash(void)
{
void ui_712_message_hash(void) {
const char *const title = "Message hash";
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] length its length
*/
static void ui_712_format_str(const uint8_t *const data, uint8_t length)
{
if (ui_712_field_shown())
{
ui_712_set_value((char*)data, length);
static void ui_712_format_str(const uint8_t *const data, uint8_t length) {
if (ui_712_field_shown()) {
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
* @return if the formatting was successful
*/
static bool ui_712_format_addr(const uint8_t *const data, uint8_t length)
{
if (length != ADDRESS_LENGTH)
{
static bool ui_712_format_addr(const uint8_t *const data, uint8_t length) {
if (length != ADDRESS_LENGTH) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
if (ui_712_field_shown())
{
getEthDisplayableAddress((uint8_t*)data,
if (ui_712_field_shown()) {
getEthDisplayableAddress((uint8_t *) data,
strings.tmp.tmp,
sizeof(strings.tmp.tmp),
&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
* @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 false_str = "false";
const char *str;
if (length != 1)
{
if (length != 1) {
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
return false;
}
str = *data ? true_str : false_str;
if (ui_712_field_shown())
{
if (ui_712_field_shown()) {
ui_712_set_value(str, strlen(str));
}
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] length its length
*/
static void ui_712_format_bytes(const uint8_t *const data, uint8_t length)
{
if (ui_712_field_shown())
{
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"0x%.*H",
length,
data);
static void ui_712_format_bytes(const uint8_t *const data, uint8_t length) {
if (ui_712_field_shown()) {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", length, data);
// +2 for the "0x"
// 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';
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,
uint8_t length,
const void *const field_ptr)
{
const void *const field_ptr) {
uint256_t value256;
uint128_t value128;
int32_t value32;
int16_t value16;
switch (get_struct_field_typesize(field_ptr) * 8)
{
switch (get_struct_field_typesize(field_ptr) * 8) {
case 256:
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));
}
break;
case 128:
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));
}
break;
case 64:
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));
}
break;
case 32:
value32 = 0;
for (int i = 0; i < length; ++i)
{
((uint8_t*)&value32)[length - 1 - i] = data[i];
for (int i = 0; i < length; ++i) {
((uint8_t *) &value32)[length - 1 - i] = data[i];
}
if (ui_712_field_shown())
{
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"%d",
value32);
if (ui_712_field_shown()) {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "%d", value32);
}
break;
case 16:
value16 = 0;
for (int i = 0; i < length; ++i)
{
((uint8_t*)&value16)[length - 1 - i] = data[i];
for (int i = 0; i < length; ++i) {
((uint8_t *) &value16)[length - 1 - i] = data[i];
}
if (ui_712_field_shown())
{
if (ui_712_field_shown()) {
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"%d",
value16); // expanded to 32 bits
value16); // expanded to 32 bits
}
break;
case 8:
if (ui_712_field_shown())
{
if (ui_712_field_shown()) {
snprintf(strings.tmp.tmp,
sizeof(strings.tmp.tmp),
"%d",
((int8_t*)data)[0]); // expanded to 32 bits
((int8_t *) data)[0]); // expanded to 32 bits
}
break;
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] 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;
convertUint256BE(data, length, &value256);
if (ui_712_field_shown())
{
if (ui_712_field_shown()) {
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] 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;
uint8_t key_len;
if (ui_ctx == NULL)
{
if (ui_ctx == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return false;
}
// 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;
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);
}
// Value
switch (struct_field_type(field_ptr))
{
switch (struct_field_type(field_ptr)) {
case TYPE_SOL_STRING:
ui_712_format_str(data, length);
break;
case TYPE_SOL_ADDRESS:
if (ui_712_format_addr(data, length) == false)
{
if (ui_712_format_addr(data, length) == false) {
return false;
}
break;
case TYPE_SOL_BOOL:
if (ui_712_format_bool(data, length) == false)
{
if (ui_712_format_bool(data, length) == false) {
return false;
}
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);
break;
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;
}
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
if (ui_712_field_shown())
{
if (ui_712_field_shown()) {
ui_712_redraw_generic_step();
}
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
* the option to approve or reject the signature
*/
void ui_712_end_sign(void)
{
if (ui_ctx == NULL)
{
void ui_712_end_sign(void) {
if (ui_ctx == NULL) {
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
return;
}
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();
}
}
@@ -502,17 +426,13 @@ void ui_712_end_sign(void)
/**
* Initializes the UI context structure in memory
*/
bool ui_712_init(void)
{
if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx)))
{
bool ui_712_init(void) {
if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx))) {
ui_ctx->shown = false;
ui_ctx->end_reached = false;
ui_ctx->pos = UI_712_POS_REVIEW;
ui_ctx->filtering_mode = EIP712_FILTERING_BASIC;
}
else
{
} else {
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
}
return ui_ctx != NULL;
@@ -521,8 +441,7 @@ bool ui_712_init(void)
/**
* Deinit function that simply unsets the struct pointer to NULL
*/
void ui_712_deinit(void)
{
void ui_712_deinit(void) {
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
* @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);
eip712_context_deinit();
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
* @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);
eip712_context_deinit();
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] name_provided if a substitution name has been provided
*/
void ui_712_flag_field(bool show, bool name_provided)
{
if (show)
{
void ui_712_flag_field(bool show, bool name_provided) {
if (show) {
ui_ctx->field_flags |= UI_712_FIELD_SHOWN;
}
if (name_provided)
{
if (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
*/
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;
}
@@ -586,16 +499,14 @@ void ui_712_set_filtering_mode(e_eip712_filtering_mode 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;
}
/**
* 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;
}
@@ -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
*/
void ui_712_queue_struct_to_review(void)
{
if (N_storage.verbose_eip712)
{
void ui_712_queue_struct_to_review(void) {
if (N_storage.verbose_eip712) {
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 "ux.h"
#define UI_712_FIELD_SHOWN (1 << 0)
#define UI_712_FIELD_NAME_PROVIDED (1 << 1)
#define UI_712_FIELD_SHOWN (1 << 0)
#define UI_712_FIELD_NAME_PROVIDED (1 << 1)
typedef enum
{
EIP712_FILTERING_BASIC,
EIP712_FILTERING_FULL
} e_eip712_filtering_mode;
typedef enum { EIP712_FILTERING_BASIC, EIP712_FILTERING_FULL } e_eip712_filtering_mode;
typedef enum
{
UI_712_POS_REVIEW,
UI_712_POS_END
} e_ui_position;
typedef enum { UI_712_POS_REVIEW, UI_712_POS_END } e_ui_position;
typedef struct
{
typedef struct {
bool shown;
bool end_reached;
e_ui_position pos;
uint8_t filtering_mode;
uint8_t field_flags;
uint8_t structs_to_review;
} t_ui_context;
} t_ui_context;
bool ui_712_init(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);
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_message_hash(void);
void ui_712_redraw_generic_step(void);
void ui_712_flag_field(bool show, bool name_provided);
void ui_712_field_flags_reset(void);
void ui_712_finalize_field(void);
void ui_712_set_filtering_mode(e_eip712_filtering_mode mode);
void ui_712_message_hash(void);
void ui_712_redraw_generic_step(void);
void ui_712_flag_field(bool show, bool name_provided);
void ui_712_field_flags_reset(void);
void ui_712_finalize_field(void);
void ui_712_set_filtering_mode(e_eip712_filtering_mode mode);
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};
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 hash[INT256_LENGTH];
uint8_t signature[100];
cx_ecfp_private_key_t privateKey;
uint32_t tx = 0;
(void)e;
(void) e;
io_seproxyhal_io_heartbeat();
cx_keccak_init(&global_sha3, 256);
cx_hash((cx_hash_t *) &global_sha3,
@@ -57,12 +56,10 @@ unsigned int ui_712_approve_cb(const bagl_element_t *e)
&info);
explicit_bzero(&privateKey, sizeof(privateKey));
G_io_apdu_buffer[0] = 27;
if (info & CX_ECCINFO_PARITY_ODD)
{
if (info & CX_ECCINFO_PARITY_ODD) {
G_io_apdu_buffer[0]++;
}
if (info & CX_ECCINFO_xGTn)
{
if (info & CX_ECCINFO_xGTn) {
G_io_apdu_buffer[0] += 2;
}
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
}
unsigned int ui_712_reject_cb(const bagl_element_t *e)
{
(void)e;
unsigned int ui_712_reject_cb(const bagl_element_t *e) {
(void) e;
reset_app_context();
G_io_apdu_buffer[0] = 0x69;
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_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,
unsigned int *flags,
unsigned int *tx) {
(void)tx;
(void)p2;
(void) tx;
(void) p2;
if (p1 != 00) {
THROW(0x6B00);
}
@@ -25,9 +25,7 @@ void handleSignEIP712Message_v0(uint8_t p1,
if ((workBuffer == NULL) || (dataLength < (KECCAK256_HASH_BYTESIZE * 2))) {
THROW(0x6a80);
}
memmove(tmpCtx.messageSigningContext712.domainHash,
workBuffer,
KECCAK256_HASH_BYTESIZE);
memmove(tmpCtx.messageSigningContext712.domainHash, workBuffer, KECCAK256_HASH_BYTESIZE);
memmove(tmpCtx.messageSigningContext712.messageHash,
workBuffer + KECCAK256_HASH_BYTESIZE,
KECCAK256_HASH_BYTESIZE);