diff --git a/src/coin.h b/src/coin.h index 6d71b37a..df7ee442 100644 --- a/src/coin.h +++ b/src/coin.h @@ -55,6 +55,8 @@ typedef struct { #define MAIN_SLOT 0 +#define DOMAIN_TAG_LENGTH 32 + #ifdef __cplusplus } #endif diff --git a/src/common/actions.c b/src/common/actions.c index 2d265cd3..c5ea4589 100644 --- a/src/common/actions.c +++ b/src/common/actions.c @@ -18,3 +18,19 @@ #include "actions.h" uint16_t action_addr_len; + +// UTF-8 encoding of "FLOW-V0.0-transaction" padded with zeros to 32 bytes +const uint8_t TX_DOMAIN_TAG_TRANSACTION[DOMAIN_TAG_LENGTH] = {\ + 0x46, 0x4C, 0x4F, 0x57, 0x2D, 0x56, 0x30, 0x2E, + 0x30, 0x2D, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6F, 0x6E, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// UTF-8 encoding of "FLOW-V0.0-user" padded with zeros to 32 bytes +const uint8_t TX_DOMAIN_TAG_MESSAGE[DOMAIN_TAG_LENGTH] = {\ + 0x46, 0x4C, 0x4F, 0x57, 0x2D, 0x56, 0x30, 0x2E, + 0x30, 0x2D, 0x75, 0x73, 0x65, 0x72, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/src/common/actions.h b/src/common/actions.h index cca4813c..64e24975 100644 --- a/src/common/actions.h +++ b/src/common/actions.h @@ -25,18 +25,31 @@ #define GET_PUB_KEY_RESPONSE_LENGTH (3 * SECP256_PK_LEN) +extern const uint8_t TX_DOMAIN_TAG_TRANSACTION[DOMAIN_TAG_LENGTH]; +extern const uint8_t TX_DOMAIN_TAG_MESSAGE[DOMAIN_TAG_LENGTH]; + __Z_INLINE void app_sign() { - const uint8_t *message = get_signable(); - const uint16_t messageLength = get_signable_length(); + const uint8_t *message = tx_get_buffer(); + const uint16_t messageLength = tx_get_buffer_length(); + + uint16_t replyLen = 0; + zxerr_t err = crypto_sign(hdPath, cryptoOptions, message, messageLength, TX_DOMAIN_TAG_TRANSACTION, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, &replyLen); + + if (err != zxerr_ok || replyLen == 0) { + set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2); + } else { + set_code(G_io_apdu_buffer, replyLen, APDU_CODE_OK); + io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, replyLen + 2); + } +} + +__Z_INLINE void app_sign_message() { + const uint8_t *message = tx_get_buffer(); + const uint16_t messageLength = tx_get_buffer_length(); uint16_t replyLen = 0; - zxerr_t err = crypto_sign(hdPath, - cryptoOptions, - message, - messageLength, - G_io_apdu_buffer, - IO_APDU_BUFFER_SIZE - 3, - &replyLen); + zxerr_t err = crypto_sign(hdPath, cryptoOptions, message, messageLength, TX_DOMAIN_TAG_MESSAGE, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, &replyLen); if (err != zxerr_ok || replyLen == 0) { set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR); diff --git a/src/common/tx.c b/src/common/tx.c index 7b72d4c7..850dcef5 100644 --- a/src/common/tx.c +++ b/src/common/tx.c @@ -51,15 +51,17 @@ const uint8_t TX_DOMAIN_TAG[DOMAIN_TAG_LENGTH] = { 0x63, 0x74, 0x69, 0x6F, 0x6E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define TX_BUFFER_OFFSET DOMAIN_TAG_LENGTH - void tx_initialize() { - buffering_init(ram_buffer, sizeof(ram_buffer), (uint8_t *) N_appdata.buffer, FLASH_BUFFER_SIZE); + buffering_init( + ram_buffer, + sizeof(ram_buffer), + (uint8_t *) N_appdata.buffer, + sizeof(N_appdata.buffer) + ); } void tx_reset() { buffering_reset(); - buffering_append((uint8_t *) TX_DOMAIN_TAG, DOMAIN_TAG_LENGTH); } uint32_t tx_append(unsigned char *buffer, uint32_t length) { @@ -67,21 +69,10 @@ uint32_t tx_append(unsigned char *buffer, uint32_t length) { } uint32_t tx_get_buffer_length() { - if (buffering_get_buffer()->pos >= TX_BUFFER_OFFSET) { - return buffering_get_buffer()->pos - TX_BUFFER_OFFSET; - } - return 0; -} - -uint32_t get_signable_length() { return buffering_get_buffer()->pos; } uint8_t *tx_get_buffer() { - return buffering_get_buffer()->data + TX_BUFFER_OFFSET; -} - -uint8_t *get_signable() { return buffering_get_buffer()->data; } diff --git a/src/crypto.c b/src/crypto.c index c6bbd9e3..9071a4b1 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -100,6 +100,7 @@ void sha256(const uint8_t *message, uint16_t messageLen, uint8_t message_digest[ zxerr_t digest_message(const uint8_t *message, uint16_t messageLen, + const uint8_t domainTag[DOMAIN_TAG_LENGTH], digest_type_e hash_kind, uint8_t *digest, uint16_t digestMax, @@ -113,8 +114,14 @@ zxerr_t digest_message(const uint8_t *message, zemu_log_stack("digest_message: zxerr_buffer_too_small"); return zxerr_buffer_too_small; } - sha256(message, messageLen, digest); - *digest_size = CX_SHA256_SIZE; + cx_sha256_t sha2; + cx_err = cx_sha256_init_no_throw(&sha2); + if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; + cx_err = cx_hash_no_throw((cx_hash_t*) &sha2, 0, domainTag, DOMAIN_TAG_LENGTH, NULL, 0); + if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; + cx_err = cx_hash_no_throw((cx_hash_t*) &sha2, CX_LAST, message, messageLen, digest, CX_SHA256_SIZE); + if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; + *digest_size = cx_hash_get_size((cx_hash_t *) &sha2);; return zxerr_ok; } case HASH_SHA3_256: { @@ -125,10 +132,11 @@ zxerr_t digest_message(const uint8_t *message, cx_sha3_t sha3; cx_err = cx_sha3_init_no_throw(&sha3, 256); if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; + cx_err = cx_hash_no_throw((cx_hash_t*) &sha3, 0, domainTag, DOMAIN_TAG_LENGTH, NULL, 0); + if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; cx_err = cx_hash_no_throw((cx_hash_t *) &sha3, CX_LAST, message, messageLen, digest, 32); if (cx_err != CX_OK) return zxerr_invalid_crypto_settings; - zemu_log_stack("sha3_256 ready"); *digest_size = cx_hash_get_size((cx_hash_t *) &sha3); return zxerr_ok; } @@ -143,6 +151,7 @@ zxerr_t crypto_sign(const hd_path_t path, const uint16_t options, const uint8_t *message, uint16_t messageLen, + const uint8_t domainTag[DOMAIN_TAG_LENGTH], uint8_t *buffer, uint16_t bufferSize, uint16_t *sigSize) { @@ -162,6 +171,7 @@ zxerr_t crypto_sign(const hd_path_t path, CHECK_ZXERR(digest_message(message, messageLen, + domainTag, cx_hash_kind, messageDigest, sizeof(messageDigest), diff --git a/src/crypto.h b/src/crypto.h index 8a1367ae..722652ee 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -46,6 +46,7 @@ zxerr_t crypto_sign(const hd_path_t path, const uint16_t options, const uint8_t *message, uint16_t messageLen, + const uint8_t domainTag[DOMAIN_TAG_LENGTH], uint8_t *signature, uint16_t signatureMaxlen, uint16_t *sigSize);