Skip to content

Commit 69a9427

Browse files
Migrated EIP-712 feature to the new memory allocator
1 parent 87cf268 commit 69a9427

21 files changed

Lines changed: 734 additions & 1076 deletions

src/mem_utils.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
* Format an unsigned number up to 32-bit into memory into an ASCII string.
99
*
1010
* @param[in] value Value to write in memory
11-
* @param[out] length number of characters written to memory
12-
*
1311
* @return pointer to memory area or \ref NULL if the allocation failed
1412
*/
15-
char *mem_legacy_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
13+
const char *mem_alloc_and_format_uint(uint32_t value) {
1614
char *mem_ptr;
1715
uint32_t value_copy;
1816
uint8_t size;
@@ -24,12 +22,8 @@ char *mem_legacy_alloc_and_format_uint(uint32_t value, uint8_t *const length) {
2422
size += 1;
2523
}
2624
// +1 for the null character
27-
if ((mem_ptr = mem_legacy_alloc(sizeof(char) * (size + 1)))) {
25+
if ((mem_ptr = app_mem_alloc(sizeof(char) * (size + 1)))) {
2826
snprintf(mem_ptr, (size + 1), "%u", value);
29-
mem_legacy_dealloc(sizeof(char)); // to skip the null character
30-
if (length != NULL) {
31-
*length = size;
32-
}
3327
}
3428
return mem_ptr;
3529
}
@@ -63,3 +57,13 @@ void *mem_legacy_alloc_and_align(size_t size, size_t alignment) {
6357
mem_legacy_align(alignment);
6458
return mem_legacy_alloc(size);
6559
}
60+
61+
char *app_mem_strdup(const char *src) {
62+
char *dst;
63+
size_t length = strlen(src) + 1;
64+
65+
if ((dst = app_mem_alloc(length)) != NULL) {
66+
memcpy(dst, src, length);
67+
}
68+
return dst;
69+
}

src/mem_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#define MEM_ALLOC_AND_ALIGN_TYPE(type) mem_legacy_alloc_and_align(sizeof(type), __alignof__(type))
66

7-
char *mem_legacy_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars);
7+
const char *mem_alloc_and_format_uint(uint32_t value);
88
uint8_t mem_legacy_align(size_t alignment);
99
void *mem_legacy_alloc_and_align(size_t size, size_t alignment);
10+
char *app_mem_strdup(const char *s);

