diff --git a/Makefile.include b/Makefile.include index 82803f5b9..782d2d59c 100644 --- a/Makefile.include +++ b/Makefile.include @@ -46,6 +46,7 @@ CFLAGS += $(OPTFLAGS) \ -I$(TOP_DIR) \ -I$(TOP_DIR)gen \ -I$(TOP_DIR)vendor/trezor-crypto \ + -I$(TOP_DIR)vendor/trezor-crypto/ed25519-donna \ -I$(TOP_DIR)vendor/trezor-qrenc ifdef APPVER diff --git a/firmware/Makefile b/firmware/Makefile index bd86a79a5..b44135d46 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -21,8 +21,10 @@ OBJS += debug.o OBJS += ../vendor/trezor-crypto/bignum.o OBJS += ../vendor/trezor-crypto/ecdsa.o +OBJS += ../vendor/trezor-crypto/curves.o OBJS += ../vendor/trezor-crypto/secp256k1.o OBJS += ../vendor/trezor-crypto/nist256p1.o +OBJS += ../vendor/trezor-crypto/ed25519-donna/ed25519.o OBJS += ../vendor/trezor-crypto/hmac.o OBJS += ../vendor/trezor-crypto/bip32.o OBJS += ../vendor/trezor-crypto/bip39.o @@ -54,3 +56,5 @@ CFLAGS += -DQR_MAX_VERSION=0 CFLAGS += -DDEBUG_LINK=0 CFLAGS += -DDEBUG_LOG=0 CFLAGS += -DSCM_REVISION='"$(shell git rev-parse HEAD | sed 's:\(..\):\\x\1:g')"' +CFLAGS += -DED25519_CUSTOMRANDOM=1 +CFLAGS += -DED25519_CUSTOMHASH=1 diff --git a/firmware/crypto.c b/firmware/crypto.c index 201a7c128..b57a2828d 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -25,8 +25,8 @@ #include "hmac.h" #include "bip32.h" #include "layout.h" +#include "curves.h" #include "secp256k1.h" -#include "nist256p1.h" uint32_t ser_length(uint32_t len, uint8_t *out) { @@ -84,23 +84,23 @@ uint32_t deser_length(const uint8_t *in, uint32_t *out) return 1 + 8; } -int sshMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature) +int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) { signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes - return ecdsa_sign(&nist256p1, privkey, message, message_len, signature + 1, NULL); + return hdnode_sign(node, message, message_len, signature + 1, NULL); } -int gpgMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature) +int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) { // GPG should sign a SHA256 digest of the original message. if (message_len != 32) { return 1; } signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes - return ecdsa_sign_digest(&nist256p1, privkey, message, signature + 1, NULL); + return hdnode_sign_digest(node, message, signature + 1, NULL); } -int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature) +int cryptoMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature) { SHA256_CTX ctx; sha256_Init(&ctx); @@ -113,7 +113,7 @@ int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t sha256_Final(hash, &ctx); sha256_Raw(hash, 32, hash); uint8_t pby; - int result = ecdsa_sign_digest(&secp256k1, privkey, hash, signature + 1, &pby); + int result = hdnode_sign_digest(node, hash, signature + 1, &pby); if (result == 0) { signature[0] = 27 + pby + 4; } @@ -183,11 +183,13 @@ int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_ 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) { if (privkey && address_raw) { // signing == true + HDNode node; payload[0] = display_only ? 0x81 : 0x01; uint32_t l = ser_length(msg_size, payload + 1); memcpy(payload + 1 + l, msg, msg_size); memcpy(payload + 1 + l + msg_size, address_raw, 21); - if (cryptoMessageSign(msg, msg_size, privkey, payload + 1 + l + msg_size + 21) != 0) { + hdnode_from_xprv(0, 0, 0, privkey, privkey, SECP256K1_NAME, &node); + if (cryptoMessageSign(&node, msg, msg_size, payload + 1 + l + msg_size + 21) != 0) { return 1; } *payload_len = 1 + l + msg_size + 21 + 65; diff --git a/firmware/crypto.h b/firmware/crypto.h index aefdc97a1..efde2265d 100644 --- a/firmware/crypto.h +++ b/firmware/crypto.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include "types.pb.h" @@ -32,11 +33,11 @@ uint32_t ser_length(uint32_t len, uint8_t *out); uint32_t ser_length_hash(SHA256_CTX *ctx, uint32_t len); -int sshMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature); +int sshMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature); -int gpgMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature); +int gpgMessageSign(const HDNode *node, const uint8_t *message, size_t message_len, uint8_t *signature); -int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature); +int cryptoMessageSign(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); diff --git a/firmware/fsm.c b/firmware/fsm.c index 64e0dbf58..bf79eb59c 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -44,8 +44,8 @@ #include "base58.h" #include "bip39.h" #include "ripemd160.h" +#include "curves.h" #include "secp256k1.h" -#include "nist256p1.h" // message methods @@ -643,7 +643,7 @@ void fsm_msgSignMessage(SignMessage *msg) if (!node) return; layoutProgressSwipe("Signing", 0); - if (cryptoMessageSign(msg->message.bytes, msg->message.size, node->private_key, resp->signature.bytes) == 0) { + if (cryptoMessageSign(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); @@ -730,14 +730,14 @@ void fsm_msgSignIdentity(SignIdentity *msg) int result = 0; layoutProgressSwipe("Signing", 0); if (sign_ssh) { // SSH does not sign visual challenge - result = sshMessageSign(msg->challenge_hidden.bytes, msg->challenge_hidden.size, node->private_key, resp->signature.bytes); + result = sshMessageSign(node, msg->challenge_hidden.bytes, msg->challenge_hidden.size, resp->signature.bytes); } else if (sign_gpg) { // GPG should sign a message digest - result = gpgMessageSign(msg->challenge_hidden.bytes, msg->challenge_hidden.size, node->private_key, resp->signature.bytes); + result = gpgMessageSign(node, msg->challenge_hidden.bytes, msg->challenge_hidden.size, resp->signature.bytes); } else { 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(digest, 64, node->private_key, resp->signature.bytes); + result = cryptoMessageSign(node, digest, 64, resp->signature.bytes); } if (result == 0) { diff --git a/firmware/storage.c b/firmware/storage.c index 19e70dd2d..4f5fb9e71 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -31,7 +31,7 @@ #include "pbkdf2.h" #include "bip32.h" #include "bip39.h" -#include "secp256k1.h" +#include "curves.h" #include "util.h" #include "memory.h" #include "rng.h" diff --git a/vendor/trezor-crypto b/vendor/trezor-crypto index de30ffbf9..55edf71e2 160000 --- a/vendor/trezor-crypto +++ b/vendor/trezor-crypto @@ -1 +1 @@ -Subproject commit de30ffbf9a68bfd6f2fb3633f855998c8e375628 +Subproject commit 55edf71e274c4b803f9b0acb2847df51532fa302