Skip to content

Instantly share code, notes, and snippets.

@romanz
Created April 16, 2016 11:57
Show Gist options
  • Save romanz/b66f5df1ca8ef15641df8ea5bb09fd47 to your computer and use it in GitHub Desktop.
Save romanz/b66f5df1ca8ef15641df8ea5bb09fd47 to your computer and use it in GitHub Desktop.
Add GPG v2.1 support by signing message digest
diff --git a/firmware/crypto.c b/firmware/crypto.c
index 84d611d..1f94ceb 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 a9cd886..98b5b94 100644
--- a/firmware/fsm.c
+++ b/firmware/fsm.c
@@ -739,11 +739,14 @@ void fsm_msgSignIdentity(SignIdentity *msg)
}
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 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment