From 2b2414cb91e11685b490d4417cf16c7d0d606181 Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Fri, 15 Apr 2016 22:04:45 +0300 Subject: [PATCH] Add GPG v2.1 support by signing message digest --- firmware/crypto.c | 10 ++++++++++ firmware/crypto.h | 2 ++ firmware/fsm.c | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/firmware/crypto.c b/firmware/crypto.c index 27e07fd..201a7c1 100644 --- a/firmware/crypto.c +++ b/firmware/crypto.c @@ -90,6 +90,16 @@ int sshMessageSign(const uint8_t *message, size_t message_len, const uint8_t *pr return ecdsa_sign(&nist256p1, privkey, message, message_len, signature + 1, NULL); } +int gpgMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, 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); +} + int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature) { SHA256_CTX ctx; diff --git a/firmware/crypto.h b/firmware/crypto.h index b9d03fd..aefdc97 100644 --- a/firmware/crypto.h +++ b/firmware/crypto.h @@ -34,6 +34,8 @@ 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 gpgMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature); + int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, 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 b3466c7..ef98363 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -731,11 +731,14 @@ void fsm_msgSignIdentity(SignIdentity *msg) memcpy(public_key, node->public_key, sizeof(public_key)); bool sign_ssh = msg->identity.has_proto && (strcmp(msg->identity.proto, "ssh") == 0); + bool sign_gpg = msg->identity.has_proto && (strcmp(msg->identity.proto, "gpg") == 0); 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); + } 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); } else { uint8_t digest[64]; sha256_Raw(msg->challenge_hidden.bytes, msg->challenge_hidden.size, digest); @@ -744,7 +747,7 @@ void fsm_msgSignIdentity(SignIdentity *msg) } if (result == 0) { - if (sign_ssh) { + if (curve != SECP256K1_NAME) { resp->has_address = false; } else { resp->has_address = true;