From 83db3c098fcfcc04e0faa400bc61c1aa32326226 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 3 Oct 2017 13:11:53 +0200 Subject: [PATCH] fsm: implement CoSi messages --- firmware/fsm.c | 79 +++++++++++++++++++++++++++++++- firmware/fsm.h | 3 ++ firmware/layout2.c | 19 ++++++++ firmware/layout2.h | 2 + firmware/protob/messages.options | 13 ++++++ vendor/trezor-common | 2 +- 6 files changed, 116 insertions(+), 2 deletions(-) diff --git a/firmware/fsm.c b/firmware/fsm.c index 4ad24b19f5..264a5d6198 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -17,6 +17,8 @@ * along with this library. If not, see . */ +#include + #include "trezor.h" #include "fsm.h" #include "messages.h" @@ -48,10 +50,10 @@ #include "ripemd160.h" #include "curves.h" #include "secp256k1.h" -#include #include "ethereum.h" #include "nem.h" #include "nem2.h" +#include "rfc6979.h" #include "gettext.h" // message methods @@ -1315,6 +1317,81 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) { layoutHome(); } +void fsm_msgCosiCommit(CosiCommit *msg) +{ + RESP_INIT(CosiCommitment); + + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_data, _("No data provided")); + + layoutCosiCommitSign(msg->data.bytes, msg->data.size, false); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + HDNode *node = fsm_getDerivedNode(ED25519_NAME, msg->address_n, msg->address_n_count); + if (!node) return; + + uint8_t nonce[32]; + sha256_Raw(msg->data.bytes, msg->data.size, nonce); + rfc6979_state rng; + init_rfc6979(node->private_key, nonce, &rng); + generate_rfc6979(nonce, &rng); + + resp->has_commitment = true; + resp->has_pubkey = true; + resp->commitment.size = 32; + resp->pubkey.size = 32; + + ed25519_publickey(nonce, resp->commitment.bytes); + ed25519_publickey(node->private_key, resp->pubkey.bytes); + + msg_write(MessageType_MessageType_CosiCommitment, resp); + layoutHome(); +} + +void fsm_msgCosiSign(CosiSign *msg) +{ + RESP_INIT(CosiSignature); + + CHECK_INITIALIZED + + CHECK_PARAM(msg->has_data, _("No data provided")); + CHECK_PARAM(msg->has_global_commitment && msg->global_commitment.size == 32, _("Invalid global commitment")); + CHECK_PARAM(msg->has_global_pubkey && msg->global_pubkey.size == 32, _("Invalid global pubkey")); + + layoutCosiCommitSign(msg->data.bytes, msg->data.size, true); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL); + layoutHome(); + return; + } + + CHECK_PIN + + HDNode *node = fsm_getDerivedNode(ED25519_NAME, msg->address_n, msg->address_n_count); + if (!node) return; + + uint8_t nonce[32]; + sha256_Raw(msg->data.bytes, msg->data.size, nonce); + rfc6979_state rng; + init_rfc6979(node->private_key, nonce, &rng); + generate_rfc6979(nonce, &rng); + + resp->has_signature = true; + resp->signature.size = 32; + + ed25519_cosi_sign(msg->data.bytes, msg->data.size, node->private_key, nonce, msg->global_commitment.bytes, msg->global_pubkey.bytes, resp->signature.bytes); + + msg_write(MessageType_MessageType_CosiSignature, resp); + layoutHome(); +} + #if DEBUG_LINK void fsm_msgDebugLinkGetState(DebugLinkGetState *msg) diff --git a/firmware/fsm.h b/firmware/fsm.h index 3768e12996..a738ab59cb 100644 --- a/firmware/fsm.h +++ b/firmware/fsm.h @@ -69,6 +69,9 @@ void fsm_msgEthereumVerifyMessage(EthereumVerifyMessage *msg); void fsm_msgNEMGetAddress(NEMGetAddress *msg); void fsm_msgNEMSignTx(NEMSignTx *msg); +void fsm_msgCosiCommit(CosiCommit *msg); +void fsm_msgCosiSign(CosiSign *msg); + // debug message functions #if DEBUG_LINK //void fsm_msgDebugLinkDecision(DebugLinkDecision *msg); diff --git a/firmware/layout2.c b/firmware/layout2.c index ac1e6ae860..0ffd7aa6d7 100644 --- a/firmware/layout2.c +++ b/firmware/layout2.c @@ -644,3 +644,22 @@ void layoutNEMLevy(const NEMMosaicDefinition *definition, uint8_t network) { break; } } + +void layoutCosiCommitSign(const uint8_t *data, uint32_t len, bool final_sign) +{ + char str[4][17]; + if (len == 32) { + data2hex(data , 8, str[0]); + data2hex(data + 8, 8, str[1]); + data2hex(data + 16, 8, str[2]); + data2hex(data + 24, 8, str[3]); + } else { + strlcpy(str[0], "Data", sizeof(str[0])); + strlcpy(str[1], "of", sizeof(str[1])); + strlcpy(str[2], "unsupported", sizeof(str[2])); + strlcpy(str[3], "length", sizeof(str[3])); + } + layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), + final_sign ? _("CoSi sign message?") : _("CoSi commit message?"), + str[0], str[1], str[2], str[3], NULL, NULL); +} diff --git a/firmware/layout2.h b/firmware/layout2.h index 6176e61794..d87c80e418 100644 --- a/firmware/layout2.h +++ b/firmware/layout2.h @@ -57,4 +57,6 @@ void layoutNEMTransferPayload(const uint8_t *payload, size_t length, bool encryp void layoutNEMMosaicDescription(const char *description); void layoutNEMLevy(const NEMMosaicDefinition *definition, uint8_t network); +void layoutCosiCommitSign(const uint8_t *data, uint32_t len, bool final_sign); + #endif diff --git a/firmware/protob/messages.options b/firmware/protob/messages.options index c4c0f06675..9964171d58 100644 --- a/firmware/protob/messages.options +++ b/firmware/protob/messages.options @@ -149,6 +149,19 @@ NEMAddress.address max_size:41 NEMSignedTx.data max_size:2048 NEMSignedTx.signature max_size:64 +CosiCommit.address_n max_count:8 +CosiCommit.data max_size:32 + +CosiCommitment.commitment max_size:32 +CosiCommitment.pubkey max_size:32 + +CosiSign.address_n max_count:8 +CosiSign.data max_size:32 +CosiSign.global_commitment max_size:32 +CosiSign.global_pubkey max_size:32 + +CosiSignature.signature max_size:32 + # deprecated SimpleSignTx skip_message:true diff --git a/vendor/trezor-common b/vendor/trezor-common index c41f84e221..c20bb1c567 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit c41f84e221f0fc370fcad399541f6fff00f717b8 +Subproject commit c20bb1c567ac0c1ddabf74354f204043eeacad10