aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-12-21 19:48:04 -0500
committerJack Lloyd <[email protected]>2016-12-21 19:48:04 -0500
commit8f5089b2bb9c571e0c9620ad43465af1e8af2b11 (patch)
treeb8237f37f23e5c986db55499060cf549a8942532 /src/lib
parent46bf28e0b6d9627a57862a180142fbf158f33ce7 (diff)
parent75e6d9aa7da63cf7dbf81359e350da682c8e4979 (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.cpp16
-rw-r--r--src/lib/pubkey/dl_group/dl_group.cpp24
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp20
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp13
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));
}
/**