diff options
author | Jack Lloyd <[email protected]> | 2019-06-20 20:18:50 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2019-06-20 20:19:52 -0400 |
commit | 2b38ded27cc0f7883b8611db5b76fe677bbe2bc9 (patch) | |
tree | 5acb9418b7bbb5128913c12368a5be718648934a /src/lib/pubkey/ed25519 | |
parent | c63d42bfca3c0b40324ff597cddf60c310fe84d2 (diff) |
Add support for RFC 8032 Ed25519ph
GH #1699
Diffstat (limited to 'src/lib/pubkey/ed25519')
-rw-r--r-- | src/lib/pubkey/ed25519/ed25519.cpp | 11 | ||||
-rw-r--r-- | src/lib/pubkey/ed25519/ed25519.h | 6 | ||||
-rw-r--r-- | src/lib/pubkey/ed25519/ed25519_key.cpp | 43 |
3 files changed, 47 insertions, 13 deletions
diff --git a/src/lib/pubkey/ed25519/ed25519.cpp b/src/lib/pubkey/ed25519/ed25519.cpp index b75028041..624f82657 100644 --- a/src/lib/pubkey/ed25519/ed25519.cpp +++ b/src/lib/pubkey/ed25519/ed25519.cpp @@ -34,8 +34,9 @@ void ed25519_gen_keypair(uint8_t* pk, uint8_t* sk, const uint8_t seed[32]) } void ed25519_sign(uint8_t sig[64], - const uint8_t* m, size_t mlen, - const uint8_t* sk) + const uint8_t m[], size_t mlen, + const uint8_t sk[64], + const uint8_t domain_sep[], size_t domain_sep_len) { uint8_t az[64]; uint8_t nonce[64]; @@ -49,6 +50,7 @@ void ed25519_sign(uint8_t sig[64], az[31] &= 63; az[31] |= 64; + sha.update(domain_sep, domain_sep_len); sha.update(az + 32, 32); sha.update(m, mlen); sha.final(nonce); @@ -56,6 +58,7 @@ void ed25519_sign(uint8_t sig[64], sc_reduce(nonce); ge_scalarmult_base(sig, nonce); + sha.update(domain_sep, domain_sep_len); sha.update(sig, 32); sha.update(sk + 32, 32); sha.update(m, mlen); @@ -67,7 +70,8 @@ void ed25519_sign(uint8_t sig[64], bool ed25519_verify(const uint8_t* m, size_t mlen, const uint8_t sig[64], - const uint8_t* pk) + const uint8_t* pk, + const uint8_t domain_sep[], size_t domain_sep_len) { uint8_t h[64]; uint8_t rcheck[32]; @@ -83,6 +87,7 @@ bool ed25519_verify(const uint8_t* m, size_t mlen, return false; } + sha.update(domain_sep, domain_sep_len); sha.update(sig, 32); sha.update(pk, 32); sha.update(m, mlen); diff --git a/src/lib/pubkey/ed25519/ed25519.h b/src/lib/pubkey/ed25519/ed25519.h index 51c75e641..97ed023f2 100644 --- a/src/lib/pubkey/ed25519/ed25519.h +++ b/src/lib/pubkey/ed25519/ed25519.h @@ -99,12 +99,14 @@ void ed25519_gen_keypair(uint8_t pk[32], uint8_t sk[64], const uint8_t seed[32]) void ed25519_sign(uint8_t sig[64], const uint8_t msg[], size_t msg_len, - const uint8_t sk[64]); + const uint8_t sk[64], + const uint8_t domain_sep[], size_t domain_sep_len); bool ed25519_verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[64], - const uint8_t pk[32]); + const uint8_t pk[32], + const uint8_t domain_sep[], size_t domain_sep_len); } diff --git a/src/lib/pubkey/ed25519/ed25519_key.cpp b/src/lib/pubkey/ed25519/ed25519_key.cpp index 1de24aa26..c4b260c4c 100644 --- a/src/lib/pubkey/ed25519/ed25519_key.cpp +++ b/src/lib/pubkey/ed25519/ed25519_key.cpp @@ -122,7 +122,7 @@ class Ed25519_Pure_Verify_Operation final : public PK_Ops::Verification const std::vector<uint8_t>& pub_key = m_key.get_public_key(); BOTAN_ASSERT_EQUAL(pub_key.size(), 32, "Expected size"); - const bool ok = ed25519_verify(m_msg.data(), m_msg.size(), sig, pub_key.data()); + const bool ok = ed25519_verify(m_msg.data(), m_msg.size(), sig, pub_key.data(), nullptr, 0); m_msg.clear(); return ok; } @@ -138,9 +138,18 @@ class Ed25519_Pure_Verify_Operation final : public PK_Ops::Verification class Ed25519_Hashed_Verify_Operation final : public PK_Ops::Verification { public: - Ed25519_Hashed_Verify_Operation(const Ed25519_PublicKey& key, const std::string& hash) : m_key(key) + Ed25519_Hashed_Verify_Operation(const Ed25519_PublicKey& key, const std::string& hash, bool rfc8032) : + m_key(key) { m_hash = HashFunction::create_or_throw(hash); + + if(rfc8032) + { + m_domain_sep = { + 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64, + 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73, + 0x01, 0x00 }; + } } void update(const uint8_t msg[], size_t msg_len) override @@ -157,12 +166,13 @@ class Ed25519_Hashed_Verify_Operation final : public PK_Ops::Verification const std::vector<uint8_t>& pub_key = m_key.get_public_key(); BOTAN_ASSERT_EQUAL(pub_key.size(), 32, "Expected size"); - return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, pub_key.data()); + return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, pub_key.data(), m_domain_sep.data(), m_domain_sep.size()); } private: std::unique_ptr<HashFunction> m_hash; const Ed25519_PublicKey& m_key; + std::vector<uint8_t> m_domain_sep; }; /** @@ -183,7 +193,7 @@ class Ed25519_Pure_Sign_Operation final : public PK_Ops::Signature secure_vector<uint8_t> sign(RandomNumberGenerator&) override { secure_vector<uint8_t> sig(64); - ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data()); + ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data(), nullptr, 0); m_msg.clear(); return sig; } @@ -201,9 +211,18 @@ class Ed25519_Pure_Sign_Operation final : public PK_Ops::Signature class Ed25519_Hashed_Sign_Operation final : public PK_Ops::Signature { public: - Ed25519_Hashed_Sign_Operation(const Ed25519_PrivateKey& key, const std::string& hash) : m_key(key) + Ed25519_Hashed_Sign_Operation(const Ed25519_PrivateKey& key, const std::string& hash, bool rfc8032) : + m_key(key) { m_hash = HashFunction::create_or_throw(hash); + + if(rfc8032) + { + m_domain_sep = std::vector<uint8_t>{ + 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64, + 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73, + 0x01, 0x00 }; + } } size_t signature_length() const override { return 64; } @@ -218,13 +237,17 @@ class Ed25519_Hashed_Sign_Operation final : public PK_Ops::Signature secure_vector<uint8_t> sig(64); std::vector<uint8_t> msg_hash(m_hash->output_length()); m_hash->final(msg_hash.data()); - ed25519_sign(sig.data(), msg_hash.data(), msg_hash.size(), m_key.get_private_key().data()); + ed25519_sign(sig.data(), + msg_hash.data(), msg_hash.size(), + m_key.get_private_key().data(), + m_domain_sep.data(), m_domain_sep.size()); return sig; } private: std::unique_ptr<HashFunction> m_hash; const Ed25519_PrivateKey& m_key; + std::vector<uint8_t> m_domain_sep; }; } @@ -237,8 +260,10 @@ Ed25519_PublicKey::create_verification_op(const std::string& params, { if(params == "" || params == "Identity" || params == "Pure") return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Pure_Verify_Operation(*this)); + else if(params == "Ed25519ph") + return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, "SHA-512", true)); else - return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, params)); + return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, params, false)); } throw Provider_Not_Found(algo_name(), provider); } @@ -252,8 +277,10 @@ Ed25519_PrivateKey::create_signature_op(RandomNumberGenerator&, { if(params == "" || params == "Identity" || params == "Pure") return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Pure_Sign_Operation(*this)); + else if(params == "Ed25519ph") + return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, "SHA-512", true)); else - return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, params)); + return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, params, false)); } throw Provider_Not_Found(algo_name(), provider); } |