Skip to content

Commit e6c8d85

Browse files
B2CA-2188: Multisig UI (#898)
* Fix crash with mem_free * Add flag 'CHALLENGE_NO_CHECK' to bypass the challenge check * Cleanup EIP712 calldata parameters * Ensure UI alloacted tag/value buffers will be freeed * Add Batch TX handling * Support Batch transactions in EIP712 * Add GCS batch test * Add eip712 batch test * Add new snapshots
1 parent 3d4f4a4 commit e6c8d85

File tree

222 files changed

+1312
-48
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

222 files changed

+1312
-48
lines changed

ledger_app.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ dbg_use_test_keys = "DEBUG=1 CAL_TEST_KEY=1 TRUSTED_NAME_TEST_KEY=1 SET_PLUGIN_T
1111
cal_bypass = "BYPASS_SIGNATURES=1"
1212
dbg_cal_bypass = "DEBUG=1 BYPASS_SIGNATURES=1"
1313
memory_profiling = "DEBUG=1 EIP7702_TEST_WHITELIST=1 MEMORY_PROFILING=1"
14+
dbg_no_checks = "DEBUG=1 BYPASS_SIGNATURES=1 CHALLENGE_NO_CHECK=1"
15+
dbg_no_checks_profiling = "DEBUG=1 BYPASS_SIGNATURES=1 CHALLENGE_NO_CHECK=1 MEMORY_PROFILING=1"
1416

1517
[tests]
1618
unit_directory = "./tests/unit"

makefile_conf/features.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ ifneq ($(BYPASS_SIGNATURES),0)
66
DEFINES += HAVE_BYPASS_SIGNATURES
77
endif
88

9+
# Bypass the challenge verification
10+
CHALLENGE_NO_CHECK ?= 0
11+
ifneq ($(CHALLENGE_NO_CHECK),0)
12+
DEFINES += HAVE_CHALLENGE_NO_CHECK
13+
endif
14+
915
# Enable the SET_PLUGIN test key
1016
SET_PLUGIN_TEST_KEY ?= 0
1117
ifneq ($(SET_PLUGIN_TEST_KEY),0)

src/features/generic_tx_parser/gtp_field.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef enum {
2828
PARAM_TYPE_TRUSTED_NAME,
2929
PARAM_TYPE_CALLDATA,
3030
PARAM_TYPE_TOKEN,
31+
PARAM_TYPE_INTENT,
3132
} e_param_type;
3233

3334
typedef struct {

src/features/generic_tx_parser/gtp_field_table.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "list.h"
66
#include "shared_context.h" // appState
77
#include "ui_logic.h"
8+
#include "tx_ctx.h"
89

910
typedef struct {
1011
s_flist_node _list;
@@ -41,7 +42,13 @@ bool add_to_field_table(e_param_type type, const char *key, const char *value) {
4142
PRINTF("Error: NULL key/value!\n");
4243
return false;
4344
}
45+
PRINTF(">>> \"%s\": \"%s\"\n", key, value);
4446
if (appState == APP_STATE_SIGNING_EIP712) {
47+
if ((type == PARAM_TYPE_INTENT) && (txContext.current_batch_size > 1)) {
48+
// Special handling for intent in EIP712 mode
49+
ui_712_set_intent();
50+
PRINTF(">>> [Intent] Start\n");
51+
}
4552
ui_712_set_title(key, strlen(key));
4653
ui_712_set_value(value, strlen(value));
4754
return true;
@@ -61,7 +68,17 @@ bool add_to_field_table(e_param_type type, const char *key, const char *value) {
6168
app_mem_free(node);
6269
return false;
6370
}
64-
PRINTF(">>> \"%s\": \"%s\"\n", key, value);
71+
if (type == PARAM_TYPE_INTENT) {
72+
// Special handling for intent
73+
node->field.start_intent = true;
74+
type = PARAM_TYPE_RAW; // store as raw
75+
PRINTF(">>> [Intent] Start\n");
76+
} else {
77+
node->field.end_intent = validate_instruction_hash();
78+
if (node->field.end_intent) {
79+
PRINTF(">>> [Intent] End\n");
80+
}
81+
}
6582

6683
node->field.type = type;
6784
memcpy(node->field.key, key, key_len);
@@ -72,7 +89,13 @@ bool add_to_field_table(e_param_type type, const char *key, const char *value) {
7289
}
7390

7491
bool set_intent_field(const char *value) {
75-
return add_to_field_table(0, "Transaction type", value);
92+
e_param_type type = PARAM_TYPE_INTENT;
93+
94+
if (txContext.current_batch_size == 1) {
95+
// Only one transaction in the batch, no need to mark as intent
96+
type = PARAM_TYPE_RAW;
97+
}
98+
return add_to_field_table(type, "Transaction type", value);
7699
}
77100

78101
size_t field_table_size(void) {

src/features/generic_tx_parser/gtp_field_table.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ typedef struct {
88
e_param_type type;
99
char *key;
1010
char *value;
11+
bool start_intent; // This pair starts a new transaction in a batch
12+
bool end_intent; // This pair ends a transaction in a batch
1113
} s_field_table_entry;
1214

1315
bool field_table_init(void);

src/features/generic_tx_parser/gtp_param_calldata.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,11 @@ bool format_param_calldata(const s_param_calldata *param, const char *name) {
252252
&selectors,
253253
&amounts,
254254
&spenders))) {
255+
// Set batch size and number of transactions
256+
if (calldatas.size > 1) {
257+
txContext.batch_nb_tx += calldatas.size;
258+
}
259+
txContext.current_batch_size = calldatas.size;
255260
for (int i = 0; i < calldatas.size; ++i) {
256261
if (calldatas.value[i].length > 0) {
257262
if (!process_nested_calldata(param,

src/features/generic_tx_parser/tx_ctx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ bool find_matching_tx_ctx(const uint8_t *contract_addr,
114114
return false;
115115
}
116116

117-
void tx_ctx_cleanup(void) {
117+
static void tx_ctx_cleanup(void) {
118118
flist_clear((s_flist_node **) &g_tx_ctx_list, (f_list_node_del) &delete_tx_ctx);
119119
g_tx_ctx_current = NULL;
120120
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#pragma once
22

33
#include <stdint.h>
4+
#include <stdbool.h>
45

56
void roll_challenge(void);
67
uint32_t get_challenge(void);
8+
bool check_challenge(uint32_t received_challenge);
79
uint16_t handle_get_challenge(unsigned int *tx);

src/features/getChallenge/cmd_get_challenge.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ static uint32_t challenge;
99
* Generate a new challenge from the Random Number Generator
1010
*/
1111
void roll_challenge(void) {
12+
#ifdef HAVE_CHALLENGE_NO_CHECK
13+
challenge = 0x12345678;
14+
#else
1215
challenge = cx_rng_u32();
16+
#endif
1317
}
1418

1519
/**
@@ -21,6 +25,22 @@ uint32_t get_challenge(void) {
2125
return challenge;
2226
}
2327

28+
/**
29+
* Check the challenge
30+
*
31+
* @return whether the received challenge matches the current one
32+
*/
33+
bool check_challenge(uint32_t received_challenge) {
34+
UNUSED(received_challenge);
35+
#ifndef HAVE_CHALLENGE_NO_CHECK
36+
if (received_challenge != challenge) {
37+
PRINTF("Error: challenge mismatch!\n");
38+
return false;
39+
}
40+
#endif
41+
return true;
42+
}
43+
2444
/**
2545
* Send back the current challenge
2646
*/

src/features/provide_proxy_info/proxy_info.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ bool handle_proxy_info_struct(const s_tlv_data *data, s_proxy_info_ctx *context)
163163

164164
bool verify_proxy_info_struct(const s_proxy_info_ctx *context) {
165165
uint8_t hash[INT256_LENGTH];
166-
uint32_t challenge;
167166

168167
if (cx_hash_no_throw((cx_hash_t *) &context->struct_hash,
169168
CX_LAST,
@@ -178,12 +177,10 @@ bool verify_proxy_info_struct(const s_proxy_info_ctx *context) {
178177
PRINTF("Error: unknown struct type (%u)!\n", context->struct_type);
179178
return false;
180179
}
181-
challenge = get_challenge();
182-
roll_challenge();
183-
if (context->challenge != challenge) {
184-
PRINTF("Error: challenge mismatch!\n");
180+
if (check_challenge(context->challenge) == false) {
185181
return false;
186182
}
183+
roll_challenge();
187184
if (context->delegation_type != DELEGATION_TYPE_PROXY) {
188185
PRINTF("Error: unsupported delegation type (%u)!\n", context->delegation_type);
189186
return false;

0 commit comments

Comments
 (0)