Skip to content

Commit daa8393

Browse files
Merge pull request #664 from Cypherock/develop
Develop
2 parents c4b7407 + aa77d2a commit daa8393

21 files changed

+895
-24
lines changed

apps/btc_family/btc_pub_key.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,16 @@ static size_t btc_get_address(const uint8_t *seed,
221221
case NON_SEGWIT:
222222
hdnode_get_address(&node, g_btc_app->p2pkh_addr_ver, addr, 35);
223223
break;
224-
// TODO: add support for taproot and segwit
224+
case PURPOSE_SEGWIT:
225+
ecdsa_get_address_segwit_p2sh(node.public_key,
226+
g_btc_app->p2sh_addr_ver,
227+
node.curve->hasher_pubkey,
228+
node.curve->hasher_base58,
229+
addr,
230+
36);
231+
break;
232+
233+
// TODO: add support for taproot
225234
default:
226235
break;
227236
}

apps/btc_family/btc_script.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,25 @@ bool btc_check_script_address(const uint8_t *script,
239239

240240
uint8_t digest[HASHER_DIGEST_LENGTH] = {0};
241241
btc_script_type_e type = btc_get_script_type(script, script_len);
242-
if (SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type) {
243-
// allow only p2pkh and p2wpkh for change output
242+
if (SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type &&
243+
SCRIPT_TYPE_P2SH != type) {
244+
// allow only p2pkh and p2wpkh and p2sh-p2wpkh for change output
244245
return false;
245246
}
246247
uint8_t offset = (SCRIPT_TYPE_P2PKH == type) ? 3 : 2;
247248

248249
hasher_Raw(HASHER_SHA2_RIPEMD, public_key, BTC_SHORT_PUB_KEY_SIZE, digest);
250+
251+
if (SCRIPT_TYPE_P2SH == type) {
252+
// Compute redeemscript(P2WPKH). scriptpub of nested-segwit is hash160 of
253+
// redeemscript
254+
uint8_t buf[22] = {0};
255+
buf[0] = 0; // version byte
256+
buf[1] = 20; // push 20 bytes
257+
memcpy(buf + 2, digest, 20);
258+
hasher_Raw(HASHER_SHA2_RIPEMD, buf, 22, digest);
259+
}
260+
249261
return (memcmp(digest, &script[offset], RIPEMD160_DIGEST_LENGTH) == 0);
250262
}
251263

apps/btc_family/btc_txn.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,8 @@ static bool fetch_valid_input(btc_query_t *query) {
502502
payload = NULL;
503503
hoisted_query = NULL;
504504

505-
if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type) ||
505+
if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type &&
506+
SCRIPT_TYPE_P2SH != type) ||
506507
validation_result != BTC_VALIDATE_SUCCESS) {
507508
// input validation failed, terminate immediately
508509
btc_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
@@ -680,11 +681,27 @@ static bool sign_input(scrip_sig_t *signatures) {
680681
status = true;
681682
for (int idx = 0; idx < btc_txn_context->metadata.input_count; idx++) {
682683
// generate the input digest and respective private key
683-
status = btc_digest_input(btc_txn_context, idx, buffer);
684684
memcpy(&t_node, &node, sizeof(HDNode));
685685
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].change_index);
686686
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].address_index);
687687
hdnode_fill_public_key(&t_node);
688+
689+
// detect input type
690+
btc_sign_txn_input_script_pub_key_t *script =
691+
&btc_txn_context->inputs[idx].script_pub_key;
692+
btc_script_type_e type = btc_get_script_type(script->bytes, script->size);
693+
if (SCRIPT_TYPE_P2SH == type) {
694+
// replace BIP16 scriptpubkey with redeemscript(P2WPKH)
695+
uint8_t buf[22] = {0};
696+
buf[0] = 0; // version byte
697+
buf[1] = 20; // push 20 bytes
698+
ecdsa_get_pubkeyhash(
699+
t_node.public_key, t_node.curve->hasher_pubkey, buf + 2);
700+
memcpy(btc_txn_context->inputs[idx].script_pub_key.bytes, buf, 22);
701+
btc_txn_context->inputs[idx].script_pub_key.size = 22;
702+
}
703+
704+
status = btc_digest_input(btc_txn_context, idx, buffer);
688705
ecdsa_sign_digest(
689706
curve, t_node.private_key, buffer, signatures[idx].bytes, NULL, NULL);
690707
signatures[idx].size = btc_sig_to_script_sig(

apps/btc_family/btc_txn_helpers.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ bool btc_digest_input(const btc_txn_context_t *context,
406406
btc_sign_txn_input_script_pub_key_t *script =
407407
&context->inputs[index].script_pub_key;
408408
btc_script_type_e type = btc_get_script_type(script->bytes, script->size);
409-
410409
if (SCRIPT_TYPE_P2WPKH == type) {
411410
// segwit digest calculation; could fail if segwit_cache not filled
412411
status = calculate_p2wpkh_digest(context, index, digest);

apps/evm_family/evm_user_verification.c

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@
6767
#include "evm_api.h"
6868
#include "evm_priv.h"
6969
#include "exchange_main.h"
70+
#include "flash_api.h"
7071
#include "ui_core_confirm.h"
7172
#include "ui_screens.h"
73+
#include "utils.h"
7274

7375
/*****************************************************************************
7476
* EXTERN VARIABLES
@@ -166,6 +168,8 @@ bool evm_verify_clear_signing(const evm_txn_context_t *txn_context) {
166168
char address[43] = "0x";
167169
const uint8_t *to_address = NULL;
168170
const char *unit = g_evm_app->lunit_name;
171+
char hex_str[30] = {'\0'};
172+
char value[34] = {'\0'};
169173
char fee[34] = "";
170174
char display[40] = "";
171175

@@ -179,6 +183,24 @@ bool evm_verify_clear_signing(const evm_txn_context_t *txn_context) {
179183
return false;
180184
}
181185

186+
// verify recipient amount
187+
uint8_t zeros[32] = {0};
188+
if (memcmp(txn_context->transaction_info.value,
189+
zeros,
190+
txn_context->transaction_info.value_size[0]) != 0) {
191+
uint8_t len = eth_get_value(txn_context, hex_str);
192+
if (!convert_byte_array_to_decimal_string(
193+
len, evm_get_decimal(txn_context), hex_str, value, sizeof(value))) {
194+
evm_send_error(ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG, 1);
195+
return false;
196+
}
197+
198+
snprintf(display, sizeof(display), UI_TEXT_VERIFY_AMOUNT, value, unit);
199+
if (!core_confirmation(display, evm_send_error)) {
200+
return false;
201+
}
202+
}
203+
182204
// verify transaction fee
183205
eth_get_fee_string(
184206
&txn_context->transaction_info, fee, sizeof(fee), ETH_DECIMAL);
@@ -207,27 +229,71 @@ bool evm_verify_blind_signing(const evm_txn_context_t *txn_context) {
207229
bool status = false;
208230
const uint8_t *to_address = NULL;
209231
char address[43] = "0x";
210-
char path_str[64] = "";
211232
char fee[34] = "";
212233
char display[40] = "";
234+
char amount_display[40] = "";
235+
uint8_t zeros[32] = {0};
236+
bool verify_amount = false;
213237
const char *unit = g_evm_app->lunit_name;
214-
const uint32_t *hd_path = txn_context->init_info.derivation_path;
215-
size_t depth = txn_context->init_info.derivation_path_count;
216238

217239
// TODO: decide on handling blind signing via wallet setting
218240
to_address = txn_context->transaction_info.to_address;
219241
ethereum_address_checksum(
220242
to_address, &address[2], false, g_evm_app->chain_id);
221-
hd_path_array_to_string(hd_path, depth, false, path_str, sizeof(path_str));
243+
222244
eth_get_fee_string(
223245
&txn_context->transaction_info, fee, sizeof(fee), ETH_DECIMAL);
224246
snprintf(display, sizeof(display), UI_TEXT_SEND_TXN_FEE, fee, unit);
225-
// show warning for unknown EVM function; take user consent
226-
if (!core_confirmation(UI_TEXT_BLIND_SIGNING_WARNING, evm_send_error) ||
227-
!core_scroll_page(UI_TEXT_VERIFY_HD_PATH, path_str, evm_send_error) ||
228-
!core_scroll_page(ui_text_verify_contract, address, evm_send_error) ||
229-
!core_scroll_page(UI_TEXT_TXN_FEE, display, evm_send_error)) {
230-
return status;
247+
248+
// verify recipient amount
249+
if (memcmp(txn_context->transaction_info.value,
250+
zeros,
251+
txn_context->transaction_info.value_size[0]) != 0) {
252+
verify_amount = true;
253+
char hex_str[30] = {'\0'};
254+
char value[34] = {'\0'};
255+
uint8_t len = eth_get_value(txn_context, hex_str);
256+
if (!convert_byte_array_to_decimal_string(
257+
len, evm_get_decimal(txn_context), hex_str, value, sizeof(value))) {
258+
evm_send_error(ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG, 1);
259+
return false;
260+
}
261+
262+
snprintf(amount_display,
263+
sizeof(amount_display),
264+
UI_TEXT_VERIFY_AMOUNT,
265+
value,
266+
unit);
267+
}
268+
269+
if (is_raw_calldata_enabled()) {
270+
uint64_t data_size = txn_context->transaction_info.data_size;
271+
char data_str[2 + data_size * 2 + 1];
272+
snprintf(data_str, sizeof(data_str), "0x");
273+
byte_array_to_hex_string(txn_context->transaction_info.data,
274+
data_size,
275+
data_str + 2,
276+
sizeof(data_str) - 2);
277+
if (!core_scroll_page(ui_text_verify_contract, address, evm_send_error) ||
278+
(verify_amount && !core_confirmation(amount_display, evm_send_error)) ||
279+
!core_scroll_page(UI_TEXT_TXN_FEE, display, evm_send_error) ||
280+
!core_scroll_page(UI_TEXT_CALLDATA, data_str, evm_send_error)) {
281+
return status;
282+
}
283+
} else {
284+
char path_str[64] = "";
285+
const uint32_t *hd_path = txn_context->init_info.derivation_path;
286+
size_t depth = txn_context->init_info.derivation_path_count;
287+
hd_path_array_to_string(hd_path, depth, false, path_str, sizeof(path_str));
288+
289+
// show warning for unknown EVM function; take user consent
290+
if (!core_confirmation(UI_TEXT_BLIND_SIGNING_WARNING, evm_send_error) ||
291+
!core_scroll_page(UI_TEXT_VERIFY_HD_PATH, path_str, evm_send_error) ||
292+
!core_scroll_page(ui_text_verify_contract, address, evm_send_error) ||
293+
(verify_amount && !core_confirmation(amount_display, evm_send_error)) ||
294+
!core_scroll_page(UI_TEXT_TXN_FEE, display, evm_send_error)) {
295+
return status;
296+
}
231297
}
232298

233299
return true;

common/interfaces/flash_interface/flash_api.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,20 @@ uint8_t get_onboarding_step(void) {
10491049
return flash_ram_instance.onboarding_step;
10501050
}
10511051

1052+
bool is_raw_calldata_enabled() {
1053+
get_flash_ram_instance();
1054+
return (flash_ram_instance.enable_raw_calldata == RAW_CALLDATA_ENABLED);
1055+
}
1056+
1057+
int set_raw_calldata_config(raw_calldata_config state,
1058+
flash_save_mode save_mode) {
1059+
get_flash_ram_instance();
1060+
flash_ram_instance.enable_raw_calldata = state;
1061+
if (save_mode == FLASH_SAVE_NOW)
1062+
flash_struct_save();
1063+
return STM_SUCCESS;
1064+
}
1065+
10521066
const uint8_t *get_perm_self_key_id() {
10531067
get_flash_perm_instance();
10541068
return flash_perm_instance.permKeyData.ext_keys.self_key_id;

common/interfaces/flash_interface/flash_api.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,39 @@ bool is_logging_enabled();
514514
*/
515515
int set_logging_config(log_config state, flash_save_mode save_mode);
516516

517+
/**
518+
* @brief
519+
* @details
520+
*
521+
* @param
522+
*
523+
* @return
524+
* @retval
525+
*
526+
* @see
527+
* @since v1.0.0
528+
*
529+
* @note
530+
*/
531+
bool is_raw_calldata_enabled();
532+
533+
/**
534+
* @brief
535+
* @details
536+
*
537+
* @param
538+
*
539+
* @return
540+
* @retval
541+
*
542+
* @see
543+
* @since v1.0.0
544+
*
545+
* @note
546+
*/
547+
int set_raw_calldata_config(raw_calldata_config state,
548+
flash_save_mode save_mode);
549+
517550
/**
518551
* @brief
519552
* @details

common/interfaces/flash_interface/flash_struct.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
*/
5959
#include "flash_struct.h"
6060

61+
#include <stdint.h>
6162
#include <string.h>
6263

6364
#include "assert_conf.h"
@@ -84,7 +85,8 @@
8485
(6 + 3 + FAMILY_ID_SIZE + 3 + sizeof(uint32_t) + 3 + \
8586
(MAX_WALLETS_ALLOWED * ((15 * 3) + sizeof(Flash_Wallet))) + 3 + \
8687
sizeof(uint8_t) + 3 + sizeof(uint8_t) + 3 + sizeof(uint8_t) + 3 + \
87-
sizeof(uint8_t))
88+
sizeof(uint8_t)) + \
89+
3 + sizeof(uint8_t)
8890

8991
/// The size of tlv that will be read and written to flash. Since we read/write
9092
/// in multiples of 4 hence it is essential to make the size divisible by 4.
@@ -106,6 +108,7 @@ typedef enum Flash_tlv_tags {
106108
TAG_FLASH_TOGGLE_PASSPHRASE = 0x07,
107109
TAG_FLASH_TOGGLE_LOGS = 0x08,
108110
TAG_FLASH_ONBOARDING_STEP = 0x09,
111+
TAG_FLASH_TOGGLE_RAW_CALLDATA = 0x10,
109112

110113
TAG_FLASH_WALLET = 0x20,
111114
TAG_FLASH_WALLET_STATE = 0x21,
@@ -425,6 +428,12 @@ static uint16_t serialize_fs(const Flash_Struct *flash_struct, uint8_t *tlv) {
425428
TAG_FLASH_ONBOARDING_STEP,
426429
sizeof(flash_struct->onboarding_step),
427430
&(flash_struct->onboarding_step));
431+
fill_flash_tlv(tlv,
432+
&index,
433+
TAG_FLASH_TOGGLE_RAW_CALLDATA,
434+
sizeof(flash_struct->enable_raw_calldata),
435+
&(flash_struct->enable_raw_calldata));
436+
428437
tlv[4] = index - 6;
429438
tlv[5] = (index - 6) >> 8;
430439

@@ -605,6 +614,11 @@ static void deserialize_fs(Flash_Struct *flash_struct, uint8_t *tlv) {
605614
break;
606615
}
607616

617+
case TAG_FLASH_TOGGLE_RAW_CALLDATA: {
618+
memcpy(&(flash_struct->enable_raw_calldata), tlv + index + 2, size);
619+
break;
620+
}
621+
608622
default: {
609623
break;
610624
}

common/interfaces/flash_interface/flash_struct.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ typedef enum log_config {
3131
LOGGING_ENABLED,
3232
} log_config;
3333

34+
/// enum for raw calldata config
35+
typedef enum raw_calldata_config {
36+
RAW_CALLDATA_DISABLED,
37+
RAW_CALLDATA_ENABLED,
38+
} raw_calldata_config;
39+
3440
/// enum to signify the wallet state
3541
typedef enum wallet_state {
3642
INVALID_WALLET = 1,
@@ -123,6 +129,7 @@ typedef struct Flash_Struct {
123129
uint8_t enable_passphrase;
124130
uint8_t enable_log;
125131
uint8_t onboarding_step;
132+
uint8_t enable_raw_calldata;
126133
} Flash_Struct;
127134
#pragma pack(pop)
128135

src/constant_texts.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const char *ui_text_options_settings[NUMBER_OF_OPTIONS_SETTINGS] = {
9191
"View Card Version",
9292
"Regulatory Info",
9393
"Pair Cards",
94+
"Advanced",
9495
#ifdef DEV_BUILD
9596
"Buzzer toggle",
9697
#endif
@@ -122,6 +123,17 @@ const char *ui_text_options_buzzer_adjust[] = {
122123
};
123124
#endif /* DEV_BUILD */
124125

126+
// Advanced Settings menu text
127+
const char *ui_text_heading_advanced_settings = "Advanced Settings";
128+
const char
129+
*ui_text_options_advanced_settings[NUMBER_OF_OPTIONS_ADVANCED_SETTINGS] = {
130+
"Toggle Raw Calldata"};
131+
132+
const char *ui_text_options_raw_calldata[] = {
133+
"Enable Raw Calldata",
134+
"Disable Raw Calldata",
135+
};
136+
125137
// Regulatory info text
126138
const char *ui_text_regulatory_info[NUMBER_OF_SLIDES_REGULATORY_INFO] = {
127139
"This device complies with Part 15 of the FCC Rules. Operation is",
@@ -448,6 +460,9 @@ const char *ui_text_warning_txn_fee_too_high =
448460
"WARNING!\nTransaction fees\ntoo high, proceed?";
449461
const char *ui_text_enable_log_export = "Do you want to enable logging?";
450462
const char *ui_text_disable_log_export = "Do you want to disable logging?";
463+
const char *ui_text_enable_raw_calldata =
464+
"This will display transaction's raw technical\ndata for in-depth "
465+
"verification before signing\nEnable Raw Calldata?";
451466

452467
//?
453468
const char *ui_text_do_you_want_import_wallet_to_desktop =

0 commit comments

Comments
 (0)