Skip to content

Commit a23c6bc

Browse files
Merge pull request #608 from LedgerHQ/fix/apa/eip712_filters_counter
EIP-712 filters counter fix + reactivation
2 parents 32a103f + 223eff0 commit a23c6bc

File tree

9 files changed

+88
-26
lines changed

9 files changed

+88
-26
lines changed

src/mem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <stdint.h>
1212
#include "mem.h"
1313

14-
#define SIZE_MEM_BUFFER 8192
14+
#define SIZE_MEM_BUFFER 10240
1515

1616
static uint8_t mem_buffer[SIZE_MEM_BUFFER];
1717
static size_t mem_idx;

src_bagl/ui_flow_signMessage712.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ static void dummy_cb(void) {
1212
if (ui_pos == UI_712_POS_REVIEW) {
1313
ux_flow_next();
1414
ui_pos = UI_712_POS_END;
15-
} else // UI_712_POS_END
16-
{
17-
ux_flow_prev();
18-
ui_pos = UI_712_POS_REVIEW;
15+
} else {
16+
// Keep user at the end of the flow
17+
ux_flow_next();
1918
}
2019
break;
2120
case EIP712_FIELD_INCOMING:

src_features/signMessageEIP712/commands_712.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ bool handle_eip712_filtering(const uint8_t *const apdu_buf) {
195195
apdu_response_code = APDU_RESPONSE_INVALID_P1_P2;
196196
ret = false;
197197
}
198+
if ((apdu_buf[OFFSET_P2] > P2_FILT_MESSAGE_INFO) && ret) {
199+
if (ui_712_push_new_filter_path()) {
200+
if (!ui_712_filters_counter_incr()) {
201+
ret = false;
202+
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
203+
}
204+
}
205+
}
198206
if (reply_apdu) {
199207
handle_eip712_return_code(ret);
200208
}
@@ -221,6 +229,10 @@ bool handle_eip712_sign(const uint8_t *const apdu_buf) {
221229
sizeof(tmpCtx.messageSigningContext712.messageHash)) ||
222230
(path_get_field() != NULL)) {
223231
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
232+
} else if ((ui_712_get_filtering_mode() == EIP712_FILTERING_FULL) &&
233+
(ui_712_remaining_filters() != 0)) {
234+
PRINTF("%d EIP712 filters are missing\n", ui_712_remaining_filters());
235+
apdu_response_code = APDU_RESPONSE_REF_DATA_NOT_FOUND;
224236
} else if (parseBip32(&apdu_buf[OFFSET_CDATA], &length, &tmpCtx.messageSigningContext.bip32) !=
225237
NULL) {
226238
if (!N_storage.verbose_eip712 && (ui_712_get_filtering_mode() == EIP712_FILTERING_BASIC)) {

src_features/signMessageEIP712/filtering.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "typed_data.h"
1212
#include "path.h"
1313
#include "ui_logic.h"
14+
#include "filtering.h"
1415

1516
#define FILT_MAGIC_MESSAGE_INFO 183
1617
#define FILT_MAGIC_AMOUNT_JOIN_TOKEN 11
@@ -188,6 +189,10 @@ bool filtering_message_info(const uint8_t *payload, uint8_t length) {
188189
return false;
189190
}
190191
filters_count = payload[offset++];
192+
if (filters_count > MAX_FILTERS) {
193+
PRINTF("%u filters planned but can only store up to %u.\n", filters_count, MAX_FILTERS);
194+
return false;
195+
}
191196
if ((offset + sizeof(sig_len)) > length) {
192197
return false;
193198
}

src_features/signMessageEIP712/filtering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <stdbool.h>
77
#include <stdint.h>
88

9+
#define MAX_FILTERS 50
10+
911
bool filtering_message_info(const uint8_t *payload, uint8_t length);
1012
bool filtering_date_time(const uint8_t *payload, uint8_t length);
1113
bool filtering_amount_join_token(const uint8_t *payload, uint8_t length);

src_features/signMessageEIP712/path.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "type_hash.h"
1010
#include "shared_context.h"
1111
#include "mem_utils.h"
12-
#include "ui_logic.h"
1312
#include "apdu_constants.h" // APDU response codes
1413
#include "typed_data.h"
1514

@@ -541,7 +540,6 @@ static bool path_advance_in_struct(void) {
541540
}
542541
if (path_struct->depth_count > 0) {
543542
*depth += 1;
544-
ui_712_notify_filter_change();
545543
end_reached = (*depth == fields_count);
546544
}
547545
if (end_reached) {
@@ -634,6 +632,35 @@ uint8_t path_get_depth_count(void) {
634632
return path_struct->depth_count;
635633
}
636634

635+
/**
636+
* Generate a unique checksum out of the current path
637+
*
638+
* Goes over the fields of the \ref path_struct with a few exceptions : we skip the root_type since
639+
* we already go over root_struct, and in array_depths we only go over path_index since it would
640+
* otherwise generate a different CRC for different fields which are targeted by the same filtering
641+
* path.
642+
*
643+
* @return CRC-32 checksum
644+
*/
645+
uint32_t get_path_crc(void) {
646+
uint32_t value = CX_CRC32_INIT;
647+
648+
value = cx_crc32_update(value, &path_struct->root_struct, sizeof(path_struct->root_struct));
649+
value = cx_crc32_update(value, &path_struct->depth_count, sizeof(path_struct->depth_count));
650+
value = cx_crc32_update(value,
651+
path_struct->depths,
652+
sizeof(path_struct->depths[0]) * path_struct->depth_count);
653+
value = cx_crc32_update(value,
654+
&path_struct->array_depth_count,
655+
sizeof(path_struct->array_depth_count));
656+
for (int i = 0; i < path_struct->array_depth_count; ++i) {
657+
value = cx_crc32_update(value,
658+
&path_struct->array_depths[i].path_index,
659+
sizeof(path_struct->array_depths[i].path_index));
660+
}
661+
return value;
662+
}
663+
637664
/**
638665
* Initialize the path context with its indexes in memory and sets it with a depth of 0.
639666
*

src_features/signMessageEIP712/path.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const void *path_get_root(void);
3737
const void *path_get_nth_field(uint8_t n);
3838
const void *path_get_nth_field_to_last(uint8_t n);
3939
uint8_t path_get_depth_count(void);
40+
uint32_t get_path_crc(void);
4041

4142
#endif // HAVE_EIP712_FULL_SUPPORT
4243

src_features/signMessageEIP712/ui_logic.c

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "commands_712.h"
1919
#include "common_ui.h"
2020
#include "uint_common.h"
21+
#include "filtering.h"
2122

2223
#define AMOUNT_JOIN_FLAG_TOKEN (1 << 0)
2324
#define AMOUNT_JOIN_FLAG_VALUE (1 << 1)
@@ -56,6 +57,8 @@ typedef struct {
5657
uint8_t field_flags;
5758
uint8_t structs_to_review;
5859
s_amount_context amount;
60+
uint8_t filters_received;
61+
uint32_t filters_crc[MAX_FILTERS];
5962
#ifdef SCREEN_SIZE_WALLET
6063
char ui_pairs_buffer[(SHARED_CTX_FIELD_1_SIZE + SHARED_CTX_FIELD_2_SIZE) * 2];
6164
#endif
@@ -617,12 +620,8 @@ void ui_712_end_sign(void) {
617620
*/
618621
bool ui_712_init(void) {
619622
if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx))) {
620-
ui_ctx->shown = false;
621-
ui_ctx->end_reached = false;
623+
explicit_bzero(ui_ctx, sizeof(*ui_ctx));
622624
ui_ctx->filtering_mode = EIP712_FILTERING_BASIC;
623-
explicit_bzero(&ui_ctx->amount, sizeof(ui_ctx->amount));
624-
explicit_bzero(strings.tmp.tmp, sizeof(strings.tmp.tmp));
625-
explicit_bzero(strings.tmp.tmp2, sizeof(strings.tmp.tmp2));
626625
} else {
627626
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
628627
}
@@ -717,7 +716,7 @@ void ui_712_set_filters_count(uint8_t count) {
717716
* @return number of filters
718717
*/
719718
uint8_t ui_712_remaining_filters(void) {
720-
return ui_ctx->filters_to_process;
719+
return ui_ctx->filters_to_process - ui_ctx->filters_received;
721720
}
722721

723722
/**
@@ -739,20 +738,16 @@ void ui_712_queue_struct_to_review(void) {
739738
}
740739

741740
/**
742-
* Notify of a filter change from a path advance
741+
* Increment the filters counter
743742
*
744-
* This function figures out by itself if there is anything to do
745-
*/
746-
void ui_712_notify_filter_change(void) {
747-
if (path_get_root_type() == ROOT_MESSAGE) {
748-
if (ui_ctx->filtering_mode == EIP712_FILTERING_FULL) {
749-
if (ui_ctx->filters_to_process > 0) {
750-
if (ui_ctx->field_flags & UI_712_FIELD_SHOWN) {
751-
ui_ctx->filters_to_process -= 1;
752-
}
753-
}
754-
}
743+
* @return if the counter could be incremented
744+
*/
745+
bool ui_712_filters_counter_incr(void) {
746+
if (ui_ctx->filters_received > ui_ctx->filters_to_process) {
747+
return false;
755748
}
749+
ui_ctx->filters_received += 1;
750+
return true;
756751
}
757752

758753
void ui_712_token_join_prepare_addr_check(uint8_t index) {
@@ -789,6 +784,26 @@ bool ui_712_show_raw_key(const void *field_ptr) {
789784
return true;
790785
}
791786

787+
/**
788+
* Push a new filter path
789+
*
790+
* @return if the path was pushed or not (in case it was already present)
791+
*/
792+
bool ui_712_push_new_filter_path(void) {
793+
uint32_t path_crc = get_path_crc();
794+
795+
// check if already present
796+
for (int i = 0; i < ui_ctx->filters_received; ++i) {
797+
if (ui_ctx->filters_crc[i] == path_crc) {
798+
PRINTF("EIP-712 path CRC (%x) already found at index %u!\n", path_crc, i);
799+
return false;
800+
}
801+
}
802+
PRINTF("Pushing new EIP-712 path CRC (%x) at index %u\n", path_crc, ui_ctx->filters_received);
803+
ui_ctx->filters_crc[ui_ctx->filters_received] = path_crc;
804+
return true;
805+
}
806+
792807
#ifdef SCREEN_SIZE_WALLET
793808
/*
794809
* Get UI pairs buffer

src_features/signMessageEIP712/ui_logic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ e_eip712_filtering_mode ui_712_get_filtering_mode(void);
3838
void ui_712_set_filters_count(uint8_t count);
3939
uint8_t ui_712_remaining_filters(void);
4040
void ui_712_queue_struct_to_review(void);
41-
void ui_712_notify_filter_change(void);
41+
bool ui_712_filters_counter_incr(void);
4242
void ui_712_token_join_prepare_addr_check(uint8_t index);
4343
void ui_712_token_join_prepare_amount(uint8_t index, const char *name, uint8_t name_length);
4444
void amount_join_set_token_received(void);
4545
bool ui_712_show_raw_key(const void *field_ptr);
46+
bool ui_712_push_new_filter_path(void);
4647
#ifdef SCREEN_SIZE_WALLET
4748
char *get_ui_pairs_buffer(size_t *size);
4849
#endif

0 commit comments

Comments
 (0)