diff options
author | Jack Lloyd <[email protected]> | 2016-12-21 19:48:04 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-12-21 19:48:04 -0500 |
commit | 8f5089b2bb9c571e0c9620ad43465af1e8af2b11 (patch) | |
tree | b8237f37f23e5c986db55499060cf549a8942532 /src/lib | |
parent | 46bf28e0b6d9627a57862a180142fbf158f33ce7 (diff) | |
parent | 75e6d9aa7da63cf7dbf81359e350da682c8e4979 (diff) |
Merge GH #779 Add ECDH/ECIES blinding and DH small subgroup checking
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/pubkey/dl_algo/dl_algo.cpp | 16 | ||||
-rw-r--r-- | src/lib/pubkey/dl_group/dl_group.cpp | 24 | ||||
-rw-r--r-- | src/lib/pubkey/ecdh/ecdh.cpp | 20 | ||||
-rw-r--r-- | src/lib/pubkey/ecies/ecies.cpp | 13 |
4 files changed, 55 insertions, 18 deletions
diff --git a/src/lib/pubkey/dl_algo/dl_algo.cpp b/src/lib/pubkey/dl_algo/dl_algo.cpp index ac6637e29..1c4fc5177 100644 --- a/src/lib/pubkey/dl_algo/dl_algo.cpp +++ b/src/lib/pubkey/dl_algo/dl_algo.cpp @@ -63,10 +63,24 @@ DL_Scheme_PrivateKey::DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id, bool DL_Scheme_PublicKey::check_key(RandomNumberGenerator& rng, bool strong) const { - if(m_y < 2 || m_y >= group_p()) + const BigInt& p = group_p(); + + if(m_y < 2 || m_y >= p) return false; if(!m_group.verify_group(rng, strong)) return false; + + try + { + const BigInt& q = group_q(); + if(power_mod(m_y, q, p) != 1) + return false; + } + catch(const Invalid_State& e) + { + return true; + } + return true; } diff --git a/src/lib/pubkey/dl_group/dl_group.cpp b/src/lib/pubkey/dl_group/dl_group.cpp index 0f4985eb9..adf207b43 100644 --- a/src/lib/pubkey/dl_group/dl_group.cpp +++ b/src/lib/pubkey/dl_group/dl_group.cpp @@ -12,6 +12,7 @@ #include <botan/ber_dec.h> #include <botan/pem.h> #include <botan/workfactor.h> +#include <botan/pow_mod.h> namespace Botan { @@ -149,15 +150,28 @@ bool DL_Group::verify_group(RandomNumberGenerator& rng, if(m_g < 2 || m_p < 3 || m_q < 0) return false; - if((m_q != 0) && ((m_p - 1) % m_q != 0)) - return false; - const size_t prob = (strong) ? 56 : 10; + const size_t prob = (strong) ? 128 : 10; + if(m_q != 0) + { + if((m_p - 1) % m_q != 0) + { + return false; + } + if(power_mod(m_g, m_q, m_p) != 1) + { + return false; + } + if(!is_prime(m_q, rng, prob)) + { + return false; + } + } if(!is_prime(m_p, rng, prob)) + { return false; - if((m_q > 0) && !is_prime(m_q, rng, prob)) - return false; + } return true; } diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 32914be2e..0ddb39275 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -27,32 +27,38 @@ class ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { public: - ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf) : + ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : PK_Ops::Key_Agreement_with_KDF(kdf), m_curve(key.domain().get_curve()), - m_cofactor(key.domain().get_cofactor()) + m_cofactor(key.domain().get_cofactor()), + m_order(key.domain().get_order()), + m_rng(rng) { - m_l_times_priv = inverse_mod(m_cofactor, key.domain().get_order()) * key.private_value(); + m_l_times_priv = inverse_mod(m_cofactor, m_order) * key.private_value(); } secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override { PointGFp point = OS2ECP(w, w_len, m_curve); - // TODO: add blinding - PointGFp S = (m_cofactor * point) * m_l_times_priv; + PointGFp S = m_cofactor * point; + Blinded_Point_Multiply blinder(S, m_order); + S = blinder.blinded_multiply(m_l_times_priv, m_rng); BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve"); return BigInt::encode_1363(S.get_affine_x(), m_curve.get_p().bytes()); } private: const CurveGFp& m_curve; const BigInt& m_cofactor; + const BigInt& m_order; BigInt m_l_times_priv; + RandomNumberGenerator& m_rng; + }; } std::unique_ptr<PK_Ops::Key_Agreement> -ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/, +ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, const std::string& params, const std::string& provider) const { @@ -72,7 +78,7 @@ ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/, #endif if(provider == "base" || provider.empty()) - return std::unique_ptr<PK_Ops::Key_Agreement>(new ECDH_KA_Operation(*this, params)); + return std::unique_ptr<PK_Ops::Key_Agreement>(new ECDH_KA_Operation(*this, params, rng)); throw Provider_Not_Found(algo_name(), provider); } diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index 84c1a8f3f..df676cfb3 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -55,9 +55,10 @@ class ECIES_PrivateKey : public EC_PrivateKey, public PK_Key_Agreement_Key class ECIES_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { public: - ECIES_ECDH_KA_Operation(const ECIES_PrivateKey& private_key) : + ECIES_ECDH_KA_Operation(const ECIES_PrivateKey& private_key, RandomNumberGenerator& rng) : PK_Ops::Key_Agreement_with_KDF("Raw"), - m_key(private_key) + m_key(private_key), + m_rng(rng) { } @@ -65,21 +66,23 @@ class ECIES_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { const CurveGFp& curve = m_key.domain().get_curve(); PointGFp point = OS2ECP(w, w_len, curve); - PointGFp S = point * m_key.private_value(); + Blinded_Point_Multiply blinder(point, m_key.domain().get_order()); + PointGFp S = blinder.blinded_multiply(m_key.private_value(), m_rng); BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve"); return BigInt::encode_1363(S.get_affine_x(), curve.get_p().bytes()); } private: ECIES_PrivateKey m_key; + RandomNumberGenerator& m_rng; }; std::unique_ptr<PK_Ops::Key_Agreement> -ECIES_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/, +ECIES_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng, const std::string& /*params*/, const std::string& /*provider*/) const { - return std::unique_ptr<PK_Ops::Key_Agreement>(new ECIES_ECDH_KA_Operation(*this)); + return std::unique_ptr<PK_Ops::Key_Agreement>(new ECIES_ECDH_KA_Operation(*this, rng)); } /** |