Skip to content

Commit ba440cf

Browse files
authored
Merge branch 'develop' into feat/test_btc
2 parents 4b242d2 + 2de49c0 commit ba440cf

Some content is hidden

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

44 files changed

+3403
-30
lines changed

apps/btc_family/btc_pub_key.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,16 @@ static size_t btc_get_address(const uint8_t *seed,
228228
case NON_SEGWIT:
229229
hdnode_get_address(&node, g_btc_app->p2pkh_addr_ver, addr, 35);
230230
break;
231-
// TODO: add support for taproot and segwit
231+
case PURPOSE_SEGWIT:
232+
ecdsa_get_address_segwit_p2sh(node.public_key,
233+
g_btc_app->p2sh_addr_ver,
234+
node.curve->hasher_pubkey,
235+
node.curve->hasher_base58,
236+
addr,
237+
36);
238+
break;
239+
240+
// TODO: add support for taproot
232241
default:
233242
break;
234243
}

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
@@ -510,7 +510,8 @@ static bool fetch_valid_input(btc_query_t *query) {
510510
payload = NULL;
511511
hoisted_query = NULL;
512512

513-
if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type) ||
513+
if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type &&
514+
SCRIPT_TYPE_P2SH != type) ||
514515
validation_result != BTC_VALIDATE_SUCCESS) {
515516
// input validation failed, terminate immediately
516517
btc_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
@@ -690,11 +691,27 @@ static bool sign_input(scrip_sig_t *signatures) {
690691
status = true;
691692
for (int idx = 0; idx < btc_txn_context->metadata.input_count; idx++) {
692693
// generate the input digest and respective private key
693-
status = btc_digest_input(btc_txn_context, idx, buffer);
694694
memcpy(&t_node, &node, sizeof(HDNode));
695695
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].change_index);
696696
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].address_index);
697697
hdnode_fill_public_key(&t_node);
698+
699+
// detect input type
700+
btc_sign_txn_input_script_pub_key_t *script =
701+
&btc_txn_context->inputs[idx].script_pub_key;
702+
btc_script_type_e type = btc_get_script_type(script->bytes, script->size);
703+
if (SCRIPT_TYPE_P2SH == type) {
704+
// replace BIP16 scriptpubkey with redeemscript(P2WPKH)
705+
uint8_t buf[22] = {0};
706+
buf[0] = 0; // version byte
707+
buf[1] = 20; // push 20 bytes
708+
ecdsa_get_pubkeyhash(
709+
t_node.public_key, t_node.curve->hasher_pubkey, buf + 2);
710+
memcpy(btc_txn_context->inputs[idx].script_pub_key.bytes, buf, 22);
711+
btc_txn_context->inputs[idx].script_pub_key.size = 22;
712+
}
713+
714+
status = btc_digest_input(btc_txn_context, idx, buffer);
698715
ecdsa_sign_digest(
699716
curve, t_node.private_key, buffer, signatures[idx].bytes, NULL, NULL);
700717
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;

0 commit comments

Comments
 (0)