From 7c91ef340a40fc163cda1e1a86db6b044d96e165 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 5 Sep 2017 17:49:25 -0400 Subject: Support arbitrary hashes for SM2 encryption This is a contribution from Ribose Inc. --- src/lib/pubkey/sm2/sm2_enc.cpp | 29 +++++++++++++++++------------ src/tests/test_sm2.cpp | 6 +++--- 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp index a832dd1ac..988db1ee9 100644 --- a/src/lib/pubkey/sm2/sm2_enc.cpp +++ b/src/lib/pubkey/sm2/sm2_enc.cpp @@ -43,11 +43,12 @@ namespace { class SM2_Encryption_Operation : public PK_Ops::Encryption { public: - SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key) : + SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, const std::string& kdf_hash) : m_p_bytes(key.domain().get_curve().get_p().bytes()), m_order(key.domain().get_order()), m_base_point(key.domain().get_base_point(), m_order), - m_public_point(key.public_point(), m_order) + m_public_point(key.public_point(), m_order), + m_kdf_hash(kdf_hash) {} size_t max_input_bits() const override @@ -60,8 +61,8 @@ class SM2_Encryption_Operation : public PK_Ops::Encryption size_t msg_len, RandomNumberGenerator& rng) override { - std::unique_ptr hash = HashFunction::create("SM3"); - std::unique_ptr kdf = KDF::create("KDF2(SM3)"); + std::unique_ptr hash = HashFunction::create_or_throw(m_kdf_hash); + std::unique_ptr kdf = KDF::create_or_throw("KDF2(" + m_kdf_hash + ")"); secure_vector ciphertext; ciphertext.reserve(1 + m_p_bytes*2 + msg_len + hash->output_length()); @@ -115,15 +116,18 @@ class SM2_Encryption_Operation : public PK_Ops::Encryption const BigInt& m_order; Blinded_Point_Multiply m_base_point; Blinded_Point_Multiply m_public_point; + const std::string m_kdf_hash; }; class SM2_Decryption_Operation : public PK_Ops::Decryption { public: SM2_Decryption_Operation(const SM2_Encryption_PrivateKey& key, - RandomNumberGenerator& rng) : + RandomNumberGenerator& rng, + const std::string& kdf_hash) : m_key(key), - m_rng(rng) + m_rng(rng), + m_kdf_hash(kdf_hash) {} secure_vector decrypt(uint8_t& valid_mask, @@ -135,7 +139,8 @@ class SM2_Decryption_Operation : public PK_Ops::Decryption valid_mask = 0; - std::unique_ptr hash = HashFunction::create("SM3"); + std::unique_ptr hash = HashFunction::create_or_throw(m_kdf_hash); + std::unique_ptr kdf = KDF::create_or_throw("KDF2(" + m_kdf_hash + ")"); // Too short to be valid - no timing problem from early return if(ciphertext_len < 1 + p_bytes*2 + hash->output_length()) @@ -174,7 +179,6 @@ class SM2_Decryption_Operation : public PK_Ops::Decryption const size_t msg_len = ciphertext_len - (1 + p_bytes*2 + hash->output_length()); - std::unique_ptr kdf = KDF::create("KDF2(SM3)"); const secure_vector kdf_output = kdf->derive_key(msg_len, kdf_input.data(), kdf_input.size()); @@ -196,6 +200,7 @@ class SM2_Decryption_Operation : public PK_Ops::Decryption const SM2_Encryption_PrivateKey& m_key; RandomNumberGenerator& m_rng; const std::string m_ident; + const std::string m_kdf_hash; }; } @@ -207,8 +212,8 @@ SM2_Encryption_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/, { if(provider == "base" || provider.empty()) { - if(params == "") - return std::unique_ptr(new SM2_Encryption_Operation(*this)); + const std::string kdf_hash = (params.empty() ? "SM3" : params); + return std::unique_ptr(new SM2_Encryption_Operation(*this, kdf_hash)); } throw Provider_Not_Found(algo_name(), provider); @@ -221,8 +226,8 @@ SM2_Encryption_PrivateKey::create_decryption_op(RandomNumberGenerator& rng, { if(provider == "base" || provider.empty()) { - if(params == "") - return std::unique_ptr(new SM2_Decryption_Operation(*this, rng)); + const std::string kdf_hash = (params.empty() ? "SM3" : params); + return std::unique_ptr(new SM2_Decryption_Operation(*this, rng, kdf_hash)); } throw Provider_Not_Found(algo_name(), provider); diff --git a/src/tests/test_sm2.cpp b/src/tests/test_sm2.cpp index 88d872435..7172605bf 100644 --- a/src/tests/test_sm2.cpp +++ b/src/tests/test_sm2.cpp @@ -71,11 +71,11 @@ class SM2_Encryption_KAT_Tests : public PK_Encryption_Decryption_Test "SM2", "pubkey/sm2_enc.vec", "P,A,B,xG,yG,Order,Cofactor,Msg,x,Nonce,Ciphertext", - "") {} + "Hash") {} - virtual std::string default_padding(const VarMap&) const override + virtual std::string default_padding(const VarMap& vars) const override { - return ""; + return get_opt_str(vars, "Hash", "SM3"); } Botan::RandomNumberGenerator* test_rng(const std::vector& nonce) const override -- cgit v1.2.3