src_features/signMessageEIP712/commands_712.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,8 @@ uint16_t handle_eip712_filtering(uint8_t p1,
225225
ret = false;
226226
}
227227
if ((p2 > P2_FILT_MESSAGE_INFO) && ret) {
228-
if (ui_712_push_new_filter_path(path_crc)) {
229-
if (!ui_712_filters_counter_incr()) {
230-
ret = false;
231-
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
232-
}
228+
if (!ui_712_push_new_filter_path(path_crc)) {
229+
ret = false;
233230
}
234231
}
235232
if (reply_apdu) {

src_features/signMessageEIP712/context_712.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ s_eip712_context *eip712_context = NULL;
1919
* @return a boolean indicating if the initialization was successful or not
2020
*/
2121
bool eip712_context_init(void) {
22-
// switch to legacy allocator
23-
mem_legacy_init();
22+
if (eip712_context != NULL) {
23+
eip712_context_deinit();
24+
return false;
25+
}
2426

2527
// init global variables
26-
if ((eip712_context = MEM_ALLOC_AND_ALIGN_TYPE(*eip712_context)) == NULL) {
28+
if ((eip712_context = app_mem_alloc(sizeof(*eip712_context))) == NULL) {
2729
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
2830
return false;
2931
}
32+
explicit_bzero(eip712_context, sizeof(*eip712_context));
3033

3134
if (sol_typenames_init() == false) {
3235
return false;
@@ -44,14 +47,10 @@ bool eip712_context_init(void) {
4447
return false;
4548
}
4649

47-
if (typed_data_init() == false) // this needs to be initialized last !
48-
{
50+
if (typed_data_init() == false) {
4951
return false;
5052
}
5153

52-
// Since they are optional, they might not be provided by the JSON data
53-
explicit_bzero(eip712_context->contract_addr, sizeof(eip712_context->contract_addr));
54-
eip712_context->chain_id = 0;
5554
eip712_context->go_home_on_failure = true;
5655

5756
struct_state = NOT_INITIALIZED;
@@ -67,8 +66,6 @@ void eip712_context_deinit(void) {
6766
path_deinit();
6867
field_hash_deinit();
6968
ui_712_deinit();
70-
// switch back to SDK allocator
71-
app_mem_init();
7269
eip712_context = NULL;
7370
reset_app_context();
7471
}

src_features/signMessageEIP712/encode_field.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static void *field_encode(const uint8_t *const value,
2525
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
2626
return NULL;
2727
}
28-
if ((padded_value = mem_legacy_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) {
28+
if ((padded_value = app_mem_alloc(EIP_712_ENCODED_FIELD_LENGTH)) != NULL) {
2929
switch (ptype) {
3030
case MSB:
3131
memset(padded_value, pval, EIP_712_ENCODED_FIELD_LENGTH - length);

src_features/signMessageEIP712/field_hash.c

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@ static s_field_hashing *fh = NULL;
2020
* @return whether the initialization was successful or not
2121
*/
2222
bool field_hash_init(void) {
23-
if (fh == NULL) {
24-
if ((fh = MEM_ALLOC_AND_ALIGN_TYPE(*fh)) == NULL) {
25-
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
26-
return false;
27-
}
28-
fh->state = FHS_IDLE;
23+
if (fh != NULL) {
24+
field_hash_deinit();
25+
return false;
26+
}
27+
28+
if ((fh = app_mem_alloc(sizeof(*fh))) == NULL) {
29+
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
30+
return false;
2931
}
32+
explicit_bzero(fh, sizeof(*fh));
33+
fh->state = FHS_IDLE;
3034
return true;
3135
}
3236

@@ -45,18 +49,16 @@ void field_hash_deinit(void) {
4549
* @param[in,out] data_length the value length
4650
* @return the data pointer
4751
*/
48-
static const uint8_t *field_hash_prepare(const void *const field_ptr,
52+
static const uint8_t *field_hash_prepare(const s_struct_712_field *field_ptr,
4953
const uint8_t *data,
5054
uint8_t *data_length) {
51-
e_type field_type;
5255
cx_err_t error = CX_INTERNAL_ERROR;
5356

54-
field_type = struct_field_type(field_ptr);
5557
fh->remaining_size = __builtin_bswap16(*(uint16_t *) &data[0]); // network byte order
5658
data += sizeof(uint16_t);
5759
*data_length -= sizeof(uint16_t);
5860
fh->state = FHS_WAITING_FOR_MORE;
59-
if (IS_DYN(field_type)) {
61+
if (IS_DYN(field_ptr->type)) {
6062
CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256));
6163
}
6264
return data;
@@ -74,16 +76,14 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr,
7476
* @param[in] data_length the value length
7577
* @return pointer to the encoded value
7678
*/
77-
static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
79+
static const uint8_t *field_hash_finalize_static(const s_struct_712_field *field_ptr,
7880
const uint8_t *const data,
7981
uint8_t data_length) {
8082
uint8_t *value = NULL;
81-
e_type field_type;
8283

83-
field_type = struct_field_type(field_ptr);
84-
switch (field_type) {
84+
switch (field_ptr->type) {
8585
case TYPE_SOL_INT:
86-
value = encode_int(data, data_length, get_struct_field_typesize(field_ptr));
86+
value = encode_int(data, data_length, field_ptr->type_size);
8787
break;
8888
case TYPE_SOL_UINT:
8989
value = encode_uint(data, data_length);
@@ -116,7 +116,7 @@ static uint8_t *field_hash_finalize_dynamic(void) {
116116
uint8_t *value;
117117
cx_err_t error = CX_INTERNAL_ERROR;
118118

119-
if ((value = mem_legacy_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) {
119+
if ((value = app_mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) {
120120
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
121121
return NULL;
122122
}
@@ -138,7 +138,7 @@ static uint8_t *field_hash_finalize_dynamic(void) {
138138
* @param[in] field_type the struct field's type
139139
* @param[in] hash the field hash
140140
*/
141-
static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash) {
141+
static void field_hash_feed_parent(e_type field_type, const uint8_t *hash) {
142142
uint8_t len;
143143

144144
if (IS_DYN(field_type)) {
@@ -149,11 +149,11 @@ static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash)
149149

150150
// last thing in mem is the hash of the previous field
151151
// and just before it is the current hash context
152-
cx_sha3_t *hash_ctx = (cx_sha3_t *) (hash - sizeof(cx_sha3_t));
152+
cx_sha3_t *hash_ctx = get_last_hash_ctx();
153153
// continue the progressive hash on it
154154
hash_nbytes(hash, len, (cx_hash_t *) hash_ctx);
155155
// deallocate it
156-
mem_legacy_dealloc(len);
156+
app_mem_free((void *) hash);
157157
}
158158

159159
/**
@@ -166,17 +166,16 @@ static void field_hash_feed_parent(e_type field_type, const uint8_t *const hash)
166166
* @param[in] data_length the value length
167167
* @return whether an error occurred or not
168168
*/
169-
static bool field_hash_domain_special_fields(const void *const field_ptr,
169+
static bool field_hash_domain_special_fields(const s_struct_712_field *field_ptr,
170170
const uint8_t *const data,
171171
uint8_t data_length) {
172172
const char *key;
173-
uint8_t keylen;
174173
const char *ethermint_vc = "cosmos";
175174

176-
key = get_struct_field_keyname(field_ptr, &keylen);
175+
key = field_ptr->key_name;
177176
// copy contract address into context
178-
if (strncmp(key, "verifyingContract", keylen) == 0) {
179-
switch (struct_field_type(field_ptr)) {
177+
if (strncmp(key, "verifyingContract", strlen(key)) == 0) {
178+
switch (field_ptr->type) {
180179
case TYPE_SOL_ADDRESS:
181180
if (data_length > sizeof(eip712_context->contract_addr)) {
182181
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
@@ -195,14 +194,13 @@ static bool field_hash_domain_special_fields(const void *const field_ptr,
195194
break;
196195
default:
197196
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
198-
PRINTF("Error: unexpected type for verifyingContract (%u)!\n",
199-
struct_field_type(field_ptr));
197+
PRINTF("Error: unexpected type for verifyingContract (%u)!\n", field_ptr->type);
200198
return false;
201199
}
202200
memcpy(eip712_context->contract_addr, data, data_length);
203201
explicit_bzero(&eip712_context->contract_addr[data_length],
204202
sizeof(eip712_context->contract_addr) - data_length);
205-
} else if (strncmp(key, "chainId", keylen) == 0) {
203+
} else if (strncmp(key, "chainId", strlen(key)) == 0) {
206204
eip712_context->chain_id = u64_from_BE(data, data_length);
207205
}
208206
return true;
@@ -216,14 +214,12 @@ static bool field_hash_domain_special_fields(const void *const field_ptr,
216214
* @param[in] data_length the value length
217215
* @return whether an error occurred or not
218216
*/
219-
static bool field_hash_finalize(const void *const field_ptr,
217+
static bool field_hash_finalize(const s_struct_712_field *field_ptr,
220218
const uint8_t *const data,
221219
uint8_t data_length) {
222220
const uint8_t *value = NULL;
223-
e_type field_type;
224221

225-
field_type = struct_field_type(field_ptr);
226-
if (!IS_DYN(field_type)) {
222+
if (!IS_DYN(field_ptr->type)) {
227223
if ((value = field_hash_finalize_static(field_ptr, data, data_length)) == NULL) {
228224
return false;
229225
}
@@ -233,7 +229,7 @@ static bool field_hash_finalize(const void *const field_ptr,
233229
}
234230
}
235231

236-
field_hash_feed_parent(field_type, value);
232+
field_hash_feed_parent(field_ptr->type, value);
237233

238234
if (path_get_root_type() == ROOT_DOMAIN) {
239235
if (field_hash_domain_special_fields(field_ptr, data, data_length) == false) {
@@ -255,16 +251,14 @@ static bool field_hash_finalize(const void *const field_ptr,
255251
* @return whether the data hashing was successful or not
256252
*/
257253
bool field_hash(const uint8_t *data, uint8_t data_length, bool partial) {
258-
const void *field_ptr;
259-
e_type field_type;
254+
const s_struct_712_field *field_ptr;
260255
bool first = fh->state == FHS_IDLE;
261256

262257
if ((fh == NULL) || ((field_ptr = path_get_field()) == NULL)) {
263258
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
264259
return false;
265260
}
266261

267-
field_type = struct_field_type(field_ptr);
268262
// first packet for this frame
269263
if (first) {
270264
if (!ui_712_show_raw_key(field_ptr)) {
@@ -283,7 +277,7 @@ bool field_hash(const uint8_t *data, uint8_t data_length, bool partial) {
283277
}
284278
fh->remaining_size -= data_length;
285279
// if a dynamic type -> continue progressive hash
286-
if (IS_DYN(field_type)) {
280+
if (IS_DYN(field_ptr->type)) {
287281
hash_nbytes(data, data_length, (cx_hash_t *) &global_sha3);
288282
}
289283
if (!ui_712_feed_to_display(field_ptr, data, data_length, first, fh->remaining_size == 0)) {
@@ -299,7 +293,7 @@ bool field_hash(const uint8_t *data, uint8_t data_length, bool partial) {
299293
return false;
300294
}
301295
} else {
302-
if (!partial || !IS_DYN(field_type)) // only makes sense if marked as partial
296+
if (!partial || !IS_DYN(field_ptr->type)) // only makes sense if marked as partial
303297
{
304298
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
305299
return false;

0 commit comments

Comments
 (0)