1
0
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:
Pavol Rusnak 2016-05-17 18:13:08 +02:00
parent 49691c2436
commit d20671b517
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
12 changed files with 41 additions and 27 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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

@ -1 +1 @@
Subproject commit 8c6401bdef92ebef7375a0e58a06af117618519d
Subproject commit 36a574056deacad8943f1412c3db149750f8b163

@ -1 +1 @@
Subproject commit 51c0bb09d8f1066555d28ae3824988b318d2f39e
Subproject commit 23590c05c652efccdfb7e837a048adbecab5b145