mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-14 03:30:02 +00:00
handle various signed_message_headers correctly
This commit is contained in:
parent
49691c2436
commit
d20671b517
@ -21,12 +21,12 @@
|
||||
#include "coins.h"
|
||||
|
||||
const CoinType coins[COINS_COUNT] = {
|
||||
{true, "Bitcoin", true, "BTC", true, 0, true, 100000, true, 5, true, 6, true, 10},
|
||||
{true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40},
|
||||
{true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0},
|
||||
{true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0},
|
||||
{true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0},
|
||||
{true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0},
|
||||
{true, "Bitcoin", true, "BTC", true, 0, true, 100000, true, 5, true, 6, true, 10, true, "\x18" "Bitcoin Signed Message:\n"},
|
||||
{true, "Testnet", true, "TEST", true, 111, true, 10000000, true, 196, true, 3, true, 40, true, "\x18" "Bitcoin Signed Message:\n"},
|
||||
{true, "Namecoin", true, "NMC", true, 52, true, 10000000, true, 5, false, 0, false, 0, true, "\x19" "Namecoin Signed Message:\n"},
|
||||
{true, "Litecoin", true, "LTC", true, 48, true, 1000000, true, 5, false, 0, false, 0, true, "\x19" "Litecoin Signed Message:\n"},
|
||||
{true, "Dogecoin", true, "DOGE", true, 30, true, 1000000000, true, 22, false, 0, false, 0, true, "\x19" "Dogecoin Signed Message:\n"},
|
||||
{true, "Dash", true, "DASH", true, 76, true, 100000, true, 16, false, 0, false, 0, true, "\x19" "DarkCoin Signed Message:\n"},
|
||||
};
|
||||
|
||||
const CoinType *coinByShortcut(const char *shortcut)
|
||||
|
@ -100,11 +100,11 @@ int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_le
|
||||
return hdnode_sign_digest(node, message, signature + 1, NULL);
|
||||
}
|
||||
|
||||
int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
sha256_Init(&ctx);
|
||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||
sha256_Update(&ctx, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
||||
uint8_t varint[5];
|
||||
uint32_t l = ser_length(message_len, varint);
|
||||
sha256_Update(&ctx, varint, l);
|
||||
@ -120,14 +120,14 @@ int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message
|
||||
return result;
|
||||
}
|
||||
|
||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
||||
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
uint8_t pubkey[65], addr_raw[21], hash[32];
|
||||
|
||||
// calculate hash
|
||||
sha256_Init(&ctx);
|
||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||
sha256_Update(&ctx, (const uint8_t *)coin->signed_message_header, strlen(coin->signed_message_header));
|
||||
uint8_t varint[5];
|
||||
uint32_t l = ser_length(message_len, varint);
|
||||
sha256_Update(&ctx, varint, l);
|
||||
|
@ -37,9 +37,9 @@ int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_le
|
||||
|
||||
int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
int cryptoMessageSign(const CoinType *coin, const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature);
|
||||
|
||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
int cryptoMessageVerify(const CoinType *coin, const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
|
||||
/* ECIES disabled
|
||||
int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_size, bool display_only, uint8_t *nonce, size_t *nonce_len, uint8_t *payload, size_t *payload_len, uint8_t *hmac, size_t *hmac_len, const uint8_t *privkey, const uint8_t *address_raw);
|
||||
|
@ -643,7 +643,7 @@ void fsm_msgSignMessage(SignMessage *msg)
|
||||
if (!node) return;
|
||||
|
||||
layoutProgressSwipe("Signing", 0);
|
||||
if (cryptoMessageSign(node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
|
||||
if (cryptoMessageSign(coin, node, msg->message.bytes, msg->message.size, resp->signature.bytes) == 0) {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, coin->address_type, addr_raw);
|
||||
@ -667,12 +667,14 @@ void fsm_msgVerifyMessage(VerifyMessage *msg)
|
||||
fsm_sendFailure(FailureType_Failure_Other, "No message provided");
|
||||
return;
|
||||
}
|
||||
const CoinType *coin = fsm_getCoin(msg->coin_name);
|
||||
if (!coin) return;
|
||||
layoutProgressSwipe("Verifying", 0);
|
||||
uint8_t addr_raw[21];
|
||||
if (!ecdsa_address_decode(msg->address, addr_raw)) {
|
||||
fsm_sendFailure(FailureType_Failure_InvalidSignature, "Invalid address");
|
||||
}
|
||||
if (msg->signature.size == 65 && cryptoMessageVerify(msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) {
|
||||
if (msg->signature.size == 65 && cryptoMessageVerify(coin, msg->message.bytes, msg->message.size, addr_raw, msg->signature.bytes) == 0) {
|
||||
layoutVerifyAddress(msg->address);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, "Message verification cancelled");
|
||||
@ -747,7 +749,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
uint8_t digest[64];
|
||||
sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest);
|
||||
sha256_Raw((const uint8_t *)msg->challenge_visual, strlen(msg->challenge_visual), digest + 32);
|
||||
result = cryptoMessageSign(node, digest, 64, resp->signature.bytes);
|
||||
result = cryptoMessageSign(&(coins[0]), node, digest, 64, resp->signature.bytes);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
|
@ -56,6 +56,7 @@ SignMessage.coin_name max_size:17
|
||||
VerifyMessage.address max_size:36
|
||||
VerifyMessage.signature max_size:65
|
||||
VerifyMessage.message max_size:1024
|
||||
VerifyMessage.coin_name max_size:17
|
||||
|
||||
MessageSignature.address max_size:36
|
||||
MessageSignature.signature max_size:65
|
||||
|
@ -9,6 +9,7 @@ const uint32_t ResetDevice_strength_default = 256u;
|
||||
const char ResetDevice_language_default[17] = "english";
|
||||
const char RecoveryDevice_language_default[17] = "english";
|
||||
const char SignMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char VerifyMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char EncryptMessage_coin_name_default[17] = "Bitcoin";
|
||||
const char EstimateTxSize_coin_name_default[17] = "Bitcoin";
|
||||
const char SignTx_coin_name_default[17] = "Bitcoin";
|
||||
@ -213,10 +214,11 @@ const pb_field_t SignMessage_fields[4] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t VerifyMessage_fields[4] = {
|
||||
const pb_field_t VerifyMessage_fields[5] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, VerifyMessage, address, address, 0),
|
||||
PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, signature, address, 0),
|
||||
PB_FIELD2( 3, BYTES , OPTIONAL, STATIC , OTHER, VerifyMessage, message, signature, 0),
|
||||
PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, VerifyMessage, coin_name, message, &VerifyMessage_coin_name_default),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -634,6 +634,8 @@ typedef struct _VerifyMessage {
|
||||
VerifyMessage_signature_t signature;
|
||||
bool has_message;
|
||||
VerifyMessage_message_t message;
|
||||
bool has_coin_name;
|
||||
char coin_name[17];
|
||||
} VerifyMessage;
|
||||
|
||||
typedef struct _WordAck {
|
||||
@ -647,6 +649,7 @@ extern const uint32_t ResetDevice_strength_default;
|
||||
extern const char ResetDevice_language_default[17];
|
||||
extern const char RecoveryDevice_language_default[17];
|
||||
extern const char SignMessage_coin_name_default[17];
|
||||
extern const char VerifyMessage_coin_name_default[17];
|
||||
extern const char EncryptMessage_coin_name_default[17];
|
||||
extern const char EstimateTxSize_coin_name_default[17];
|
||||
extern const char SignTx_coin_name_default[17];
|
||||
@ -688,7 +691,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define WordRequest_init_default {0}
|
||||
#define WordAck_init_default {""}
|
||||
#define SignMessage_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, "Bitcoin"}
|
||||
#define VerifyMessage_init_default {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define VerifyMessage_init_default {false, "", false, {0, {0}}, false, {0, {0}}, false, "Bitcoin"}
|
||||
#define MessageSignature_init_default {false, "", false, {0, {0}}}
|
||||
#define EncryptMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin"}
|
||||
#define EncryptedMessage_init_default {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
@ -742,7 +745,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define WordRequest_init_zero {0}
|
||||
#define WordAck_init_zero {""}
|
||||
#define SignMessage_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, false, ""}
|
||||
#define VerifyMessage_init_zero {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define VerifyMessage_init_zero {false, "", false, {0, {0}}, false, {0, {0}}, false, ""}
|
||||
#define MessageSignature_init_zero {false, "", false, {0, {0}}}
|
||||
#define EncryptMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, false, ""}
|
||||
#define EncryptedMessage_init_zero {false, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
@ -904,6 +907,7 @@ extern const uint32_t SimpleSignTx_lock_time_default;
|
||||
#define VerifyMessage_address_tag 1
|
||||
#define VerifyMessage_signature_tag 2
|
||||
#define VerifyMessage_message_tag 3
|
||||
#define VerifyMessage_coin_name_tag 4
|
||||
#define WordAck_word_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
@ -938,7 +942,7 @@ extern const pb_field_t RecoveryDevice_fields[7];
|
||||
extern const pb_field_t WordRequest_fields[1];
|
||||
extern const pb_field_t WordAck_fields[2];
|
||||
extern const pb_field_t SignMessage_fields[4];
|
||||
extern const pb_field_t VerifyMessage_fields[4];
|
||||
extern const pb_field_t VerifyMessage_fields[5];
|
||||
extern const pb_field_t MessageSignature_fields[3];
|
||||
extern const pb_field_t EncryptMessage_fields[6];
|
||||
extern const pb_field_t EncryptedMessage_fields[4];
|
||||
@ -994,7 +998,7 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define WordRequest_size 0
|
||||
#define WordAck_size 14
|
||||
#define SignMessage_size 1094
|
||||
#define VerifyMessage_size 1132
|
||||
#define VerifyMessage_size 1151
|
||||
#define MessageSignature_size 105
|
||||
#define EncryptMessage_size 1131
|
||||
#define EncryptedMessage_size 1168
|
||||
|
@ -6,6 +6,7 @@ HDNodePathType.address_n max_count:8
|
||||
|
||||
CoinType.coin_name max_size:17
|
||||
CoinType.coin_shortcut max_size:9
|
||||
CoinType.signed_message_header max_size:32
|
||||
|
||||
TxInputType.address_n max_count:8
|
||||
TxInputType.prev_hash max_size:32
|
||||
|
@ -28,7 +28,7 @@ const pb_field_t HDNodePathType_fields[3] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t CoinType_fields[8] = {
|
||||
const pb_field_t CoinType_fields[9] = {
|
||||
PB_FIELD2( 1, STRING , OPTIONAL, STATIC , FIRST, CoinType, coin_name, coin_name, 0),
|
||||
PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, CoinType, coin_shortcut, coin_name, 0),
|
||||
PB_FIELD2( 3, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type, coin_shortcut, &CoinType_address_type_default),
|
||||
@ -36,6 +36,7 @@ const pb_field_t CoinType_fields[8] = {
|
||||
PB_FIELD2( 5, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2sh, maxfee_kb, &CoinType_address_type_p2sh_default),
|
||||
PB_FIELD2( 6, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2wpkh, address_type_p2sh, &CoinType_address_type_p2wpkh_default),
|
||||
PB_FIELD2( 7, UINT32 , OPTIONAL, STATIC , OTHER, CoinType, address_type_p2wsh, address_type_p2wpkh, &CoinType_address_type_p2wsh_default),
|
||||
PB_FIELD2( 8, STRING , OPTIONAL, STATIC , OTHER, CoinType, signed_message_header, address_type_p2wsh, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,8 @@ typedef struct _CoinType {
|
||||
uint32_t address_type_p2wpkh;
|
||||
bool has_address_type_p2wsh;
|
||||
uint32_t address_type_p2wsh;
|
||||
bool has_signed_message_header;
|
||||
char signed_message_header[32];
|
||||
} CoinType;
|
||||
|
||||
typedef struct {
|
||||
@ -261,7 +263,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
/* Initializer values for message structs */
|
||||
#define HDNodeType_init_default {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
#define HDNodePathType_init_default {HDNodeType_init_default, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define CoinType_init_default {false, "", false, "", false, 0u, false, 0, false, 5u, false, 6u, false, 10u}
|
||||
#define CoinType_init_default {false, "", false, "", false, 0u, false, 0, false, 5u, false, 6u, false, 10u, false, ""}
|
||||
#define MultisigRedeemScriptType_init_default {0, {HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default, HDNodePathType_init_default}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
|
||||
#define TxInputType_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 4294967295u, false, InputScriptType_SPENDADDRESS, false, MultisigRedeemScriptType_init_default}
|
||||
#define TxOutputType_init_default {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_default, false, {0, {0}}}
|
||||
@ -272,7 +274,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
#define IdentityType_init_default {false, "", false, "", false, "", false, "", false, "", false, 0u}
|
||||
#define HDNodeType_init_zero {0, 0, 0, {0, {0}}, false, {0, {0}}, false, {0, {0}}}
|
||||
#define HDNodePathType_init_zero {HDNodeType_init_zero, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define CoinType_init_zero {false, "", false, "", false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define CoinType_init_zero {false, "", false, "", false, 0, false, 0, false, 0, false, 0, false, 0, false, ""}
|
||||
#define MultisigRedeemScriptType_init_zero {0, {HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero, HDNodePathType_init_zero}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, false, 0}
|
||||
#define TxInputType_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, {0}}, 0, false, {0, {0}}, false, 0, false, (InputScriptType)0, false, MultisigRedeemScriptType_init_zero}
|
||||
#define TxOutputType_init_zero {false, "", 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, (OutputScriptType)0, false, MultisigRedeemScriptType_init_zero, false, {0, {0}}}
|
||||
@ -290,6 +292,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
#define CoinType_address_type_p2sh_tag 5
|
||||
#define CoinType_address_type_p2wpkh_tag 6
|
||||
#define CoinType_address_type_p2wsh_tag 7
|
||||
#define CoinType_signed_message_header_tag 8
|
||||
#define HDNodeType_depth_tag 1
|
||||
#define HDNodeType_fingerprint_tag 2
|
||||
#define HDNodeType_child_num_tag 3
|
||||
@ -342,7 +345,7 @@ extern const uint32_t IdentityType_index_default;
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t HDNodeType_fields[7];
|
||||
extern const pb_field_t HDNodePathType_fields[3];
|
||||
extern const pb_field_t CoinType_fields[8];
|
||||
extern const pb_field_t CoinType_fields[9];
|
||||
extern const pb_field_t MultisigRedeemScriptType_fields[4];
|
||||
extern const pb_field_t TxInputType_fields[8];
|
||||
extern const pb_field_t TxOutputType_fields[7];
|
||||
@ -355,7 +358,7 @@ extern const pb_field_t IdentityType_fields[7];
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define HDNodeType_size 121
|
||||
#define HDNodePathType_size 171
|
||||
#define CoinType_size 65
|
||||
#define CoinType_size 99
|
||||
#define MultisigRedeemScriptType_size 3741
|
||||
#define TxInputType_size 5497
|
||||
#define TxOutputType_size 3929
|
||||
|
2
vendor/trezor-common
vendored
2
vendor/trezor-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 8c6401bdef92ebef7375a0e58a06af117618519d
|
||||
Subproject commit 36a574056deacad8943f1412c3db149750f8b163
|
2
vendor/trezor-crypto
vendored
2
vendor/trezor-crypto
vendored
@ -1 +1 @@
|
||||
Subproject commit 51c0bb09d8f1066555d28ae3824988b318d2f39e
|
||||
Subproject commit 23590c05c652efccdfb7e837a048adbecab5b145
|
Loading…
Reference in New Issue
Block a user