diff options
Diffstat (limited to 'src/lib/pubkey')
25 files changed, 806 insertions, 693 deletions
diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp index 7a39db134..8fdd5b2c6 100644 --- a/src/lib/pubkey/curve25519/curve25519.cpp +++ b/src/lib/pubkey/curve25519/curve25519.cpp @@ -5,6 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/curve25519.h> #include <botan/ber_dec.h> #include <botan/der_enc.h> @@ -108,8 +109,33 @@ bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const secure_vector<byte> Curve25519_PrivateKey::agree(const byte w[], size_t w_len) const { size_check(w_len, "public value"); - return curve25519(m_private, w); } +namespace { + +/** +* Curve25519 operation +*/ +class Curve25519_KA_Operation : public PK_Ops::Key_Agreement + { + public: + typedef Curve25519_PrivateKey Key_Type; + + Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string&) : + m_key(key) {} + + secure_vector<byte> agree(const byte w[], size_t w_len) + { + return m_key.agree(w, w_len); + } + private: + const Curve25519_PrivateKey& m_key; + }; + +BOTAN_REGISTER_PK_KEY_AGREE_OP("Curve25519", Curve25519_KA_Operation); + +} + + } diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index 2baf0af26..849940505 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -9,7 +9,6 @@ #define BOTAN_CURVE_25519_H__ #include <botan/pk_keys.h> -#include <botan/pk_ops.h> namespace Botan { @@ -65,22 +64,6 @@ class BOTAN_DLL Curve25519_PrivateKey : public Curve25519_PublicKey, secure_vector<byte> m_private; }; -/** -* Curve25519 operation -*/ -class BOTAN_DLL Curve25519_KA_Operation : public PK_Ops::Key_Agreement - { - public: - Curve25519_KA_Operation(const Curve25519_PrivateKey& key) : m_key(key) {} - - secure_vector<byte> agree(const byte w[], size_t w_len) - { - return m_key.agree(w, w_len); - } - private: - const Curve25519_PrivateKey& m_key; - }; - /* * The types above are just wrappers for curve25519_donna, plus defining * encodings for public and private keys. diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp index b5fd4e643..8f44895ae 100644 --- a/src/lib/pubkey/dh/dh.cpp +++ b/src/lib/pubkey/dh/dh.cpp @@ -5,9 +5,17 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/dh.h> -#include <botan/numthry.h> #include <botan/workfactor.h> +#include <botan/pow_mod.h> +#include <botan/blinding.h> + +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#else + #include <botan/auto_rng.h> +#endif namespace Botan { @@ -75,10 +83,33 @@ std::vector<byte> DH_PrivateKey::public_value() const return DH_PublicKey::public_value(); } -DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh, - RandomNumberGenerator& rng) : +namespace { + +/** +* DH operation +*/ +class DH_KA_Operation : public PK_Ops::Key_Agreement + { + public: + typedef DH_PrivateKey Key_Type; + DH_KA_Operation(const DH_PrivateKey& key, const std::string&); + + secure_vector<byte> agree(const byte w[], size_t w_len); + private: + const BigInt& p; + + Fixed_Exponent_Power_Mod powermod_x_p; + Blinder blinder; + }; + +DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh, const std::string&) : p(dh.group_p()), powermod_x_p(dh.get_x(), p) { +#if defined(BOTAN_HAS_SYSTEM_RNG) + auto& rng = system_rng(); +#else + AutoSeeded_RNG rng; +#endif BigInt k(rng, p.bits() - 1); blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p); } @@ -96,3 +127,7 @@ secure_vector<byte> DH_KA_Operation::agree(const byte w[], size_t w_len) } } + +BOTAN_REGISTER_PK_KEY_AGREE_OP("DH", DH_KA_Operation); + +} diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index 3fa4fe694..32ca21440 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -9,9 +9,6 @@ #define BOTAN_DIFFIE_HELLMAN_H__ #include <botan/dl_algo.h> -#include <botan/pow_mod.h> -#include <botan/blinding.h> -#include <botan/pk_ops.h> namespace Botan { @@ -72,23 +69,6 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, const BigInt& x = 0); }; -/** -* DH operation -*/ -class BOTAN_DLL DH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - DH_KA_Operation(const DH_PrivateKey& key, - RandomNumberGenerator& rng); - - secure_vector<byte> agree(const byte w[], size_t w_len); - private: - const BigInt& p; - - Fixed_Exponent_Power_Mod powermod_x_p; - Blinder blinder; - }; - } #endif diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index dcb8f2a64..ca5e93f4e 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -5,9 +5,11 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/dsa.h> -#include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/pow_mod.h> +#include <botan/reducer.h> #include <botan/rfc6979.h> #include <future> @@ -67,15 +69,37 @@ bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } -DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa, - const std::string& emsa) : - q(dsa.group_q()), - x(dsa.get_x()), - powermod_g_p(dsa.group_g(), dsa.group_p()), - mod_q(dsa.group_q()), - m_hash(hash_for_deterministic_signature(emsa)) +namespace { + +/** +* Object that can create a DSA signature +*/ +class DSA_Signature_Operation : public PK_Ops::Signature { - } + public: + typedef DSA_PrivateKey Key_Type; + DSA_Signature_Operation(const DSA_PrivateKey& dsa, const std::string& emsa) : + q(dsa.group_q()), + x(dsa.get_x()), + powermod_g_p(dsa.group_g(), dsa.group_p()), + mod_q(dsa.group_q()), + m_hash(hash_for_deterministic_signature(emsa)) + { + } + + size_t message_parts() const override { return 2; } + size_t message_part_size() const override { return q.bytes(); } + size_t max_input_bits() const override { return q.bits(); } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng) override; + private: + const BigInt& q; + const BigInt& x; + Fixed_Base_Power_Mod powermod_g_p; + Modular_Reducer mod_q; + std::string m_hash; + }; secure_vector<byte> DSA_Signature_Operation::sign(const byte msg[], size_t msg_len, @@ -105,14 +129,38 @@ DSA_Signature_Operation::sign(const byte msg[], size_t msg_len, return output; } -DSA_Verification_Operation::DSA_Verification_Operation(const DSA_PublicKey& dsa) : - q(dsa.group_q()), y(dsa.get_y()) +/** +* Object that can verify a DSA signature +*/ +class DSA_Verification_Operation : public PK_Ops::Verification { - powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p()); - powermod_y_p = Fixed_Base_Power_Mod(y, dsa.group_p()); - mod_p = Modular_Reducer(dsa.group_p()); - mod_q = Modular_Reducer(dsa.group_q()); - } + public: + typedef DSA_PublicKey Key_Type; + DSA_Verification_Operation(const DSA_PublicKey& dsa, + const std::string&) : + q(dsa.group_q()), y(dsa.get_y()) + { + powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p()); + powermod_y_p = Fixed_Base_Power_Mod(y, dsa.group_p()); + mod_p = Modular_Reducer(dsa.group_p()); + mod_q = Modular_Reducer(dsa.group_q()); + } + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return q.bytes(); } + size_t max_input_bits() const { return q.bits(); } + + bool with_recovery() const override { return false; } + + bool verify(const byte msg[], size_t msg_len, + const byte sig[], size_t sig_len) override; + private: + const BigInt& q; + const BigInt& y; + + Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; + Modular_Reducer mod_p, mod_q; + }; bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len, const byte sig[], size_t sig_len) @@ -140,4 +188,9 @@ bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len, return (mod_q.reduce(s) == r); } +BOTAN_REGISTER_PK_SIGNATURE_OP("DSA", DSA_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("DSA", DSA_Verification_Operation); + +} + } diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index 67ac26dec..294774bf0 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -9,9 +9,6 @@ #define BOTAN_DSA_H__ #include <botan/dl_algo.h> -#include <botan/pk_ops.h> -#include <botan/reducer.h> -#include <botan/pow_mod.h> namespace Botan { @@ -57,52 +54,6 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, bool check_key(RandomNumberGenerator& rng, bool strong) const; }; -/** -* Object that can create a DSA signature -*/ -class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature - { - public: - DSA_Signature_Operation(const DSA_PrivateKey& dsa, const std::string& hash); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - std::string m_hash; - }; - -/** -* Object that can verify a DSA signature -*/ -class BOTAN_DLL DSA_Verification_Operation : public PK_Ops::Verification - { - public: - DSA_Verification_Operation(const DSA_PublicKey& dsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return q.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - } #endif diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 418240a4c..3b0502a36 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -7,17 +7,34 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/ecdh.h> namespace Botan { -ECDH_KA_Operation::ECDH_KA_Operation(const ECDH_PrivateKey& key) : - curve(key.domain().get_curve()), - cofactor(key.domain().get_cofactor()) +namespace { + +/** +* ECDH operation +*/ +class ECDH_KA_Operation : public PK_Ops::Key_Agreement { - l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * - key.private_value(); - } + public: + typedef ECDH_PrivateKey Key_Type; + + ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string&) : + curve(key.domain().get_curve()), + cofactor(key.domain().get_cofactor()) + { + l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * key.private_value(); + } + + secure_vector<byte> agree(const byte w[], size_t w_len); + private: + const CurveGFp& curve; + const BigInt& cofactor; + BigInt l_times_priv; + }; secure_vector<byte> ECDH_KA_Operation::agree(const byte w[], size_t w_len) { @@ -33,3 +50,7 @@ secure_vector<byte> ECDH_KA_Operation::agree(const byte w[], size_t w_len) } } + +BOTAN_REGISTER_PK_KEY_AGREE_OP("ECDH", ECDH_KA_Operation); + +} diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index 6dfa4efe6..1e806f119 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -11,7 +11,6 @@ #define BOTAN_ECDH_KEY_H__ #include <botan/ecc_key.h> -#include <botan/pk_ops.h> namespace Botan { @@ -87,21 +86,6 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, { return ECDH_PublicKey::public_value(); } }; -/** -* ECDH operation -*/ -class BOTAN_DLL ECDH_KA_Operation : public PK_Ops::Key_Agreement - { - public: - ECDH_KA_Operation(const ECDH_PrivateKey& key); - - secure_vector<byte> agree(const byte w[], size_t w_len); - private: - const CurveGFp& curve; - const BigInt& cofactor; - BigInt l_times_priv; - }; - } #endif diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 1b7318f1b..6b8e5fa67 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -7,7 +7,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/ecdsa.h> +#include <botan/reducer.h> #include <botan/keypair.h> #include <botan/rfc6979.h> @@ -25,14 +27,40 @@ bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng, return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } -ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) : - base_point(ecdsa.domain().get_base_point()), - order(ecdsa.domain().get_order()), - x(ecdsa.private_value()), - mod_order(order), - m_hash(hash_for_deterministic_signature(emsa)) +namespace { + +/** +* ECDSA signature operation +*/ +class ECDSA_Signature_Operation : public PK_Ops::Signature { - } + public: + typedef ECDSA_PrivateKey Key_Type; + + ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, + const std::string& emsa) : + base_point(ecdsa.domain().get_base_point()), + order(ecdsa.domain().get_order()), + x(ecdsa.private_value()), + mod_order(order), + m_hash(hash_for_deterministic_signature(emsa)) + { + } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng); + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return order.bytes(); } + size_t max_input_bits() const { return order.bits(); } + + private: + const PointGFp& base_point; + const BigInt& order; + const BigInt& x; + Modular_Reducer mod_order; + std::string m_hash; + }; secure_vector<byte> ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len, @@ -56,12 +84,34 @@ ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len, return output; } -ECDSA_Verification_Operation::ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa) : - base_point(ecdsa.domain().get_base_point()), - public_point(ecdsa.public_point()), - order(ecdsa.domain().get_order()) +/** +* ECDSA verification operation +*/ +class ECDSA_Verification_Operation : public PK_Ops::Verification { - } + public: + typedef ECDSA_PublicKey Key_Type; + ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, + const std::string&) : + base_point(ecdsa.domain().get_base_point()), + public_point(ecdsa.public_point()), + order(ecdsa.domain().get_order()) + { + } + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return order.bytes(); } + size_t max_input_bits() const { return order.bits(); } + + bool with_recovery() const { return false; } + + bool verify(const byte msg[], size_t msg_len, + const byte sig[], size_t sig_len); + private: + const PointGFp& base_point; + const PointGFp& public_point; + const BigInt& order; + }; bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, const byte sig[], size_t sig_len) @@ -88,4 +138,9 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, return (R.get_affine_x() % order == r); } +BOTAN_REGISTER_PK_SIGNATURE_OP("ECDSA", ECDSA_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("ECDSA", ECDSA_Verification_Operation); + +} + } diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index c0245e8bc..91ddb500d 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -11,8 +11,6 @@ #define BOTAN_ECDSA_KEY_H__ #include <botan/ecc_key.h> -#include <botan/reducer.h> -#include <botan/pk_ops.h> namespace Botan { @@ -89,52 +87,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, bool check_key(RandomNumberGenerator& rng, bool) const; }; -/** -* ECDSA signature operation -*/ -class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature - { - public: - ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, - const std::string& hash); - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - Modular_Reducer mod_order; - std::string m_hash; - }; - -/** -* ECDSA verification operation -*/ -class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification - { - public: - ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - } #endif diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp index b3bd23c48..d59fc1f6b 100644 --- a/src/lib/pubkey/elgamal/elgamal.cpp +++ b/src/lib/pubkey/elgamal/elgamal.cpp @@ -5,11 +5,19 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/elgamal.h> -#include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/reducer.h> +#include <botan/blinding.h> #include <botan/workfactor.h> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#else + #include <botan/auto_rng.h> +#endif + namespace Botan { /* @@ -66,7 +74,30 @@ bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng, return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)"); } -ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key) +namespace { + +/** +* ElGamal encryption operation +*/ +class ElGamal_Encryption_Operation : public PK_Ops::Encryption + { + public: + typedef ElGamal_PublicKey Key_Type; + + size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } + + ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, const std::string&); + + secure_vector<byte> encrypt(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng); + + private: + Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; + Modular_Reducer mod_p; + }; + +ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, + const std::string&) { const BigInt& p = key.group_p(); @@ -97,14 +128,38 @@ ElGamal_Encryption_Operation::encrypt(const byte msg[], size_t msg_len, return output; } +/** +* ElGamal decryption operation +*/ +class ElGamal_Decryption_Operation : public PK_Ops::Decryption + { + public: + typedef ElGamal_PrivateKey Key_Type; + + size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } + + ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& emsa); + + secure_vector<byte> decrypt(const byte msg[], size_t msg_len); + private: + Fixed_Exponent_Power_Mod powermod_x_p; + Modular_Reducer mod_p; + Blinder blinder; + }; + ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, - RandomNumberGenerator& rng) + const std::string&) { const BigInt& p = key.group_p(); powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p); mod_p = Modular_Reducer(p); +#if defined(BOTAN_HAS_SYSTEM_RNG) + auto& rng = system_rng(); +#else + AutoSeeded_RNG rng; +#endif BigInt k(rng, p.bits() - 1); blinder = Blinder(k, powermod_x_p(k), p); } @@ -132,4 +187,9 @@ ElGamal_Decryption_Operation::decrypt(const byte msg[], size_t msg_len) return BigInt::encode_locked(blinder.unblind(r)); } +BOTAN_REGISTER_PK_ENCRYPTION_OP("ElGamal", ElGamal_Encryption_Operation); +BOTAN_REGISTER_PK_DECRYPTION_OP("ElGamal", ElGamal_Decryption_Operation); + +} + } diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index 1bef91579..90940b609 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -9,10 +9,6 @@ #define BOTAN_ELGAMAL_H__ #include <botan/dl_algo.h> -#include <botan/numthry.h> -#include <botan/reducer.h> -#include <botan/blinding.h> -#include <botan/pk_ops.h> namespace Botan { @@ -55,42 +51,6 @@ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, const BigInt& priv_key = 0); }; -/** -* ElGamal encryption operation -*/ -class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Encryption_Operation(const ElGamal_PublicKey& key); - - secure_vector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p; - }; - -/** -* ElGamal decryption operation -*/ -class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption - { - public: - size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; } - - ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, - RandomNumberGenerator& rng); - - secure_vector<byte> decrypt(const byte msg[], size_t msg_len); - private: - Fixed_Exponent_Power_Mod powermod_x_p; - Modular_Reducer mod_p; - Blinder blinder; - }; - } #endif diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index aeaa5735e..497712fd9 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -7,6 +7,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/gost_3410.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> @@ -90,16 +91,30 @@ BigInt decode_le(const byte msg[], size_t msg_len) return BigInt(&msg_le[0], msg_le.size()); } -} - -GOST_3410_Signature_Operation::GOST_3410_Signature_Operation( - const GOST_3410_PrivateKey& gost_3410) : - - base_point(gost_3410.domain().get_base_point()), - order(gost_3410.domain().get_order()), - x(gost_3410.private_value()) +/** +* GOST-34.10 signature operation +*/ +class GOST_3410_Signature_Operation : public PK_Ops::Signature { - } + public: + typedef GOST_3410_PrivateKey Key_Type; + GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410, const std::string&): + base_point(gost_3410.domain().get_base_point()), + order(gost_3410.domain().get_order()), + x(gost_3410.private_value()) {} + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return order.bytes(); } + size_t max_input_bits() const { return order.bits(); } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng); + + private: + const PointGFp& base_point; + const BigInt& order; + const BigInt& x; + }; secure_vector<byte> GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len, @@ -117,9 +132,7 @@ GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len, e = 1; PointGFp k_times_P = base_point * k; - - BOTAN_ASSERT(k_times_P.on_the_curve(), - "GOST 34.10 k*g is on the curve"); + BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve"); BigInt r = k_times_P.get_affine_x() % order; @@ -134,12 +147,32 @@ GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len, return output; } -GOST_3410_Verification_Operation::GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost) : - base_point(gost.domain().get_base_point()), - public_point(gost.public_point()), - order(gost.domain().get_order()) +/** +* GOST-34.10 verification operation +*/ +class GOST_3410_Verification_Operation : public PK_Ops::Verification { - } + public: + typedef GOST_3410_PublicKey Key_Type; + + GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost, const std::string&) : + base_point(gost.domain().get_base_point()), + public_point(gost.public_point()), + order(gost.domain().get_order()) {} + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return order.bytes(); } + size_t max_input_bits() const { return order.bits(); } + + bool with_recovery() const { return false; } + + bool verify(const byte msg[], size_t msg_len, + const byte sig[], size_t sig_len); + private: + const PointGFp& base_point; + const PointGFp& public_point; + const BigInt& order; + }; bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, const byte sig[], size_t sig_len) @@ -174,3 +207,8 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, } } + +BOTAN_REGISTER_PK_SIGNATURE_OP("GOST-34.10", GOST_3410_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("GOST-34.10", GOST_3410_Verification_Operation); + +} diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index d74ea08d7..2356d8e3d 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -11,7 +11,6 @@ #define BOTAN_GOST_3410_KEY_H__ #include <botan/ecc_key.h> -#include <botan/pk_ops.h> namespace Botan { @@ -91,49 +90,6 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, { return EC_PublicKey::algorithm_identifier(); } }; -/** -* GOST-34.10 signature operation -*/ -class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature - { - public: - GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - private: - const PointGFp& base_point; - const BigInt& order; - const BigInt& x; - }; - -/** -* GOST-34.10 verification operation -*/ -class BOTAN_DLL GOST_3410_Verification_Operation : public PK_Ops::Verification - { - public: - GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return order.bytes(); } - size_t max_input_bits() const { return order.bits(); } - - bool with_recovery() const { return false; } - - bool verify(const byte msg[], size_t msg_len, - const byte sig[], size_t sig_len); - private: - const PointGFp& base_point; - const PointGFp& public_point; - const BigInt& order; - }; - } #endif diff --git a/src/lib/pubkey/info.txt b/src/lib/pubkey/info.txt index 760f9c5cc..4e95c3742 100644 --- a/src/lib/pubkey/info.txt +++ b/src/lib/pubkey/info.txt @@ -22,6 +22,7 @@ workfactor.h <header:internal> pk_algs.h +pk_utils.h </header:internal> <requires> diff --git a/src/lib/pubkey/mce/mceliece.cpp b/src/lib/pubkey/mce/mceliece.cpp index 15a6f5ea8..4986254b1 100644 --- a/src/lib/pubkey/mce/mceliece.cpp +++ b/src/lib/pubkey/mce/mceliece.cpp @@ -17,7 +17,6 @@ #include <botan/goppa_code.h> #include <botan/internal/bit_ops.h> #include <botan/internal/xor_buf.h> -#include <iostream> namespace Botan { diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index c77dfe5b1..19de27d8e 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -23,123 +23,119 @@ namespace Botan { - - secure_vector<gf2m> BOTAN_DLL create_random_error_positions(unsigned code_length, unsigned error_weight, RandomNumberGenerator& rng); - class mceliece_message_parts -{ - public: - - mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length) - :m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)), - m_code_length(code_length) - { - m_message_word.resize(message_length); - copy_mem(&m_message_word[0], message, message_length); - }; - - mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length) - :m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)), - m_message_word(message), - m_code_length(code_length) - {}; - static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length) - { - secure_vector<byte> result((code_length+7)/8); - for(unsigned i = 0; i < err_pos_len; i++) - { - u16bit pos = err_pos[i]; - u32bit byte_pos = _BITP_TO_BYTEP(pos); - if(byte_pos > result.size()) - { - throw Invalid_Argument("error position larger than code size"); - } - result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos)); - } - return result; - }; - mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length) - :m_code_length(code_length) - { - size_t err_vec_len = (code_length+7)/8; - if(message_concat_errors_len < err_vec_len ) - { - throw Invalid_Argument("cannot split McEliece message parts"); - } - size_t err_vec_start_pos = message_concat_errors_len - err_vec_len; - m_message_word = secure_vector<byte>(err_vec_start_pos ); - copy_mem(&m_message_word[0], &message_concat_errors[0], err_vec_start_pos); - m_error_vector = secure_vector<byte>(err_vec_len ); - copy_mem(&m_error_vector[0], &message_concat_errors[err_vec_start_pos], err_vec_len); - - }; - secure_vector<byte> get_concat() const - { - secure_vector<byte> result(m_error_vector.size() + m_message_word.size()); - copy_mem(&result[0], &m_message_word[0], m_message_word.size()); - copy_mem(&result[m_message_word.size()], &m_error_vector[0], m_error_vector.size()); - return result; - }; - secure_vector<gf2m> get_error_positions() const - { - secure_vector<gf2m> result; - for(unsigned i = 0; i < m_code_length; i++) - { - - if ( i >= m_code_length) - { - throw Invalid_Argument("index out of range in get_error_positions()"); - } - if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1) - { - result.push_back(i); - } - } - return result; - }; - secure_vector<byte> get_error_vector() const { return m_error_vector; }; - secure_vector<byte> get_message_word() const { return m_message_word; }; - private: - secure_vector<byte> m_error_vector; - secure_vector<byte> m_message_word; - unsigned m_code_length; -}; + { + public: + + mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length) : + m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)), + m_code_length(code_length) + { + m_message_word.resize(message_length); + copy_mem(&m_message_word[0], message, message_length); + } + + mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length) : + m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)), + m_message_word(message), + m_code_length(code_length) + {} + + static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length) + { + secure_vector<byte> result((code_length+7)/8); + for(unsigned i = 0; i < err_pos_len; i++) + { + u16bit pos = err_pos[i]; + u32bit byte_pos = _BITP_TO_BYTEP(pos); + if(byte_pos > result.size()) + { + throw Invalid_Argument("error position larger than code size"); + } + result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos)); + } + return result; + } + + mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length) : + m_code_length(code_length) + { + size_t err_vec_len = (code_length+7)/8; + if(message_concat_errors_len < err_vec_len ) + { + throw Invalid_Argument("cannot split McEliece message parts"); + } + size_t err_vec_start_pos = message_concat_errors_len - err_vec_len; + m_message_word = secure_vector<byte>(err_vec_start_pos ); + copy_mem(&m_message_word[0], &message_concat_errors[0], err_vec_start_pos); + m_error_vector = secure_vector<byte>(err_vec_len ); + copy_mem(&m_error_vector[0], &message_concat_errors[err_vec_start_pos], err_vec_len); + } + + secure_vector<byte> get_concat() const + { + secure_vector<byte> result(m_error_vector.size() + m_message_word.size()); + copy_mem(&result[0], &m_message_word[0], m_message_word.size()); + copy_mem(&result[m_message_word.size()], &m_error_vector[0], m_error_vector.size()); + return result; + } + + secure_vector<gf2m> get_error_positions() const + { + secure_vector<gf2m> result; + for(unsigned i = 0; i < m_code_length; i++) + { + if(i >= m_code_length) + { + throw Invalid_Argument("index out of range in get_error_positions()"); + } + if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1) + { + result.push_back(i); + } + } + return result; + } + + secure_vector<byte> get_error_vector() const { return m_error_vector; } + secure_vector<byte> get_message_word() const { return m_message_word; } + private: + secure_vector<byte> m_error_vector; + secure_vector<byte> m_message_word; + unsigned m_code_length; + }; class BOTAN_DLL McEliece_Private_Operation : public PK_Ops::Decryption - { - public: + { + public: McEliece_Private_Operation(const McEliece_PrivateKey& mce_key); - size_t max_input_bits() const { - return m_priv_key.max_input_bits(); - - }; - + size_t max_input_bits() const { return m_priv_key.max_input_bits(); } -secure_vector<byte> decrypt(const byte msg[], size_t msg_len); + secure_vector<byte> decrypt(const byte msg[], size_t msg_len); - McEliece_PrivateKey const& get_key() const { return m_priv_key; }; + McEliece_PrivateKey const& get_key() const { return m_priv_key; } - private: + private: const McEliece_PrivateKey m_priv_key; - }; + }; class BOTAN_DLL McEliece_Public_Operation : public PK_Ops::Encryption -{ - public: - McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length); + { + public: + McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length); - size_t max_input_bits() const { return m_pub_key.max_input_bits(); }; - secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&); + size_t max_input_bits() const { return m_pub_key.max_input_bits(); } + secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&); - McEliece_PublicKey const& get_key() const { return m_pub_key; }; + McEliece_PublicKey const& get_key() const { return m_pub_key; } - private: - McEliece_PublicKey m_pub_key; - u32bit m_code_length; -}; + private: + McEliece_PublicKey m_pub_key; + u32bit m_code_length; + }; /** * Estimate work factor for McEliece diff --git a/src/lib/pubkey/nr/nr.cpp b/src/lib/pubkey/nr/nr.cpp index f100efb26..6e3a8f0c1 100644 --- a/src/lib/pubkey/nr/nr.cpp +++ b/src/lib/pubkey/nr/nr.cpp @@ -5,9 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/nr.h> -#include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/reducer.h> #include <future> namespace Botan { @@ -72,13 +73,35 @@ bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } -NR_Signature_Operation::NR_Signature_Operation(const NR_PrivateKey& nr) : - q(nr.group_q()), - x(nr.get_x()), - powermod_g_p(nr.group_g(), nr.group_p()), - mod_q(nr.group_q()) +namespace { + +/** +* Nyberg-Rueppel signature operation +*/ +class NR_Signature_Operation : public PK_Ops::Signature { - } + public: + typedef NR_PrivateKey Key_Type; + NR_Signature_Operation(const NR_PrivateKey& nr, const std::string&) : + q(nr.group_q()), + x(nr.get_x()), + powermod_g_p(nr.group_g(), nr.group_p()), + mod_q(nr.group_q()) + { + } + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return q.bytes(); } + size_t max_input_bits() const { return (q.bits() - 1); } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng); + private: + const BigInt& q; + const BigInt& x; + Fixed_Base_Power_Mod powermod_g_p; + Modular_Reducer mod_q; + }; secure_vector<byte> NR_Signature_Operation::sign(const byte msg[], size_t msg_len, @@ -110,14 +133,37 @@ NR_Signature_Operation::sign(const byte msg[], size_t msg_len, return output; } -NR_Verification_Operation::NR_Verification_Operation(const NR_PublicKey& nr) : - q(nr.group_q()), y(nr.get_y()) + +/** +* Nyberg-Rueppel verification operation +*/ +class NR_Verification_Operation : public PK_Ops::Verification { - powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p()); - powermod_y_p = Fixed_Base_Power_Mod(y, nr.group_p()); - mod_p = Modular_Reducer(nr.group_p()); - mod_q = Modular_Reducer(nr.group_q()); - } + public: + typedef NR_PublicKey Key_Type; + NR_Verification_Operation(const NR_PublicKey& nr, const std::string&) : + q(nr.group_q()), y(nr.get_y()) + { + powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p()); + powermod_y_p = Fixed_Base_Power_Mod(y, nr.group_p()); + mod_p = Modular_Reducer(nr.group_p()); + mod_q = Modular_Reducer(nr.group_q()); + } + + size_t message_parts() const { return 2; } + size_t message_part_size() const { return q.bytes(); } + size_t max_input_bits() const { return (q.bits() - 1); } + + bool with_recovery() const { return true; } + + secure_vector<byte> verify_mr(const byte msg[], size_t msg_len); + private: + const BigInt& q; + const BigInt& y; + + Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; + Modular_Reducer mod_p, mod_q; + }; secure_vector<byte> NR_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) @@ -139,5 +185,9 @@ NR_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) BigInt i = mod_p.multiply(g_d, future_y_c.get()); return BigInt::encode_locked(mod_q.reduce(c - i)); } +} + +BOTAN_REGISTER_PK_SIGNATURE_OP("NR", NR_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("NR", NR_Verification_Operation); } diff --git a/src/lib/pubkey/nr/nr.h b/src/lib/pubkey/nr/nr.h index 76f689079..51752f8ce 100644 --- a/src/lib/pubkey/nr/nr.h +++ b/src/lib/pubkey/nr/nr.h @@ -9,9 +9,6 @@ #define BOTAN_NYBERG_RUEPPEL_H__ #include <botan/dl_algo.h> -#include <botan/pk_ops.h> -#include <botan/numthry.h> -#include <botan/reducer.h> namespace Botan { @@ -55,50 +52,6 @@ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, const BigInt& x = 0); }; -/** -* Nyberg-Rueppel signature operation -*/ -class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature - { - public: - NR_Signature_Operation(const NR_PrivateKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& q; - const BigInt& x; - Fixed_Base_Power_Mod powermod_g_p; - Modular_Reducer mod_q; - }; - -/** -* Nyberg-Rueppel verification operation -*/ -class BOTAN_DLL NR_Verification_Operation : public PK_Ops::Verification - { - public: - NR_Verification_Operation(const NR_PublicKey& nr); - - size_t message_parts() const { return 2; } - size_t message_part_size() const { return q.bytes(); } - size_t max_input_bits() const { return (q.bits() - 1); } - - bool with_recovery() const { return true; } - - secure_vector<byte> verify_mr(const byte msg[], size_t msg_len); - private: - const BigInt& q; - const BigInt& y; - - Fixed_Base_Power_Mod powermod_g_p, powermod_y_p; - Modular_Reducer mod_p, mod_q; - }; - } #endif diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h index 7965e7464..7277c7ad5 100644 --- a/src/lib/pubkey/pk_ops.h +++ b/src/lib/pubkey/pk_ops.h @@ -8,6 +8,7 @@ #ifndef BOTAN_PK_OPERATIONS_H__ #define BOTAN_PK_OPERATIONS_H__ +#include <botan/pk_keys.h> #include <botan/secmem.h> #include <botan/rng.h> @@ -15,6 +16,24 @@ namespace Botan { namespace PK_Ops { +template<typename Key> +struct PK_Spec + { + public: + PK_Spec(const Key& key, const std::string& pad) : + m_key(key), m_pad(pad) {} + + std::string algo_name() const { return m_key.algo_name(); } + + std::string as_string() const { return algo_name() + "/" + padding(); } + + const Key& key() const { return m_key; } + const std::string& padding() const { return m_pad; } + private: + const Key& m_key; + const std::string m_pad; + }; + /** * Public key encryption interface */ @@ -23,8 +42,9 @@ class BOTAN_DLL Encryption public: virtual size_t max_input_bits() const = 0; - virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) = 0; + virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) = 0; + + typedef PK_Spec<Public_Key> Spec; virtual ~Encryption() {} }; @@ -37,8 +57,9 @@ class BOTAN_DLL Decryption public: virtual size_t max_input_bits() const = 0; - virtual secure_vector<byte> decrypt(const byte msg[], - size_t msg_len) = 0; + virtual secure_vector<byte> decrypt(const byte msg[], size_t msg_len) = 0; + + typedef PK_Spec<Private_Key> Spec; virtual ~Decryption() {} }; @@ -76,6 +97,8 @@ class BOTAN_DLL Signature virtual secure_vector<byte> sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) = 0; + typedef PK_Spec<Private_Key> Spec; + virtual ~Signature() {} }; @@ -136,6 +159,8 @@ class BOTAN_DLL Verification throw Invalid_State("Message recovery not supported"); } + typedef PK_Spec<Public_Key> Spec; + virtual ~Verification() {} }; @@ -153,6 +178,8 @@ class BOTAN_DLL Key_Agreement */ virtual secure_vector<byte> agree(const byte w[], size_t w_len) = 0; + typedef PK_Spec<Private_Key> Spec; + virtual ~Key_Agreement() {} }; diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index 07f02d3e0..95d61ad4c 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -10,27 +10,34 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/parsing.h> -#include <botan/libstate.h> -#include <botan/engine.h> +#include <botan/algo_registry.h> #include <botan/internal/bit_ops.h> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#else + #include <botan/auto_rng.h> +#endif + namespace Botan { +namespace { + +template<typename T, typename Key> +T* get_pk_op(const Key& key, const std::string& pad) + { + return Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad)); + } + +} + /* * PK_Encryptor_EME Constructor */ PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, const std::string& eme_name) { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - RandomNumberGenerator& rng = global_state().global_rng(); - - while(const Engine* engine = i.next()) - { - m_op.reset(engine->get_encryption_op(key, rng)); - if(m_op) - break; - } + m_op.reset(get_pk_op<PK_Ops::Encryption>(key, eme_name)); if(!m_op) throw Lookup_Error("Encryption with " + key.algo_name() + " not supported"); @@ -82,19 +89,7 @@ size_t PK_Encryptor_EME::maximum_input_size() const PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& eme_name) { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - RandomNumberGenerator& rng = global_state().global_rng(); - - while(const Engine* engine = i.next()) - { - m_op.reset(engine->get_decryption_op(key, rng)); - if(m_op) - break; - } - - if(!m_op) - throw Lookup_Error("Decryption with " + key.algo_name() + " not supported"); - + m_op.reset(get_pk_op<PK_Ops::Decryption>(key, eme_name)); m_eme.reset(get_eme(eme_name)); } @@ -105,7 +100,7 @@ secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[], size_t length) const { try { - secure_vector<byte> decrypted = m_op->decrypt(msg, length); + const secure_vector<byte> decrypted = m_op->decrypt(msg, length); if(m_eme) return m_eme->decode(decrypted, m_op->max_input_bits()); else @@ -125,25 +120,12 @@ PK_Signer::PK_Signer(const Private_Key& key, Signature_Format format, Fault_Protection prot) { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - RandomNumberGenerator& rng = global_state().global_rng(); + m_op.reset(get_pk_op<PK_Ops::Signature>(key, emsa_name)); - m_op = nullptr; - m_verify_op = nullptr; - - while(const Engine* engine = i.next()) - { - if(!m_op) - m_op.reset(engine->get_signature_op(key, emsa_name, rng)); - - if(!m_verify_op && prot == ENABLE_FAULT_PROTECTION) - m_verify_op.reset(engine->get_verify_op(key, emsa_name, rng)); - - if(m_op && (m_verify_op || prot == DISABLE_FAULT_PROTECTION)) - break; - } + if(prot == ENABLE_FAULT_PROTECTION) + m_verify_op.reset(get_pk_op<PK_Ops::Verification>(key, emsa_name)); - if(!m_op || (!m_verify_op && prot == ENABLE_FAULT_PROTECTION)) + if(!m_op || (prot == ENABLE_FAULT_PROTECTION && !m_verify_op)) throw Lookup_Error("Signing with " + key.algo_name() + " not supported"); m_emsa.reset(get_emsa(emsa_name)); @@ -244,15 +226,7 @@ PK_Verifier::PK_Verifier(const Public_Key& key, const std::string& emsa_name, Signature_Format format) { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - RandomNumberGenerator& rng = global_state().global_rng(); - - while(const Engine* engine = i.next()) - { - m_op.reset(engine->get_verify_op(key, emsa_name, rng)); - if(m_op) - break; - } + m_op.reset(get_pk_op<PK_Ops::Verification>(key, emsa_name)); if(!m_op) throw Lookup_Error("Verification with " + key.algo_name() + " not supported"); @@ -338,7 +312,7 @@ bool PK_Verifier::validate_signature(const secure_vector<byte>& msg, } else { - RandomNumberGenerator& rng = global_state().global_rng(); + Null_RNG rng; secure_vector<byte> encoded = m_emsa->encoding_of(msg, m_op->max_input_bits(), rng); @@ -353,15 +327,7 @@ bool PK_Verifier::validate_signature(const secure_vector<byte>& msg, PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key, const std::string& kdf_name) { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - RandomNumberGenerator& rng = global_state().global_rng(); - - while(const Engine* engine = i.next()) - { - m_op.reset(engine->get_key_agreement_op(key, rng)); - if(m_op) - break; - } + m_op.reset(get_pk_op<PK_Ops::Key_Agreement>(key, kdf_name)); if(!m_op) throw Lookup_Error("Key agreement with " + key.algo_name() + " not supported"); diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index 2a0e8253e..9393cb954 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -5,12 +5,20 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/rsa.h> #include <botan/parsing.h> -#include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/blinding.h> +#include <botan/reducer.h> #include <future> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#else + #include <botan/auto_rng.h> +#endif + namespace Botan { /* @@ -59,63 +67,182 @@ bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-1)"); } -RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa, - RandomNumberGenerator& rng) : - n(rsa.get_n()), - q(rsa.get_q()), - c(rsa.get_c()), - powermod_e_n(rsa.get_e(), rsa.get_n()), - powermod_d1_p(rsa.get_d1(), rsa.get_p()), - powermod_d2_q(rsa.get_d2(), rsa.get_q()), - mod_p(rsa.get_p()) - { - BigInt k(rng, n.bits() - 1); - blinder = Blinder(powermod_e_n(k), inverse_mod(k, n), n); - } +namespace { -BigInt RSA_Private_Operation::private_op(const BigInt& m) const +/** +* RSA private (decrypt/sign) operation +*/ +class RSA_Private_Operation + { + protected: + size_t get_max_input_bits() const { return (n.bits() - 1); } + + RSA_Private_Operation(const RSA_PrivateKey& rsa) : + n(rsa.get_n()), + q(rsa.get_q()), + c(rsa.get_c()), + m_powermod_e_n(rsa.get_e(), rsa.get_n()), + m_powermod_d1_p(rsa.get_d1(), rsa.get_p()), + m_powermod_d2_q(rsa.get_d2(), rsa.get_q()), + m_mod_p(rsa.get_p()) + { +#if defined(BOTAN_HAS_SYSTEM_RNG) + auto& rng = system_rng(); +#else + AutoSeeded_RNG rng; +#endif + BigInt k(rng, n.bits() - 1); + m_blinder = Blinder(m_powermod_e_n(k), inverse_mod(k, n), n); + } + + BigInt blinded_private_op(const BigInt& m) const + { + return m_blinder.unblind(private_op(m_blinder.blind(m))); + } + + BigInt private_op(const BigInt& m) const + { + if(m >= n) + throw Invalid_Argument("RSA private op - input is too large"); + + auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m); + BigInt j2 = m_powermod_d2_q(m); + BigInt j1 = future_j1.get(); + + j1 = m_mod_p.reduce(sub_mul(j1, j2, c)); + + return mul_add(j1, q, j2); + } + + const BigInt& n; + const BigInt& q; + const BigInt& c; + Fixed_Exponent_Power_Mod m_powermod_e_n, m_powermod_d1_p, m_powermod_d2_q; + Modular_Reducer m_mod_p; + Blinder m_blinder; + }; + +class RSA_Signature_Operation : public PK_Ops::Signature, + private RSA_Private_Operation { - if(m >= n) - throw Invalid_Argument("RSA private op - input is too large"); + public: + typedef RSA_PrivateKey Key_Type; + + size_t max_input_bits() const override { return get_max_input_bits(); }; + + RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string&) : + RSA_Private_Operation(rsa) + { + } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator&) override + { + /* We don't check signatures against powermod_e_n here because + PK_Signer checks verification consistency for all signature + algorithms. + */ + const BigInt m(msg, msg_len); + const BigInt x = blinded_private_op(m); + return BigInt::encode_1363(x, n.bytes()); + } + }; + +class RSA_Decryption_Operation : public PK_Ops::Decryption, + private RSA_Private_Operation + { + public: + typedef RSA_PrivateKey Key_Type; - auto future_j1 = std::async(std::launch::async, powermod_d1_p, m); - BigInt j2 = powermod_d2_q(m); - BigInt j1 = future_j1.get(); + size_t max_input_bits() const override { return get_max_input_bits(); }; - j1 = mod_p.reduce(sub_mul(j1, j2, c)); + RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string&) : + RSA_Private_Operation(rsa) + { + } - return mul_add(j1, q, j2); - } + secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override + { + const BigInt m(msg, msg_len); + const BigInt x = blinded_private_op(m); + BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA decrypt consistency check"); + return BigInt::encode_locked(x); + } + }; -secure_vector<byte> -RSA_Private_Operation::sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng) + +/** +* RSA public (encrypt/verify) operation +*/ +class RSA_Public_Operation { - rng.add_entropy(msg, msg_len); + public: + RSA_Public_Operation(const RSA_PublicKey& rsa) : + n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n()) + {} + + size_t get_max_input_bits() const { return (n.bits() - 1); } + + protected: + BigInt public_op(const BigInt& m) const + { + if(m >= n) + throw Invalid_Argument("RSA public op - input is too large"); + return powermod_e_n(m); + } + + const BigInt& n; + Fixed_Exponent_Power_Mod powermod_e_n; + }; + +class RSA_Encryption_Operation : public PK_Ops::Encryption, + private RSA_Public_Operation + { + public: + typedef RSA_PublicKey Key_Type; + + RSA_Encryption_Operation(const RSA_PublicKey& rsa, const std::string&) : + RSA_Public_Operation(rsa) + { + } + + size_t max_input_bits() const override { return get_max_input_bits(); }; + + secure_vector<byte> encrypt(const byte msg[], size_t msg_len, + RandomNumberGenerator&) + { + BigInt m(msg, msg_len); + return BigInt::encode_1363(public_op(m), n.bytes()); + } + }; + +class RSA_Verify_Operation : public PK_Ops::Verification, + private RSA_Public_Operation + { + public: + typedef RSA_PublicKey Key_Type; - /* We don't check signatures against powermod_e_n here because - PK_Signer checks verification consistency for all signature - algorithms. - */ + size_t max_input_bits() const override { return get_max_input_bits(); }; - const BigInt m(msg, msg_len); - const BigInt x = blinder.unblind(private_op(blinder.blind(m))); - return BigInt::encode_1363(x, n.bytes()); - } + RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string&) : + RSA_Public_Operation(rsa) + { + } -/* -* RSA Decryption Operation -*/ -secure_vector<byte> -RSA_Private_Operation::decrypt(const byte msg[], size_t msg_len) - { - const BigInt m(msg, msg_len); - const BigInt x = blinder.unblind(private_op(blinder.blind(m))); + bool with_recovery() const override { return true; } - BOTAN_ASSERT(m == powermod_e_n(x), - "RSA decrypt passed consistency check"); + secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override + { + BigInt m(msg, msg_len); + return BigInt::encode_locked(public_op(m)); + } + }; - return BigInt::encode_locked(x); - } +BOTAN_REGISTER_PK_ENCRYPTION_OP("RSA", RSA_Encryption_Operation); +BOTAN_REGISTER_PK_DECRYPTION_OP("RSA", RSA_Decryption_Operation); +BOTAN_REGISTER_PK_SIGNATURE_OP("RSA", RSA_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("RSA", RSA_Verify_Operation); + +} } diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index 8a599d2ab..67357d859 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -9,9 +9,7 @@ #define BOTAN_RSA_H__ #include <botan/if_algo.h> -#include <botan/pk_ops.h> -#include <botan/reducer.h> -#include <botan/blinding.h> + namespace Botan { @@ -83,73 +81,6 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, size_t bits, size_t exp = 65537); }; -/** -* RSA private (decrypt/sign) operation -*/ -class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, - public PK_Ops::Decryption - { - public: - RSA_Private_Operation(const RSA_PrivateKey& rsa, - RandomNumberGenerator& rng); - - size_t max_input_bits() const { return (n.bits() - 1); } - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - - secure_vector<byte> decrypt(const byte msg[], size_t msg_len); - - private: - BigInt private_op(const BigInt& m) const; - - const BigInt& n; - const BigInt& q; - const BigInt& c; - Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* RSA public (encrypt/verify) operation -*/ -class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, - public PK_Ops::Encryption - { - public: - RSA_Public_Operation(const RSA_PublicKey& rsa) : - n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - secure_vector<byte> encrypt(const byte msg[], size_t msg_len, - RandomNumberGenerator&) - { - BigInt m(msg, msg_len); - return BigInt::encode_1363(public_op(m), n.bytes()); - } - - secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) - { - BigInt m(msg, msg_len); - return BigInt::encode_locked(public_op(m)); - } - - private: - BigInt public_op(const BigInt& m) const - { - if(m >= n) - throw Invalid_Argument("RSA public op - input is too large"); - return powermod_e_n(m); - } - - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - } #endif diff --git a/src/lib/pubkey/rw/rw.cpp b/src/lib/pubkey/rw/rw.cpp index a2f21ecb8..3c7a6250b 100644 --- a/src/lib/pubkey/rw/rw.cpp +++ b/src/lib/pubkey/rw/rw.cpp @@ -5,10 +5,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/pk_utils.h> #include <botan/rw.h> -#include <botan/numthry.h> #include <botan/keypair.h> #include <botan/parsing.h> +#include <botan/reducer.h> +#include <botan/blinding.h> #include <algorithm> #include <future> @@ -60,16 +62,42 @@ bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA2(SHA-1)"); } -RW_Signature_Operation::RW_Signature_Operation(const RW_PrivateKey& rw) : - n(rw.get_n()), - e(rw.get_e()), - q(rw.get_q()), - c(rw.get_c()), - powermod_d1_p(rw.get_d1(), rw.get_p()), - powermod_d2_q(rw.get_d2(), rw.get_q()), - mod_p(rw.get_p()) +namespace { + +/** +* Rabin-Williams Signature Operation +*/ +class RW_Signature_Operation : public PK_Ops::Signature { - } + public: + typedef RW_PrivateKey Key_Type; + + RW_Signature_Operation(const RW_PrivateKey& rw, + const std::string&) : + n(rw.get_n()), + e(rw.get_e()), + q(rw.get_q()), + c(rw.get_c()), + powermod_d1_p(rw.get_d1(), rw.get_p()), + powermod_d2_q(rw.get_d2(), rw.get_q()), + mod_p(rw.get_p()) + { + } + + size_t max_input_bits() const { return (n.bits() - 1); } + + secure_vector<byte> sign(const byte msg[], size_t msg_len, + RandomNumberGenerator& rng); + private: + const BigInt& n; + const BigInt& e; + const BigInt& q; + const BigInt& c; + + Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q; + Modular_Reducer mod_p; + Blinder blinder; + }; secure_vector<byte> RW_Signature_Operation::sign(const byte msg[], size_t msg_len, @@ -104,6 +132,28 @@ RW_Signature_Operation::sign(const byte msg[], size_t msg_len, return BigInt::encode_1363(std::min(r, n - r), n.bytes()); } +/** +* Rabin-Williams Verification Operation +*/ +class RW_Verification_Operation : public PK_Ops::Verification + { + public: + typedef RW_PublicKey Key_Type; + + RW_Verification_Operation(const RW_PublicKey& rw, const std::string&) : + n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n()) + {} + + size_t max_input_bits() const { return (n.bits() - 1); } + bool with_recovery() const { return true; } + + secure_vector<byte> verify_mr(const byte msg[], size_t msg_len); + + private: + const BigInt& n; + Fixed_Exponent_Power_Mod powermod_e_n; + }; + secure_vector<byte> RW_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) { @@ -127,4 +177,9 @@ RW_Verification_Operation::verify_mr(const byte msg[], size_t msg_len) throw Invalid_Argument("RW signature verification: Invalid signature"); } +BOTAN_REGISTER_PK_SIGNATURE_OP("RW", RW_Signature_Operation); +BOTAN_REGISTER_PK_VERIFY_OP("RW", RW_Verification_Operation); + +} + } diff --git a/src/lib/pubkey/rw/rw.h b/src/lib/pubkey/rw/rw.h index b42d26b64..5d754e817 100644 --- a/src/lib/pubkey/rw/rw.h +++ b/src/lib/pubkey/rw/rw.h @@ -9,9 +9,6 @@ #define BOTAN_RW_H__ #include <botan/if_algo.h> -#include <botan/pk_ops.h> -#include <botan/reducer.h> -#include <botan/blinding.h> namespace Botan { @@ -59,49 +56,6 @@ class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, bool check_key(RandomNumberGenerator& rng, bool) const; }; -/** -* Rabin-Williams Signature Operation -*/ -class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature - { - public: - RW_Signature_Operation(const RW_PrivateKey& rw); - - size_t max_input_bits() const { return (n.bits() - 1); } - - secure_vector<byte> sign(const byte msg[], size_t msg_len, - RandomNumberGenerator& rng); - private: - const BigInt& n; - const BigInt& e; - const BigInt& q; - const BigInt& c; - - Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q; - Modular_Reducer mod_p; - Blinder blinder; - }; - -/** -* Rabin-Williams Verification Operation -*/ -class BOTAN_DLL RW_Verification_Operation : public PK_Ops::Verification - { - public: - RW_Verification_Operation(const RW_PublicKey& rw) : - n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n()) - {} - - size_t max_input_bits() const { return (n.bits() - 1); } - bool with_recovery() const { return true; } - - secure_vector<byte> verify_mr(const byte msg[], size_t msg_len); - - private: - const BigInt& n; - Fixed_Exponent_Power_Mod powermod_e_n; - }; - } #endif |