diff options
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 23 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.h | 11 | ||||
-rw-r--r-- | src/lib/pubkey/ecdh/ecdh.cpp | 24 | ||||
-rw-r--r-- | src/lib/pubkey/ecdsa/ecdsa.cpp | 6 | ||||
-rw-r--r-- | src/lib/pubkey/ecgdsa/ecgdsa.cpp | 5 | ||||
-rw-r--r-- | src/lib/pubkey/ecies/ecies.cpp | 18 | ||||
-rw-r--r-- | src/lib/pubkey/eckcdsa/eckcdsa.cpp | 5 | ||||
-rw-r--r-- | src/lib/pubkey/gost_3410/gost_3410.cpp | 5 | ||||
-rw-r--r-- | src/lib/pubkey/sm2/sm2.cpp | 5 | ||||
-rw-r--r-- | src/lib/pubkey/sm2/sm2_enc.cpp | 29 |
10 files changed, 87 insertions, 44 deletions
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index 771bd4b0f..a41a59b66 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -17,6 +17,10 @@ #include <botan/mutex.h> #include <vector> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#endif + namespace Botan { class EC_Group_Data final @@ -36,10 +40,14 @@ class EC_Group_Data final m_order(order), m_cofactor(cofactor), m_mod_order(order), + m_base_mult(m_base_point, 5), m_oid(oid), m_p_bits(p.bits()), m_order_bits(order.bits()) { +#if defined(BOTAN_HAS_SYSTEM_RNG) + m_base_mult.randomize(system_rng()); +#endif } bool match(const BigInt& p, const BigInt& a, const BigInt& b, @@ -76,12 +84,20 @@ class EC_Group_Data final return m_mod_order.multiply(x, y); } + PointGFp blinded_base_point_multiply(const BigInt& k, + RandomNumberGenerator& rng, + std::vector<BigInt>& ws) const + { + return m_base_mult.mul(k, m_order, rng, ws); + } + private: CurveGFp m_curve; PointGFp m_base_point; BigInt m_order; BigInt m_cofactor; Modular_Reducer m_mod_order; + PointGFp_Blinded_Multiplier m_base_mult; OID m_oid; size_t m_p_bits; size_t m_order_bits; @@ -429,6 +445,13 @@ PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const Big return multi_exponentiate(get_base_point(), x, pt, y); } +PointGFp EC_Group::blinded_base_point_multiply(const BigInt& k, + RandomNumberGenerator& rng, + std::vector<BigInt>& ws) const + { + return data().blinded_base_point_multiply(k, rng, ws); + } + PointGFp EC_Group::zero_point() const { return PointGFp(data().curve()); diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h index a60c71157..0e5f352f2 100644 --- a/src/lib/pubkey/ec_group/ec_group.h +++ b/src/lib/pubkey/ec_group/ec_group.h @@ -206,12 +206,21 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final PointGFp point(const BigInt& x, const BigInt& y) const; /** - * Multi exponentiate + * Multi exponentiate. Not constant time. * @return base_point*x + pt*y */ PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const; /** + * Blinded point multiplication, attempts resistance to side channels + * @param k the scalar + * @param rng a random number generator + * @param ws a temp workspace + * @return base_point*k + */ + PointGFp blinded_base_point_multiply(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const; + + /** * Return the zero (or infinite) point on this curve */ PointGFp zero_point() const; diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 1850696e1..4989fa0a5 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -28,26 +28,30 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : PK_Ops::Key_Agreement_with_KDF(kdf), - m_domain(key.domain()), + m_group(key.domain()), m_rng(rng) { - m_l_times_priv = inverse_mod(m_domain.get_cofactor(), m_domain.get_order()) * key.private_value(); + m_l_times_priv = inverse_mod(m_group.get_cofactor(), m_group.get_order()) * key.private_value(); } secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override { - PointGFp point = m_domain.OS2ECP(w, w_len); - PointGFp S = m_domain.get_cofactor() * point; - Blinded_Point_Multiply blinder(S, m_domain.get_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_domain.get_p_bytes()); + PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len); + input_point.randomize_repr(m_rng); + + PointGFp_Blinded_Multiplier blinder(input_point, m_ws); + + const PointGFp S = blinder.mul(m_l_times_priv, m_group.get_order(), m_rng, m_ws); + + if(S.on_the_curve() == false) + throw Internal_Error("ECDH agreed value was not on the curve"); + return BigInt::encode_1363(S.get_affine_x(), m_group.get_p_bytes()); } private: - const EC_Group& m_domain; + const EC_Group m_group; BigInt m_l_times_priv; RandomNumberGenerator& m_rng; - + std::vector<BigInt> m_ws; }; } diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 12ccd9608..57bc197c5 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -53,7 +53,6 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_group(ecdsa.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), m_x(ecdsa.private_value()) { #if defined(BOTAN_HAS_RFC6979_GENERATOR) @@ -68,12 +67,13 @@ class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; const BigInt& m_x; #if defined(BOTAN_HAS_RFC6979_GENERATOR) std::string m_rfc6979_hash; #endif + + std::vector<BigInt> m_ws; }; secure_vector<uint8_t> @@ -89,7 +89,7 @@ ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, #endif const BigInt k_inv = inverse_mod(k, m_group.get_order()); - const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws); const BigInt r = m_group.mod_order(k_times_P.get_affine_x()); const BigInt s = m_group.multiply_mod_order(k_inv, mul_add(m_x, r, m)); diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index f8e5744d9..6cbd3453b 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -38,7 +38,6 @@ class ECGDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_group(ecgdsa.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), m_x(ecgdsa.private_value()) { } @@ -50,8 +49,8 @@ class ECGDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; const BigInt& m_x; + std::vector<BigInt> m_ws; }; secure_vector<uint8_t> @@ -62,7 +61,7 @@ ECGDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, BigInt k = BigInt::random_integer(rng, 1, m_group.get_order()); - const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws); const BigInt r = m_group.mod_order(k_times_P.get_affine_x()); const BigInt s = m_group.multiply_mod_order(m_x, mul_sub(k, r, m)); diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index cd09b4c52..1120a850a 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -66,16 +66,24 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override { - PointGFp point = m_key.domain().OS2ECP(w, w_len); - 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(), m_key.domain().get_p_bytes()); + const EC_Group& group = m_key.domain(); + + PointGFp input_point = group.OS2ECP(w, w_len); + input_point.randomize_repr(m_rng); + + PointGFp_Blinded_Multiplier blinder(input_point, m_ws); + + const PointGFp S = blinder.mul(m_key.private_value(), group.get_order(), m_rng, m_ws); + + if(S.on_the_curve() == false) + throw Internal_Error("ECDH agreed value was not on the curve"); + return BigInt::encode_1363(S.get_affine_x(), group.get_p_bytes()); } private: ECIES_PrivateKey m_key; RandomNumberGenerator& m_rng; + std::vector<BigInt> m_ws; }; std::unique_ptr<PK_Ops::Key_Agreement> diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp index 743d5ab95..be721a6b6 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -45,7 +45,6 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_group(eckcdsa.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), m_x(eckcdsa.private_value()), m_prefix() { @@ -68,9 +67,9 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; const BigInt& m_x; secure_vector<uint8_t> m_prefix; + std::vector<BigInt> m_ws; }; secure_vector<uint8_t> @@ -78,7 +77,7 @@ ECKCDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t, RandomNumberGenerator& rng) { const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order()); - const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws); const BigInt k_times_P_x = k_times_P.get_affine_x(); secure_vector<uint8_t> to_be_hashed(k_times_P_x.bytes()); diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index 760e667aa..79d3f204d 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -101,7 +101,6 @@ class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_group(gost_3410.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), m_x(gost_3410.private_value()) {} @@ -112,8 +111,8 @@ class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; const BigInt& m_x; + std::vector<BigInt> m_ws; }; secure_vector<uint8_t> @@ -133,7 +132,7 @@ GOST_3410_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, if(e == 0) e = 1; - const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws); BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve"); const BigInt r = m_group.mod_order(k_times_P.get_affine_x()); diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp index 2af888bbc..9ef30d9bf 100644 --- a/src/lib/pubkey/sm2/sm2.cpp +++ b/src/lib/pubkey/sm2/sm2.cpp @@ -83,7 +83,6 @@ class SM2_Signature_Operation final : public PK_Ops::Signature const std::string& ident, const std::string& hash) : m_group(sm2.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), m_x(sm2.private_value()), m_da_inv(sm2.get_da_inv()), m_hash(HashFunction::create_or_throw(hash)) @@ -102,12 +101,12 @@ class SM2_Signature_Operation final : public PK_Ops::Signature private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; const BigInt& m_x; const BigInt& m_da_inv; std::vector<uint8_t> m_za; std::unique_ptr<HashFunction> m_hash; + std::vector<BigInt> m_ws; }; secure_vector<uint8_t> @@ -115,7 +114,7 @@ SM2_Signature_Operation::sign(RandomNumberGenerator& rng) { const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order()); - const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); + const PointGFp k_times_P = m_group.blinded_base_point_multiply(k, rng, m_ws); const BigInt e = BigInt::decode(m_hash->final()); const BigInt r = m_group.mod_order(k_times_P.get_affine_x() + e); diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp index 462c4b968..b0d773635 100644 --- a/src/lib/pubkey/sm2/sm2_enc.cpp +++ b/src/lib/pubkey/sm2/sm2_enc.cpp @@ -47,8 +47,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption public: SM2_Encryption_Operation(const SM2_Encryption_PublicKey& key, const std::string& kdf_hash) : m_group(key.domain()), - m_base_point(m_group.get_base_point(), m_group.get_order()), - m_public_point(key.public_point(), m_group.get_order()), + m_mul_public_point(key.public_point()), m_kdf_hash(kdf_hash) {} @@ -69,7 +68,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption const BigInt k = BigInt::random_integer(rng, 1, m_group.get_order()); - const PointGFp C1 = m_base_point.blinded_multiply(k, rng); + const PointGFp C1 = m_group.blinded_base_point_multiply(k, rng, m_ws); const BigInt x1 = C1.get_affine_x(); const BigInt y1 = C1.get_affine_y(); std::vector<uint8_t> x1_bytes(p_bytes); @@ -77,7 +76,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption BigInt::encode_1363(x1_bytes.data(), x1_bytes.size(), x1); BigInt::encode_1363(y1_bytes.data(), y1_bytes.size(), y1); - const PointGFp kPB = m_public_point.blinded_multiply(k, rng); + const PointGFp kPB = m_mul_public_point.mul(k, m_group.get_order(), rng, m_ws); const BigInt x2 = kPB.get_affine_x(); const BigInt y2 = kPB.get_affine_y(); @@ -114,9 +113,9 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption private: const EC_Group m_group; - Blinded_Point_Multiply m_base_point; - Blinded_Point_Multiply m_public_point; + PointGFp_Blinded_Multiplier m_mul_public_point; const std::string m_kdf_hash; + std::vector<BigInt> m_ws; }; class SM2_Decryption_Operation final : public PK_Ops::Decryption @@ -134,8 +133,9 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption const uint8_t ciphertext[], size_t ciphertext_len) override { - const BigInt& cofactor = m_key.domain().get_cofactor(); - const size_t p_bytes = m_key.domain().get_p_bytes(); + const EC_Group& group = m_key.domain(); + const BigInt& cofactor = group.get_cofactor(); + const size_t p_bytes = group.get_p_bytes(); valid_mask = 0x00; @@ -160,18 +160,20 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption .end_cons() .verify_end(); - const PointGFp C1 = m_key.domain().point(x1, y1); + PointGFp C1 = group.point(x1, y1); if(!C1.on_the_curve()) return secure_vector<uint8_t>(); - Blinded_Point_Multiply C1_mul(C1, m_key.domain().get_order()); - - if(cofactor > 1 && C1_mul.blinded_multiply(cofactor, m_rng).is_zero()) + if(cofactor > 1 && (C1 * cofactor).is_zero()) { return secure_vector<uint8_t>(); } - const PointGFp dbC1 = C1_mul.blinded_multiply(m_key.private_value(), m_rng); + C1.randomize_repr(m_rng); + + PointGFp_Blinded_Multiplier C1_mul(C1); + + const PointGFp dbC1 = C1_mul.mul(m_key.private_value(), group.get_order(), m_rng, m_ws); const BigInt x2 = dbC1.get_affine_x(); const BigInt y2 = dbC1.get_affine_y(); @@ -205,6 +207,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption const SM2_Encryption_PrivateKey& m_key; RandomNumberGenerator& m_rng; const std::string m_kdf_hash; + std::vector<BigInt> m_ws; }; } |