diff options
author | Jack Lloyd <[email protected]> | 2016-09-04 10:04:02 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-10-07 19:27:56 -0400 |
commit | 25b6fb53eec30620d084411fb1dbc8913142fc6d (patch) | |
tree | 6ffa291a3f4a74cac23bce304a42f4c26e33bcda /src/lib | |
parent | 62cd6e3651711f759f870460599596ff5be904a5 (diff) |
Remove Algo_Registry usage from public key code.
Instead the key types exposes operations like `create_encryption_op`
which will return the relevant operation if the algorithm supports it.
Changes pubkey.h interface, now RNG is passed at init time.
Blinder previous created its own RNG, now it takes it from app.
Diffstat (limited to 'src/lib')
61 files changed, 1080 insertions, 388 deletions
diff --git a/src/lib/cert/x509/ocsp.cpp b/src/lib/cert/x509/ocsp.cpp index 761c5b436..fb6234cc8 100644 --- a/src/lib/cert/x509/ocsp.cpp +++ b/src/lib/cert/x509/ocsp.cpp @@ -61,7 +61,8 @@ void check_signature(const std::vector<byte>& tbs_response, Signature_Format format = (pub_key->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - PK_Verifier verifier(*pub_key, padding, format); + Null_RNG null_rng; + PK_Verifier verifier(*pub_key, null_rng, padding, format); if(!verifier.verify_message(ASN1::put_in_sequence(tbs_response), signature)) throw Exception("Signature on OCSP response does not verify"); diff --git a/src/lib/cert/x509/x509_ca.cpp b/src/lib/cert/x509/x509_ca.cpp index 58c6676f4..179d903c4 100644 --- a/src/lib/cert/x509/x509_ca.cpp +++ b/src/lib/cert/x509/x509_ca.cpp @@ -26,12 +26,13 @@ namespace Botan { */ X509_CA::X509_CA(const X509_Certificate& c, const Private_Key& key, - const std::string& hash_fn) : m_cert(c) + const std::string& hash_fn, + RandomNumberGenerator& rng) : m_cert(c) { if(!m_cert.is_CA_cert()) throw Invalid_Argument("X509_CA: This certificate is not for a CA"); - m_signer = choose_sig_format(key, hash_fn, m_ca_sig_algo); + m_signer = choose_sig_format(key, rng, hash_fn, m_ca_sig_algo); } /* @@ -225,6 +226,7 @@ X509_Certificate X509_CA::ca_certificate() const * Choose a signing format for the key */ PK_Signer* choose_sig_format(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& hash_fn, AlgorithmIdentifier& sig_algo) { @@ -258,7 +260,7 @@ PK_Signer* choose_sig_format(const Private_Key& key, sig_algo.oid = OIDS::lookup(algo_name + "/" + padding); sig_algo.parameters = key.algorithm_identifier().parameters; - return new PK_Signer(key, padding, format); + return new PK_Signer(key, rng, padding, format); } } diff --git a/src/lib/cert/x509/x509_ca.h b/src/lib/cert/x509/x509_ca.h index ba3724f5e..218ee0803 100644 --- a/src/lib/cert/x509/x509_ca.h +++ b/src/lib/cert/x509/x509_ca.h @@ -14,6 +14,10 @@ #include <botan/pkcs10.h> #include <botan/pubkey.h> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> +#endif + namespace Botan { /** @@ -95,7 +99,17 @@ class BOTAN_DLL X509_CA */ X509_CA(const X509_Certificate& ca_certificate, const Private_Key& key, - const std::string& hash_fn); + const std::string& hash_fn, + RandomNumberGenerator& rng); + +#if defined(BOTAN_HAS_SYSTEM_RNG) + BOTAN_DEPRECATED("Use version taking RNG object") + X509_CA(const X509_Certificate& ca_certificate, + const Private_Key& key, + const std::string& hash_fn) : + X509_CA(ca_certificate, key, hash_fn, system_rng()) + {} +#endif X509_CA(const X509_CA&) = delete; X509_CA& operator=(const X509_CA&) = delete; @@ -120,6 +134,7 @@ class BOTAN_DLL X509_CA * @return A PK_Signer object for generating signatures */ BOTAN_DLL PK_Signer* choose_sig_format(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& hash_fn, AlgorithmIdentifier& alg_id); diff --git a/src/lib/cert/x509/x509_obj.cpp b/src/lib/cert/x509/x509_obj.cpp index 983be40b2..25da0155e 100644 --- a/src/lib/cert/x509/x509_obj.cpp +++ b/src/lib/cert/x509/x509_obj.cpp @@ -197,7 +197,8 @@ bool X509_Object::check_signature(const Public_Key& pub_key) const Signature_Format format = (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; - PK_Verifier verifier(pub_key, padding, format); + Null_RNG null_rng; + PK_Verifier verifier(pub_key, null_rng, padding, format); return verifier.verify_message(tbs_data(), signature()); } diff --git a/src/lib/cert/x509/x509self.cpp b/src/lib/cert/x509/x509self.cpp index 102e24f77..a59632858 100644 --- a/src/lib/cert/x509/x509self.cpp +++ b/src/lib/cert/x509/x509self.cpp @@ -50,7 +50,7 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, AlternativeName subject_alt; std::vector<byte> pub_key = X509::BER_encode(key); - std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); + std::unique_ptr<PK_Signer> signer(choose_sig_format(key, rng, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); Key_Constraints constraints; @@ -102,7 +102,7 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, AlternativeName subject_alt; std::vector<byte> pub_key = X509::BER_encode(key); - std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); + std::unique_ptr<PK_Signer> signer(choose_sig_format(key, rng, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); const size_t PKCS10_VERSION = 0; diff --git a/src/lib/prov/openssl/openssl.h b/src/lib/prov/openssl/openssl.h index ebaa2b756..c7bd5774b 100644 --- a/src/lib/prov/openssl/openssl.h +++ b/src/lib/prov/openssl/openssl.h @@ -8,9 +8,11 @@ #ifndef BOTAN_OPENSSL_H__ #define BOTAN_OPENSSL_H__ +#include <botan/pk_ops.h> #include <botan/secmem.h> #include <botan/exceptn.h> #include <memory> +#include <string> #include <openssl/err.h> @@ -27,9 +29,50 @@ class OpenSSL_Error : public Exception #define BOTAN_OPENSSL_HASH_PRIO 150 #define BOTAN_OPENSSL_RC4_PRIO 150 -#define BOTAN_OPENSSL_RSA_PRIO 90 -#define BOTAN_OPENSSL_ECDSA_PRIO 90 -#define BOTAN_OPENSSL_ECDH_PRIO 90 +/* RSA */ + +#if defined(BOTAN_HAS_RSA) + +class RSA_PublicKey; +class RSA_PrivateKey; + +std::unique_ptr<PK_Ops::Encryption> +make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params); +std::unique_ptr<PK_Ops::Decryption> +make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params); + +std::unique_ptr<PK_Ops::Verification> +make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params); +std::unique_ptr<PK_Ops::Signature> +make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params); + +#endif + +/* ECDSA */ + +#if defined(BOTAN_HAS_ECDSA) + +class ECDSA_PublicKey; +class ECDSA_PrivateKey; + +std::unique_ptr<PK_Ops::Verification> +make_openssl_ecdsa_ver_op(const ECDSA_PublicKey& key, const std::string& params); +std::unique_ptr<PK_Ops::Signature> +make_openssl_ecdsa_sig_op(const ECDSA_PrivateKey& key, const std::string& params); + +#endif + +/* ECDH */ + +#if defined(BOTAN_HAS_ECDH) + +class ECDH_PrivateKey; + +std::unique_ptr<PK_Ops::Key_Agreement> +make_openssl_ecdh_ka_op(const ECDH_PrivateKey& key, const std::string& params); + +#endif + } diff --git a/src/lib/prov/openssl/openssl_ec.cpp b/src/lib/prov/openssl/openssl_ec.cpp index 4378833ec..6593ba129 100644 --- a/src/lib/prov/openssl/openssl_ec.cpp +++ b/src/lib/prov/openssl/openssl_ec.cpp @@ -11,7 +11,7 @@ #include <botan/der_enc.h> #include <botan/pkcs8.h> #include <botan/oids.h> - #include <botan/internal/pk_utils.h> + #include <botan/internal/pk_ops_impl.h> #endif #if defined(BOTAN_HAS_ECDSA) @@ -91,20 +91,6 @@ int OpenSSL_EC_nid_for(const OID& oid) class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EMSA { public: - typedef ECDSA_PublicKey Key_Type; - - static OpenSSL_ECDSA_Verification_Operation* make(const Spec& spec) - { - if(const ECDSA_PublicKey* ecdsa = dynamic_cast<const ECDSA_PublicKey*>(&spec.key())) - { - const int nid = OpenSSL_EC_nid_for(ecdsa->domain().get_oid()); - if(nid > 0) - return new OpenSSL_ECDSA_Verification_Operation(*ecdsa, spec.padding(), nid); - } - - return nullptr; - } - OpenSSL_ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, const std::string& emsa, int nid) : PK_Ops::Verification_with_EMSA(emsa), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free) { @@ -158,20 +144,6 @@ class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EM class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA { public: - typedef ECDSA_PrivateKey Key_Type; - - static OpenSSL_ECDSA_Signing_Operation* make(const Spec& spec) - { - if(const ECDSA_PrivateKey* ecdsa = dynamic_cast<const ECDSA_PrivateKey*>(&spec.key())) - { - const int nid = OpenSSL_EC_nid_for(ecdsa->domain().get_oid()); - if(nid > 0) - return new OpenSSL_ECDSA_Signing_Operation(*ecdsa, spec.padding()); - } - - return nullptr; - } - OpenSSL_ECDSA_Signing_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_ossl_ec(nullptr, ::EC_KEY_free) @@ -213,35 +185,39 @@ class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA size_t m_order_bits = 0; }; -BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_ECDSA_Verification_Operation, "ECDSA", - OpenSSL_ECDSA_Verification_Operation::make, - "openssl", BOTAN_OPENSSL_ECDSA_PRIO); +} + +std::unique_ptr<PK_Ops::Verification> +make_openssl_ecdsa_ver_op(const ECDSA_PublicKey& key, const std::string& params) + { + const int nid = OpenSSL_EC_nid_for(key.domain().get_oid()); + if(nid > 0) + { + return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_ECDSA_Verification_Operation(key, params, nid)); + } + return {}; + } -BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_ECDSA_Signing_Operation, "ECDSA", - OpenSSL_ECDSA_Signing_Operation::make, - "openssl", BOTAN_OPENSSL_ECDSA_PRIO); +std::unique_ptr<PK_Ops::Signature> +make_openssl_ecdsa_sig_op(const ECDSA_PrivateKey& key, const std::string& params) + { + const int nid = OpenSSL_EC_nid_for(key.domain().get_oid()); + if(nid > 0) + return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_ECDSA_Signing_Operation(key, params)); + return {}; + } #endif #if defined(BOTAN_HAS_ECDH) && !defined(OPENSSL_NO_ECDH) +namespace { + class OpenSSL_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { public: typedef ECDH_PrivateKey Key_Type; - static OpenSSL_ECDH_KA_Operation* make(const Spec& spec) - { - if(const ECDH_PrivateKey* ecdh = dynamic_cast<const ECDH_PrivateKey*>(&spec.key())) - { - const int nid = OpenSSL_EC_nid_for(ecdh->domain().get_oid()); - if(nid > 0) - return new OpenSSL_ECDH_KA_Operation(*ecdh, spec.padding()); - } - - return nullptr; - } - OpenSSL_ECDH_KA_Operation(const ECDH_PrivateKey& ecdh, const std::string& kdf) : PK_Ops::Key_Agreement_with_KDF(kdf), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free) { @@ -291,13 +267,21 @@ class OpenSSL_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF size_t m_order_bits = 0; }; -BOTAN_REGISTER_TYPE(PK_Ops::Key_Agreement, OpenSSL_ECDH_KA_Operation, "ECDH", - OpenSSL_ECDH_KA_Operation::make, - "openssl", BOTAN_OPENSSL_ECDH_PRIO); +} -#endif +std::unique_ptr<PK_Ops::Key_Agreement> +make_openssl_ecdh_ka_op(const ECDH_PrivateKey& key, const std::string& params) + { + const int nid = OpenSSL_EC_nid_for(key.domain().get_oid()); + if(nid > 0) + { + return std::unique_ptr<PK_Ops::Key_Agreement>(new OpenSSL_ECDH_KA_Operation(key, params)); + } -} + return {}; + } + +#endif } diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp index ed8f2b0fd..5405ddda1 100644 --- a/src/lib/prov/openssl/openssl_rsa.cpp +++ b/src/lib/prov/openssl/openssl_rsa.cpp @@ -10,7 +10,7 @@ #if defined(BOTAN_HAS_RSA) #include <botan/rsa.h> -#include <botan/internal/pk_utils.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/internal/ct_utils.h> #include <functional> @@ -42,21 +42,6 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption public: typedef RSA_PublicKey Key_Type; - static OpenSSL_RSA_Encryption_Operation* make(const Spec& spec) - { - try - { - if(auto* key = dynamic_cast<const RSA_PublicKey*>(&spec.key())) - { - auto pad_info = get_openssl_enc_pad(spec.padding()); - return new OpenSSL_RSA_Encryption_Operation(*key, pad_info.first, pad_info.second); - } - } - catch(...) {} - - return nullptr; - } - OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) : m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) { @@ -113,21 +98,6 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption public: typedef RSA_PrivateKey Key_Type; - static OpenSSL_RSA_Decryption_Operation* make(const Spec& spec) - { - try - { - if(auto* key = dynamic_cast<const RSA_PrivateKey*>(&spec.key())) - { - auto pad_info = get_openssl_enc_pad(spec.padding()); - return new OpenSSL_RSA_Decryption_Operation(*key, pad_info.first); - } - } - catch(...) {} - - return nullptr; - } - OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) : m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad) { @@ -174,16 +144,6 @@ class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA public: typedef RSA_PublicKey Key_Type; - static OpenSSL_RSA_Verification_Operation* make(const Spec& spec) - { - if(const RSA_PublicKey* rsa = dynamic_cast<const RSA_PublicKey*>(&spec.key())) - { - return new OpenSSL_RSA_Verification_Operation(*rsa, spec.padding()); - } - - return nullptr; - } - OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), m_openssl_rsa(nullptr, ::RSA_free) @@ -225,16 +185,6 @@ class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA public: typedef RSA_PrivateKey Key_Type; - static OpenSSL_RSA_Signing_Operation* make(const Spec& spec) - { - if(const RSA_PrivateKey* rsa = dynamic_cast<const RSA_PrivateKey*>(&spec.key())) - { - return new OpenSSL_RSA_Signing_Operation(*rsa, spec.padding()); - } - - return nullptr; - } - OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), m_openssl_rsa(nullptr, ::RSA_free) @@ -273,19 +223,46 @@ class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa; }; -BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_RSA_Verification_Operation, "RSA", - OpenSSL_RSA_Verification_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); +} -BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_RSA_Signing_Operation, "RSA", - OpenSSL_RSA_Signing_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); +std::unique_ptr<PK_Ops::Encryption> +make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params) + { + try + { + auto pad_info = get_openssl_enc_pad(params); + return std::unique_ptr<PK_Ops::Encryption>( + new OpenSSL_RSA_Encryption_Operation(key, pad_info.first, pad_info.second)); + } + catch(...) {} + + return {}; + } -BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA", - OpenSSL_RSA_Encryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); +std::unique_ptr<PK_Ops::Decryption> +make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params) + { + try + { + auto pad_info = get_openssl_enc_pad(params); + return std::unique_ptr<PK_Ops::Decryption>(new OpenSSL_RSA_Decryption_Operation(key, pad_info.first)); + } + catch(...) {} + + return {}; + } -BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA", - OpenSSL_RSA_Decryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO); +std::unique_ptr<PK_Ops::Verification> +make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params) + { + return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_RSA_Verification_Operation(key, params)); + } -} +std::unique_ptr<PK_Ops::Signature> +make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params) + { + return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params)); + } } diff --git a/src/lib/prov/pkcs11/p11_ecdh.cpp b/src/lib/prov/pkcs11/p11_ecdh.cpp index de24d6da4..8d8d79db7 100644 --- a/src/lib/prov/pkcs11/p11_ecdh.cpp +++ b/src/lib/prov/pkcs11/p11_ecdh.cpp @@ -14,7 +14,7 @@ #include <botan/ber_dec.h> #include <botan/der_enc.h> #include <botan/internal/algo_registry.h> -#include <botan/internal/pk_utils.h> +#include <botan/pk_ops.h> #include <botan/rng.h> namespace Botan { @@ -43,26 +43,8 @@ namespace { class PKCS11_ECDH_KA_Operation : public PK_Ops::Key_Agreement { public: - typedef PKCS11_EC_PrivateKey Key_Type; - - static PKCS11_ECDH_KA_Operation* make_ecdh(const Spec& spec, bool use_cofactor) - { - try - { - if(auto* key = dynamic_cast< const PKCS11_EC_PrivateKey* >(&spec.key())) - { - return new PKCS11_ECDH_KA_Operation(*key, spec.padding(), use_cofactor); - } - } - catch(...) - { - } - - return nullptr; - } - - PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, const std::string& kdf, bool use_cofactor) - : PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(kdf, use_cofactor)) + PKCS11_ECDH_KA_Operation(const PKCS11_EC_PrivateKey& key, const std::string& params) + : PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(params)) {} @@ -112,14 +94,16 @@ class PKCS11_ECDH_KA_Operation : public PK_Ops::Key_Agreement MechanismWrapper m_mechanism; }; -Algo_Registry<PK_Ops::Key_Agreement>::Add g_PKCS11_ECDH_KA_Operation_reg("ECDH", - std::bind(&PKCS11_ECDH_KA_Operation::make_ecdh, std::placeholders::_1, false), "pkcs11", BOTAN_PKCS11_ECDH_PRIO); - -Algo_Registry<PK_Ops::Key_Agreement>::Add g_PKCS11_ECDHC_KA_Operation_reg("ECDHC", - std::bind(&PKCS11_ECDH_KA_Operation::make_ecdh, std::placeholders::_1, true), "pkcs11", BOTAN_PKCS11_ECDH_PRIO); - } +std::unique_ptr<PK_Ops::Key_Agreement> +PKCS11_ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator&, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Key_Agreement>(new PKCS11_ECDH_KA_Operation(*this, params)); + } + PKCS11_ECDH_KeyPair generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props) { diff --git a/src/lib/prov/pkcs11/p11_ecdh.h b/src/lib/prov/pkcs11/p11_ecdh.h index 749a00d52..ef9ccb250 100644 --- a/src/lib/prov/pkcs11/p11_ecdh.h +++ b/src/lib/prov/pkcs11/p11_ecdh.h @@ -102,6 +102,11 @@ class BOTAN_DLL PKCS11_ECDH_PrivateKey final : public virtual PKCS11_EC_PrivateK ECDH_PrivateKey export_key() const; secure_vector<byte> pkcs8_private_key() const override; + + std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; using PKCS11_ECDH_KeyPair = std::pair<PKCS11_ECDH_PublicKey, PKCS11_ECDH_PrivateKey>; diff --git a/src/lib/prov/pkcs11/p11_ecdsa.cpp b/src/lib/prov/pkcs11/p11_ecdsa.cpp index 078bc429d..9e21a3701 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.cpp +++ b/src/lib/prov/pkcs11/p11_ecdsa.cpp @@ -12,7 +12,7 @@ #include <botan/internal/p11_mechanism.h> #include <botan/internal/algo_registry.h> -#include <botan/internal/pk_utils.h> +#include <botan/pk_ops.h> #include <botan/keypair.h> #include <botan/rng.h> @@ -198,13 +198,23 @@ class PKCS11_ECDSA_Verification_Operation : public PK_Ops::Verification bool m_initialized = false; }; -BOTAN_REGISTER_TYPE(PK_Ops::Signature, PKCS11_ECDSA_Signature_Operation, "ECDSA", - (make_pk_op<PK_Ops::Signature, PKCS11_ECDSA_Signature_Operation>), "pkcs11", BOTAN_PKCS11_ECDSA_PRIO); +} -BOTAN_REGISTER_TYPE(PK_Ops::Verification, PKCS11_ECDSA_Verification_Operation, "ECDSA", - (make_pk_op<PK_Ops::Verification, PKCS11_ECDSA_Verification_Operation>), "pkcs11", BOTAN_PKCS11_ECDSA_PRIO); +std::unique_ptr<PK_Ops::Verification> +PKCS11_ECDSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Verification>(new PKCS11_ECDSA_Verification_Operation(*this, params)); + } -} +std::unique_ptr<PK_Ops::Signature> +PKCS11_ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new PKCS11_ECDSA_Signature_Operation(*this, params)); + } PKCS11_ECDSA_KeyPair generate_ecdsa_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props) diff --git a/src/lib/prov/pkcs11/p11_ecdsa.h b/src/lib/prov/pkcs11/p11_ecdsa.h index d3d07a780..d391ce0b9 100644 --- a/src/lib/prov/pkcs11/p11_ecdsa.h +++ b/src/lib/prov/pkcs11/p11_ecdsa.h @@ -55,6 +55,11 @@ class BOTAN_DLL PKCS11_ECDSA_PublicKey final : public PKCS11_EC_PublicKey, publi /// @return the exported ECDSA public key ECDSA_PublicKey export_key() const; + + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; /// Represents a PKCS#11 ECDSA private key @@ -107,6 +112,11 @@ class BOTAN_DLL PKCS11_ECDSA_PrivateKey final : public PKCS11_EC_PrivateKey secure_vector<byte> pkcs8_private_key() const override; bool check_key(RandomNumberGenerator&, bool) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; using PKCS11_ECDSA_KeyPair = std::pair<PKCS11_ECDSA_PublicKey, PKCS11_ECDSA_PrivateKey>; diff --git a/src/lib/prov/pkcs11/p11_mechanism.cpp b/src/lib/prov/pkcs11/p11_mechanism.cpp index 07ac00770..a4c6e73a7 100644 --- a/src/lib/prov/pkcs11/p11_mechanism.cpp +++ b/src/lib/prov/pkcs11/p11_mechanism.cpp @@ -219,8 +219,18 @@ MechanismWrapper MechanismWrapper::create_ecdsa_mechanism(const std::string& has return MechanismWrapper(mechanism_type->second); } -MechanismWrapper MechanismWrapper::create_ecdh_mechanism(const std::string& kdf_name, bool use_cofactor) +MechanismWrapper MechanismWrapper::create_ecdh_mechanism(const std::string& params) { + std::vector<std::string> param_parts = split_on(params, ','); + + if(param_parts.empty() || param_parts.size() > 2) + throw Invalid_Argument("PKCS #11 ECDH key derivation bad params " + params); + + const bool use_cofactor = + (param_parts[0] == "Cofactor") || + (param_parts.size() == 2 && param_parts[1] == "Cofactor"); + + std::string kdf_name = (param_parts[0] == "Cofactor" ? param_parts[1] : param_parts[0]); std::string hash = kdf_name; if(kdf_name != "Raw") diff --git a/src/lib/prov/pkcs11/p11_mechanism.h b/src/lib/prov/pkcs11/p11_mechanism.h index 5d8c826ee..0f7b6f07c 100644 --- a/src/lib/prov/pkcs11/p11_mechanism.h +++ b/src/lib/prov/pkcs11/p11_mechanism.h @@ -51,10 +51,12 @@ class MechanismWrapper final /** * Creates the CK_MECHANISM data for ECDH key derivation (CKM_ECDH1_DERIVE or CKM_ECDH1_COFACTOR_DERIVE) - * @param kdf_name the key derivation function to use. Supported KDFs are Raw and SHA-160 to SHA-512 - * @param use_cofactor true if the cofactor key derivation mechanism should be used + * @param params specifies the key derivation function to use. + * Supported KDFs are Raw and SHA-160 to SHA-512. + * Params can also include the string "Cofactor" if the cofactor + * key derivation mechanism should be used, for example "SHA-512,Cofactor" */ - static MechanismWrapper create_ecdh_mechanism(const std::string& kdf_name, bool use_cofactor); + static MechanismWrapper create_ecdh_mechanism(const std::string& params); /// Sets the salt for the ECDH mechanism parameters inline void set_ecdh_salt(const byte salt[], size_t salt_len) diff --git a/src/lib/prov/pkcs11/p11_rsa.cpp b/src/lib/prov/pkcs11/p11_rsa.cpp index 9e5675301..18965fd95 100644 --- a/src/lib/prov/pkcs11/p11_rsa.cpp +++ b/src/lib/prov/pkcs11/p11_rsa.cpp @@ -13,7 +13,7 @@ #include <botan/internal/p11_mechanism.h> #include <botan/pk_ops.h> #include <botan/internal/algo_registry.h> -#include <botan/internal/pk_utils.h> +#include <botan/pk_ops.h> #include <botan/rng.h> #include <botan/blinding.h> @@ -125,14 +125,18 @@ secure_vector<byte> PKCS11_RSA_PrivateKey::pkcs8_private_key() const namespace { // note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal) // are not supported (PK_Ops::Decryption does not provide an `update` method) -class PKCS11_RSA_Decryption_Operation : public PK_Ops::Decryption +class PKCS11_RSA_Decryption_Operation final : public PK_Ops::Decryption { public: typedef PKCS11_RSA_PrivateKey Key_Type; - PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key, const std::string& padding) - : m_key(key), m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)), - m_powermod(m_key.get_e(), m_key.get_n()), m_blinder(m_key.get_n(), + PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key, + const std::string& padding, + RandomNumberGenerator& rng) + : m_key(key), + m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)), + m_powermod(m_key.get_e(), m_key.get_n()), + m_blinder(m_key.get_n(), rng, [ this ](const BigInt& k) { return m_powermod(k); }, [ this ](const BigInt& k) { return inverse_mod(k, m_key.get_n()); }) { @@ -343,19 +347,39 @@ class PKCS11_RSA_Verification_Operation : public PK_Ops::Verification MechanismWrapper m_mechanism; }; -BOTAN_REGISTER_TYPE(PK_Ops::Decryption, PKCS11_RSA_Decryption_Operation, "RSA", - (make_pk_op<PK_Ops::Decryption, PKCS11_RSA_Decryption_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO); +} -BOTAN_REGISTER_TYPE(PK_Ops::Encryption, PKCS11_RSA_Encryption_Operation, "RSA", - (make_pk_op<PK_Ops::Encryption, PKCS11_RSA_Encryption_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO); +std::unique_ptr<PK_Ops::Encryption> +PKCS11_RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Encryption>(new PKCS11_RSA_Encryption_Operation(*this, params)); + } -BOTAN_REGISTER_TYPE(PK_Ops::Signature, PKCS11_RSA_Signature_Operation, "RSA", - (make_pk_op<PK_Ops::Signature, PKCS11_RSA_Signature_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO); +std::unique_ptr<PK_Ops::Verification> +PKCS11_RSA_PublicKey::create_verification_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Verification>(new PKCS11_RSA_Verification_Operation(*this, params)); + } -BOTAN_REGISTER_TYPE(PK_Ops::Verification, PKCS11_RSA_Verification_Operation, "RSA", - (make_pk_op<PK_Ops::Verification, PKCS11_RSA_Verification_Operation>), "pkcs11", BOTAN_PKCS11_RSA_PRIO); +std::unique_ptr<PK_Ops::Decryption> +PKCS11_RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Decryption>(new PKCS11_RSA_Decryption_Operation(*this, params, rng)); + } -} +std::unique_ptr<PK_Ops::Signature> +PKCS11_RSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Signature>(new PKCS11_RSA_Signature_Operation(*this, params)); + } PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props, const RSA_PrivateKeyGenerationProperties& priv_props) @@ -374,4 +398,5 @@ PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session, const RSA_PublicKeyGen } } + #endif diff --git a/src/lib/prov/pkcs11/p11_rsa.h b/src/lib/prov/pkcs11/p11_rsa.h index 2739cf3e5..6a085a7d7 100644 --- a/src/lib/prov/pkcs11/p11_rsa.h +++ b/src/lib/prov/pkcs11/p11_rsa.h @@ -83,6 +83,16 @@ class BOTAN_DLL PKCS11_RSA_PublicKey final : public RSA_PublicKey, * @param pubkey_props the attributes of the public key */ PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props); + + std::unique_ptr<PK_Ops::Encryption> + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; /// Properties for importing a PKCS#11 RSA private key @@ -192,6 +202,16 @@ class BOTAN_DLL PKCS11_RSA_PrivateKey final : public Private_Key, RSA_PrivateKey export_key() const; secure_vector<byte> pkcs8_private_key() const override; + + std::unique_ptr<PK_Ops::Decryption> + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; using PKCS11_RSA_KeyPair = std::pair<PKCS11_RSA_PublicKey, PKCS11_RSA_PrivateKey>; diff --git a/src/lib/prov/tpm/tpm.cpp b/src/lib/prov/tpm/tpm.cpp index c0b265b98..73eb063ce 100644 --- a/src/lib/prov/tpm/tpm.cpp +++ b/src/lib/prov/tpm/tpm.cpp @@ -11,7 +11,7 @@ #include <botan/hash_id.h> #include <botan/der_enc.h> #include <botan/workfactor.h> -#include <botan/internal/pk_utils.h> +#include <botan/pk_ops.h> #include <sstream> #include <tss/platform.h> @@ -386,18 +386,6 @@ namespace { class TPM_Signing_Operation : public PK_Ops::Signature { public: - static TPM_Signing_Operation* make(const Spec& spec) - { - if(auto* key = dynamic_cast<const TPM_PrivateKey*>(&spec.key())) - { - const std::string padding = spec.padding(); - const std::string hash = "SHA-256"; // TODO - return new TPM_Signing_Operation(*key, hash); - } - - return nullptr; - } - TPM_Signing_Operation(const TPM_PrivateKey& key, const std::string& hash_name) : m_key(key), @@ -454,7 +442,12 @@ class TPM_Signing_Operation : public PK_Ops::Signature } -BOTAN_REGISTER_TYPE(PK_Ops::Signature, TPM_Signing_Operation, "RSA", - TPM_Signing_Operation::make, "tpm", 100); +std::unique_ptr<PK_Ops::Signature> +TPM_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new TPM_Signing_Operation(*this, params)); + } } diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h index b8093518c..413896df1 100644 --- a/src/lib/prov/tpm/tpm.h +++ b/src/lib/prov/tpm/tpm.h @@ -162,6 +162,11 @@ class BOTAN_DLL TPM_PrivateKey : public Private_Key std::string algo_name() const override { return "RSA"; } // ??? + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + private: BigInt get_n() const; BigInt get_e() const; diff --git a/src/lib/pubkey/blinding.cpp b/src/lib/pubkey/blinding.cpp index b20a30fa1..47436bcb0 100644 --- a/src/lib/pubkey/blinding.cpp +++ b/src/lib/pubkey/blinding.cpp @@ -8,25 +8,21 @@ #include <botan/blinding.h> #include <botan/numthry.h> -#if defined(BOTAN_HAS_SYSTEM_RNG) - #include <botan/system_rng.h> -#else - #include <botan/auto_rng.h> -#endif - namespace Botan { Blinder::Blinder(const BigInt& modulus, + RandomNumberGenerator& rng, std::function<BigInt (const BigInt&)> fwd, std::function<BigInt (const BigInt&)> inv) : - m_reducer{Modular_Reducer(modulus)}, m_rng{}, m_fwd_fn(fwd), m_inv_fn(inv), m_modulus_bits{modulus.bits()}, m_e{}, m_d{}, m_counter{} + m_reducer(modulus), + m_rng(rng), + m_fwd_fn(fwd), + m_inv_fn(inv), + m_modulus_bits(modulus.bits()), + m_e{}, + m_d{}, + m_counter{} { -#if defined(BOTAN_HAS_SYSTEM_RNG) - m_rng.reset(new System_RNG); -#else - m_rng.reset(new AutoSeeded_RNG); -#endif - const BigInt k = blinding_nonce(); m_e = m_fwd_fn(k); m_d = m_inv_fn(k); @@ -34,7 +30,7 @@ Blinder::Blinder(const BigInt& modulus, BigInt Blinder::blinding_nonce() const { - return BigInt(*m_rng, m_modulus_bits - 1); + return BigInt(m_rng, m_modulus_bits - 1); } BigInt Blinder::blind(const BigInt& i) const @@ -44,11 +40,12 @@ BigInt Blinder::blind(const BigInt& i) const ++m_counter; - if(BOTAN_BLINDING_REINIT_INTERVAL > 0 && (m_counter % BOTAN_BLINDING_REINIT_INTERVAL == 0)) + if((BOTAN_BLINDING_REINIT_INTERVAL > 0) && (m_counter > BOTAN_BLINDING_REINIT_INTERVAL)) { const BigInt k = blinding_nonce(); m_e = m_fwd_fn(k); m_d = m_inv_fn(k); + m_counter = 0; } else { diff --git a/src/lib/pubkey/blinding.h b/src/lib/pubkey/blinding.h index c1999feb7..a6b266807 100644 --- a/src/lib/pubkey/blinding.h +++ b/src/lib/pubkey/blinding.h @@ -26,11 +26,8 @@ class BOTAN_DLL Blinder BigInt unblind(const BigInt& x) const; - bool initialized() const { return m_reducer.initialized(); } - - Blinder() {} - Blinder(const BigInt& modulus, + RandomNumberGenerator& rng, std::function<BigInt (const BigInt&)> fwd_func, std::function<BigInt (const BigInt&)> inv_func); @@ -42,7 +39,7 @@ class BOTAN_DLL Blinder BigInt blinding_nonce() const; Modular_Reducer m_reducer; - std::unique_ptr<RandomNumberGenerator> m_rng; + RandomNumberGenerator& m_rng; std::function<BigInt (const BigInt&)> m_fwd_fn; std::function<BigInt (const BigInt&)> m_inv_fn; size_t m_modulus_bits = 0; diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp index aa0646d04..b1dfc59a1 100644 --- a/src/lib/pubkey/curve25519/curve25519.cpp +++ b/src/lib/pubkey/curve25519/curve25519.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/curve25519.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/ber_dec.h> #include <botan/der_enc.h> @@ -134,9 +134,14 @@ class Curve25519_KA_Operation : public PK_Ops::Key_Agreement_with_KDF const Curve25519_PrivateKey& m_key; }; -BOTAN_REGISTER_PK_KEY_AGREE_OP("Curve25519", Curve25519_KA_Operation); - } +std::unique_ptr<PK_Ops::Key_Agreement> +Curve25519_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 Curve25519_KA_Operation(*this, params)); + } } diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h index 9d2868d6d..fe39d9dd6 100644 --- a/src/lib/pubkey/curve25519/curve25519.h +++ b/src/lib/pubkey/curve25519/curve25519.h @@ -33,6 +33,7 @@ class BOTAN_DLL Curve25519_PublicKey : public virtual Public_Key const secure_vector<byte>& key_bits); explicit Curve25519_PublicKey(const secure_vector<byte>& pub) : m_public(pub) {} + protected: Curve25519_PublicKey() {} secure_vector<byte> m_public; @@ -60,6 +61,12 @@ class BOTAN_DLL Curve25519_PrivateKey : public Curve25519_PublicKey, secure_vector<byte> pkcs8_private_key() const override; bool check_key(RandomNumberGenerator& rng, bool strong) const override; + + std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + private: secure_vector<byte> m_private; }; diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp index 8ed79aa3d..3cd47c581 100644 --- a/src/lib/pubkey/dh/dh.cpp +++ b/src/lib/pubkey/dh/dh.cpp @@ -1,12 +1,12 @@ /* * Diffie-Hellman -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/dh.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/workfactor.h> #include <botan/pow_mod.h> #include <botan/blinding.h> @@ -41,7 +41,7 @@ DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, m_group = grp; m_x = x_arg; - if(m_x == 0) + if(generate) { const BigInt& p = group_p(); m_x.randomize(rng, dl_exponent_size(p.bits())); @@ -93,7 +93,16 @@ class DH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { public: typedef DH_PrivateKey Key_Type; - DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf); + + DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) : + PK_Ops::Key_Agreement_with_KDF(kdf), + m_p(key.group_p()), + m_powermod_x_p(key.get_x(), m_p), + m_blinder(m_p, + rng, + [](const BigInt& k) { return k; }, + [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) + {} secure_vector<byte> raw_agree(const byte w[], size_t w_len) override; private: @@ -103,16 +112,6 @@ class DH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF Blinder m_blinder; }; -DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh, const std::string& kdf) : - PK_Ops::Key_Agreement_with_KDF(kdf), - m_p(dh.group_p()), - m_powermod_x_p(dh.get_x(), m_p), - m_blinder(m_p, - [](const BigInt& k) { return k; }, - [this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); }) - { - } - secure_vector<byte> DH_KA_Operation::raw_agree(const byte w[], size_t w_len) { BigInt input = BigInt::decode(w, w_len); @@ -127,6 +126,12 @@ secure_vector<byte> DH_KA_Operation::raw_agree(const byte w[], size_t w_len) } -BOTAN_REGISTER_PK_KEY_AGREE_OP("DH", DH_KA_Operation); +std::unique_ptr<PK_Ops::Key_Agreement> +DH_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 DH_KA_Operation(*this, params, rng)); + } } diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h index 9911453fb..d15bc5eb3 100644 --- a/src/lib/pubkey/dh/dh.h +++ b/src/lib/pubkey/dh/dh.h @@ -67,6 +67,11 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, */ DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, const BigInt& x = 0); + + std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; } diff --git a/src/lib/pubkey/dlies/dlies.cpp b/src/lib/pubkey/dlies/dlies.cpp index 9666a1c23..09f24adb7 100644 --- a/src/lib/pubkey/dlies/dlies.cpp +++ b/src/lib/pubkey/dlies/dlies.cpp @@ -12,14 +12,16 @@ namespace Botan { DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, MessageAuthenticationCode* mac, size_t mac_key_length) : - DLIES_Encryptor(own_priv_key, kdf, nullptr, 0, mac, mac_key_length) + DLIES_Encryptor(own_priv_key, rng, kdf, nullptr, 0, mac, mac_key_length) { } DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, Cipher_Mode* cipher, size_t cipher_key_len, @@ -27,7 +29,7 @@ DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key, size_t mac_key_length) : m_other_pub_key(), m_own_pub_key(own_priv_key.public_value()), - m_ka(own_priv_key, "Raw"), + m_ka(own_priv_key, rng, "Raw"), m_kdf(kdf), m_cipher(cipher), m_cipher_key_len(cipher_key_len), @@ -111,13 +113,14 @@ size_t DLIES_Encryptor::maximum_input_size() const } DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, Cipher_Mode* cipher, size_t cipher_key_len, MessageAuthenticationCode* mac, size_t mac_key_length) : m_pub_key_size(own_priv_key.public_value().size()), - m_ka(own_priv_key, "Raw"), + m_ka(own_priv_key, rng, "Raw"), m_kdf(kdf), m_cipher(cipher), m_cipher_key_len(cipher_key_len), @@ -130,10 +133,11 @@ DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key, } DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, MessageAuthenticationCode* mac, size_t mac_key_length) : - DLIES_Decryptor(own_priv_key, kdf, nullptr, 0, mac, mac_key_length) + DLIES_Decryptor(own_priv_key, rng, kdf, nullptr, 0, mac, mac_key_length) {} secure_vector<byte> DLIES_Decryptor::do_decrypt(byte& valid_mask, diff --git a/src/lib/pubkey/dlies/dlies.h b/src/lib/pubkey/dlies/dlies.h index 5f7251d03..f6bf9c6dd 100644 --- a/src/lib/pubkey/dlies/dlies.h +++ b/src/lib/pubkey/dlies/dlies.h @@ -34,6 +34,7 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor * output = (ephemeral) public key + ciphertext + tag */ DLIES_Encryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, MessageAuthenticationCode* mac, size_t mac_key_len = 20); @@ -51,6 +52,7 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor * output = (ephemeral) public key + ciphertext + tag */ DLIES_Encryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, Cipher_Mode* cipher, size_t cipher_key_len, @@ -103,6 +105,7 @@ class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor * input = (ephemeral) public key + ciphertext + tag */ DLIES_Decryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, MessageAuthenticationCode* mac, size_t mac_key_len = 20); @@ -120,6 +123,7 @@ class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor * input = (ephemeral) public key + ciphertext + tag */ DLIES_Decryptor(const DH_PrivateKey& own_priv_key, + RandomNumberGenerator& rng, KDF* kdf, Cipher_Mode* cipher, size_t cipher_key_len, diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index 399756b1a..00d7b77d7 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -1,20 +1,22 @@ /* * DSA -* (C) 1999-2010,2014 Jack Lloyd +* (C) 1999-2010,2014,2016 Jack Lloyd * (C) 2016 René Korthaus * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/dsa.h> #include <botan/keypair.h> #include <botan/pow_mod.h> #include <botan/reducer.h> +#include <botan/internal/pk_ops_impl.h> + #if defined(BOTAN_HAS_RFC6979_GENERATOR) - #include <botan/rfc6979.h> #include <botan/emsa.h> + #include <botan/rfc6979.h> #endif + #include <future> namespace Botan { @@ -193,9 +195,22 @@ bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len, return (m_mod_q.reduce(s) == r); } -BOTAN_REGISTER_PK_SIGNATURE_OP("DSA", DSA_Signature_Operation); -BOTAN_REGISTER_PK_VERIFY_OP("DSA", DSA_Verification_Operation); - } +std::unique_ptr<PK_Ops::Verification> +DSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Verification>(new DSA_Verification_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Signature> +DSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new DSA_Signature_Operation(*this, params)); + } + } diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h index 2653c9229..d8cd61df5 100644 --- a/src/lib/pubkey/dsa/dsa.h +++ b/src/lib/pubkey/dsa/dsa.h @@ -32,6 +32,11 @@ class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey } DSA_PublicKey(const DL_Group& group, const BigInt& y); + + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; protected: DSA_PublicKey() {} }; @@ -52,6 +57,11 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, const BigInt& private_key = 0); bool check_key(RandomNumberGenerator& rng, bool strong) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; }; } diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp index 55e215bc1..79c63da8c 100644 --- a/src/lib/pubkey/ecdh/ecdh.cpp +++ b/src/lib/pubkey/ecdh/ecdh.cpp @@ -7,8 +7,12 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/ecdh.h> +#include <botan/internal/pk_ops_impl.h> + +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> +#endif namespace Botan { @@ -47,6 +51,22 @@ class ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF } -BOTAN_REGISTER_PK_KEY_AGREE_OP("ECDH", ECDH_KA_Operation); +std::unique_ptr<PK_Ops::Key_Agreement> +ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Key_Agreement> res = make_openssl_ecdh_ka_op(*this, params); + if(res) + return res; + } +#endif + + return std::unique_ptr<PK_Ops::Key_Agreement>(new ECDH_KA_Operation(*this, params)); + } + } diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h index bdd9ea047..5b6ec7261 100644 --- a/src/lib/pubkey/ecdh/ecdh.h +++ b/src/lib/pubkey/ecdh/ecdh.h @@ -94,6 +94,11 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, std::vector<byte> public_value(PointGFp::Compression_Type type) const { return ECDH_PublicKey::public_value(type); } + + std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; } diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp index 264a36963..6a81ababf 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.cpp +++ b/src/lib/pubkey/ecdsa/ecdsa.cpp @@ -2,18 +2,24 @@ * ECDSA implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * 2007 Falko Strenzke, FlexSecure GmbH -* 2008-2010,2015 Jack Lloyd +* 2008-2010,2015,2016 Jack Lloyd * 2016 René Korthaus * * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/ecdsa.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/keypair.h> +#include <botan/reducer.h> +#include <botan/emsa.h> + #if defined(BOTAN_HAS_RFC6979_GENERATOR) #include <botan/rfc6979.h> - #include <botan/emsa.h> +#endif + +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> #endif namespace Botan { @@ -150,9 +156,39 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, return (v == r); } -BOTAN_REGISTER_PK_SIGNATURE_OP("ECDSA", ECDSA_Signature_Operation); -BOTAN_REGISTER_PK_VERIFY_OP("ECDSA", ECDSA_Verification_Operation); - } +std::unique_ptr<PK_Ops::Verification> +ECDSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Verification> res = make_openssl_ecdsa_ver_op(*this, params); + if(res) + return res; + } +#endif + return std::unique_ptr<PK_Ops::Verification>(new ECDSA_Verification_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Signature> +ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Signature> res = make_openssl_ecdsa_sig_op(*this, params); + if(res) + return res; + } +#endif + + return std::unique_ptr<PK_Ops::Signature>(new ECDSA_Signature_Operation(*this, params)); + } + } diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h index eed09afe6..9a55fbe48 100644 --- a/src/lib/pubkey/ecdsa/ecdsa.h +++ b/src/lib/pubkey/ecdsa/ecdsa.h @@ -53,6 +53,10 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey size_t message_part_size() const override { return domain().get_order().bytes(); } + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; protected: ECDSA_PublicKey() {} }; @@ -86,6 +90,11 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, EC_PrivateKey(rng, domain, x) {} bool check_key(RandomNumberGenerator& rng, bool) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; }; } diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp index 30ea32817..b112a4466 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp +++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp @@ -5,9 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/ecgdsa.h> #include <botan/keypair.h> +#include <botan/reducer.h> +#include <botan/internal/pk_ops_impl.h> namespace Botan { @@ -137,9 +138,22 @@ bool ECGDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, return (v == r); } -BOTAN_REGISTER_PK_SIGNATURE_OP("ECGDSA", ECGDSA_Signature_Operation); -BOTAN_REGISTER_PK_VERIFY_OP("ECGDSA", ECGDSA_Verification_Operation); - } +std::unique_ptr<PK_Ops::Verification> +ECGDSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Verification>(new ECGDSA_Verification_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Signature> +ECGDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new ECGDSA_Signature_Operation(*this, params)); + } + } diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h index 518adeeab..ec9180ee5 100644 --- a/src/lib/pubkey/ecgdsa/ecgdsa.h +++ b/src/lib/pubkey/ecgdsa/ecgdsa.h @@ -51,6 +51,10 @@ class BOTAN_DLL ECGDSA_PublicKey : public virtual EC_PublicKey size_t message_part_size() const override { return domain().get_order().bytes(); } + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; protected: ECGDSA_PublicKey() {} }; @@ -84,6 +88,11 @@ class BOTAN_DLL ECGDSA_PrivateKey : public ECGDSA_PublicKey, EC_PrivateKey(rng, domain, x, true) {} bool check_key(RandomNumberGenerator& rng, bool) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; }; } diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp index d44d14803..d2e453bdf 100644 --- a/src/lib/pubkey/ecies/ecies.cpp +++ b/src/lib/pubkey/ecies/ecies.cpp @@ -10,7 +10,7 @@ #include <botan/cipher_mode.h> #include <botan/internal/ct_utils.h> -#include <botan/internal/pk_utils.h> +#include <botan/internal/pk_ops_impl.h> namespace Botan { @@ -45,6 +45,11 @@ class ECIES_PrivateKey : public EC_PrivateKey, public PK_Key_Agreement_Key return m_key.max_input_bits(); } + std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + private: ECDH_PrivateKey m_key; }; @@ -55,9 +60,7 @@ class ECIES_PrivateKey : public EC_PrivateKey, public PK_Key_Agreement_Key class ECIES_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF { public: - typedef ECIES_PrivateKey Key_Type; - - ECIES_ECDH_KA_Operation(const ECIES_PrivateKey& private_key, const std::string&) : + ECIES_ECDH_KA_Operation(const ECIES_PrivateKey& private_key) : PK_Ops::Key_Agreement_with_KDF("Raw"), m_key(private_key) { @@ -76,6 +79,14 @@ class ECIES_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF ECIES_PrivateKey m_key; }; +std::unique_ptr<PK_Ops::Key_Agreement> +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)); + } + /** * Creates a PK_Key_Agreement instance for the given key and ecies_params * Returns either ECIES_ECDH_KA_Operation or the default implementation for the given key, @@ -110,8 +121,6 @@ PK_Key_Agreement create_key_agreement(const PK_Key_Agreement_Key& private_key, c } } -BOTAN_REGISTER_PK_KEY_AGREE_OP("ECIES", ECIES_ECDH_KA_Operation); - ECIES_KA_Operation::ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key, const ECIES_KA_Params& ecies_params, bool for_encryption) : m_ka(create_key_agreement(private_key, ecies_params, for_encryption)), diff --git a/src/lib/pubkey/ecies/info.txt b/src/lib/pubkey/ecies/info.txt index 12776f8c2..fb35e7b97 100644 --- a/src/lib/pubkey/ecies/info.txt +++ b/src/lib/pubkey/ecies/info.txt @@ -5,4 +5,4 @@ kdf mac ecdh modes -</requires>
\ No newline at end of file +</requires> diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp index 5ca89675c..e61ceaa19 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -5,9 +5,10 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/eckcdsa.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/keypair.h> +#include <botan/reducer.h> #include <botan/emsa.h> #include <botan/hash.h> @@ -192,9 +193,22 @@ bool ECKCDSA_Verification_Operation::verify(const byte msg[], size_t, return (v == r); } -BOTAN_REGISTER_PK_SIGNATURE_OP("ECKCDSA", ECKCDSA_Signature_Operation); -BOTAN_REGISTER_PK_VERIFY_OP("ECKCDSA", ECKCDSA_Verification_Operation); - } +std::unique_ptr<PK_Ops::Verification> +ECKCDSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Verification>(new ECKCDSA_Verification_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Signature> +ECKCDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new ECKCDSA_Signature_Operation(*this, params)); + } + } diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h index b85c4025e..f8514776b 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.h +++ b/src/lib/pubkey/eckcdsa/eckcdsa.h @@ -51,6 +51,10 @@ class BOTAN_DLL ECKCDSA_PublicKey : public virtual EC_PublicKey size_t message_part_size() const override { return domain().get_order().bytes(); } + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; protected: ECKCDSA_PublicKey() {} }; @@ -84,6 +88,11 @@ class BOTAN_DLL ECKCDSA_PrivateKey : public ECKCDSA_PublicKey, EC_PrivateKey(rng, domain, x, true) {} bool check_key(RandomNumberGenerator& rng, bool) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; }; } diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp index 37dfe89cf..fbbd09226 100644 --- a/src/lib/pubkey/elgamal/elgamal.cpp +++ b/src/lib/pubkey/elgamal/elgamal.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/elgamal.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/keypair.h> #include <botan/reducer.h> #include <botan/blinding.h> @@ -134,7 +134,9 @@ class ElGamal_Decryption_Operation : public PK_Ops::Decryption_with_EME size_t max_raw_input_bits() const override { return m_mod_p.get_modulus().bits() - 1; } - ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& eme); + ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, + const std::string& eme, + RandomNumberGenerator& rng); secure_vector<byte> raw_decrypt(const byte msg[], size_t msg_len) override; private: @@ -144,13 +146,15 @@ class ElGamal_Decryption_Operation : public PK_Ops::Decryption_with_EME }; ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, - const std::string& eme) : + const std::string& eme, + RandomNumberGenerator& rng) : PK_Ops::Decryption_with_EME(eme), m_powermod_x_p(Fixed_Exponent_Power_Mod(key.get_x(), key.group_p())), m_mod_p(Modular_Reducer(key.group_p())), m_blinder(key.group_p(), - [](const BigInt& k) { return k; }, - [this](const BigInt& k) { return m_powermod_x_p(k); }) + rng, + [](const BigInt& k) { return k; }, + [this](const BigInt& k) { return m_powermod_x_p(k); }) { } @@ -177,9 +181,22 @@ ElGamal_Decryption_Operation::raw_decrypt(const byte msg[], size_t msg_len) return BigInt::encode_1363(m_blinder.unblind(r), p_bytes); } -BOTAN_REGISTER_PK_ENCRYPTION_OP("ElGamal", ElGamal_Encryption_Operation); -BOTAN_REGISTER_PK_DECRYPTION_OP("ElGamal", ElGamal_Decryption_Operation); - } +std::unique_ptr<PK_Ops::Encryption> +ElGamal_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Encryption>(new ElGamal_Encryption_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Decryption> +ElGamal_PrivateKey::create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::Decryption>(new ElGamal_Decryption_Operation(*this, params, rng)); + } + } diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h index 9f287158d..8ca4facc2 100644 --- a/src/lib/pubkey/elgamal/elgamal.h +++ b/src/lib/pubkey/elgamal/elgamal.h @@ -29,6 +29,12 @@ class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey {} ElGamal_PublicKey(const DL_Group& group, const BigInt& y); + + std::unique_ptr<PK_Ops::Encryption> + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + protected: ElGamal_PublicKey() {} }; @@ -49,6 +55,11 @@ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, ElGamal_PrivateKey(RandomNumberGenerator& rng, const DL_Group& group, const BigInt& priv_key = 0); + + std::unique_ptr<PK_Ops::Decryption> + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; }; } diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index 51db47619..c37c8c845 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -7,8 +7,9 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/gost_3410.h> +#include <botan/internal/pk_ops_impl.h> +#include <botan/reducer.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> @@ -212,7 +213,20 @@ 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); +std::unique_ptr<PK_Ops::Verification> +GOST_3410_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Verification>(new GOST_3410_Verification_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Signature> +GOST_3410_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { + return std::unique_ptr<PK_Ops::Signature>(new GOST_3410_Signature_Operation(*this, params)); + } } diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h index 62a627c37..9d79f48d7 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.h +++ b/src/lib/pubkey/gost_3410/gost_3410.h @@ -59,6 +59,11 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey size_t message_part_size() const override { return domain().get_order().bytes(); } + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + protected: GOST_3410_PublicKey() {} }; @@ -88,6 +93,11 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, AlgorithmIdentifier pkcs8_algorithm_identifier() const override { return EC_PublicKey::algorithm_identifier(); } + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; }; } diff --git a/src/lib/pubkey/info.txt b/src/lib/pubkey/info.txt index 10eb12567..393e089e2 100644 --- a/src/lib/pubkey/info.txt +++ b/src/lib/pubkey/info.txt @@ -23,7 +23,6 @@ workfactor.h <header:internal> pk_algs.h -pk_utils.h pk_ops_impl.h </header:internal> diff --git a/src/lib/pubkey/keypair/keypair.cpp b/src/lib/pubkey/keypair/keypair.cpp index 0f5a48541..6ea514d34 100644 --- a/src/lib/pubkey/keypair/keypair.cpp +++ b/src/lib/pubkey/keypair/keypair.cpp @@ -19,8 +19,8 @@ bool encryption_consistency_check(RandomNumberGenerator& rng, const Private_Key& key, const std::string& padding) { - PK_Encryptor_EME encryptor(key, padding); - PK_Decryptor_EME decryptor(key, padding); + PK_Encryptor_EME encryptor(key, rng, padding); + PK_Decryptor_EME decryptor(key, rng, padding); /* Weird corner case, if the key is too small to encrypt anything at @@ -48,8 +48,8 @@ bool signature_consistency_check(RandomNumberGenerator& rng, const Private_Key& key, const std::string& padding) { - PK_Signer signer(key, padding); - PK_Verifier verifier(key, padding); + PK_Signer signer(key, rng, padding); + PK_Verifier verifier(key, rng, padding); std::vector<byte> message = unlock(rng.random_vec(16)); diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h index 311f0f253..c8b2606c5 100644 --- a/src/lib/pubkey/mce/mceliece.h +++ b/src/lib/pubkey/mce/mceliece.h @@ -58,6 +58,11 @@ class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key bool operator==(const McEliece_PublicKey& other) const; bool operator!=(const McEliece_PublicKey& other) const { return !(*this == other); } + std::unique_ptr<PK_Ops::KEM_Encryption> + create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + protected: McEliece_PublicKey() : m_t(0), m_code_length(0) {} @@ -115,6 +120,10 @@ class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey, bool operator!=(const McEliece_PrivateKey& other) const { return !(*this == other); } + std::unique_ptr<PK_Ops::KEM_Decryption> + create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; private: polyn_gf2m m_g; std::vector<polyn_gf2m> m_sqrtmod; diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp index 455d1f381..b5eed5a38 100644 --- a/src/lib/pubkey/mce/mceliece_key.cpp +++ b/src/lib/pubkey/mce/mceliece_key.cpp @@ -15,7 +15,6 @@ #include <botan/internal/bit_ops.h> #include <botan/internal/code_based_util.h> #include <botan/internal/pk_ops_impl.h> -#include <botan/internal/pk_utils.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> @@ -352,11 +351,24 @@ class MCE_KEM_Decryptor : public PK_Ops::KEM_Decryption_with_KDF const McEliece_PrivateKey& m_key; }; -BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP("McEliece", MCE_KEM_Encryptor); -BOTAN_REGISTER_PK_KEM_DECRYPTION_OP("McEliece", MCE_KEM_Decryptor); - } +std::unique_ptr<PK_Ops::KEM_Encryption> +McEliece_PublicKey::create_kem_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::KEM_Encryption>(new MCE_KEM_Encryptor(*this, params)); + } + +std::unique_ptr<PK_Ops::KEM_Decryption> +McEliece_PrivateKey::create_kem_decryption_op(RandomNumberGenerator& /*rng*/, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::KEM_Decryption>(new MCE_KEM_Decryptor(*this, params)); + } + } diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp index 95042e529..253e9ddee 100644 --- a/src/lib/pubkey/mceies/mceies.cpp +++ b/src/lib/pubkey/mceies/mceies.cpp @@ -36,7 +36,7 @@ mceies_encrypt(const McEliece_PublicKey& pubkey, RandomNumberGenerator& rng, const std::string& algo) { - PK_KEM_Encryptor kem_op(pubkey, "KDF1(SHA-512)"); + PK_KEM_Encryptor kem_op(pubkey, rng, "KDF1(SHA-512)"); secure_vector<byte> mce_ciphertext, mce_key; kem_op.encrypt(mce_ciphertext, mce_key, 64, rng); @@ -74,7 +74,8 @@ mceies_decrypt(const McEliece_PrivateKey& privkey, { try { - PK_KEM_Decryptor kem_op(privkey, "KDF1(SHA-512)"); + Null_RNG null_rng; + PK_KEM_Decryptor kem_op(privkey, null_rng, "KDF1(SHA-512)"); const size_t mce_code_bytes = (privkey.get_code_length() + 7) / 8; diff --git a/src/lib/pubkey/pk_keys.cpp b/src/lib/pubkey/pk_keys.cpp index 9597ed08d..ff57d88cc 100644 --- a/src/lib/pubkey/pk_keys.cpp +++ b/src/lib/pubkey/pk_keys.cpp @@ -6,6 +6,7 @@ */ #include <botan/pk_keys.h> +#include <botan/pk_ops.h> #include <botan/der_enc.h> #include <botan/oids.h> #include <botan/hash.h> @@ -78,4 +79,60 @@ std::string Private_Key::fingerprint(const std::string& alg) const return formatted_print; } +std::unique_ptr<PK_Ops::Encryption> +Public_Key::create_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support encryption"); + } + +std::unique_ptr<PK_Ops::KEM_Encryption> +Public_Key::create_kem_encryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support KEM encryption"); + } + +std::unique_ptr<PK_Ops::Verification> +Public_Key::create_verification_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support verification"); + } + +std::unique_ptr<PK_Ops::Decryption> +Private_Key::create_decryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support decryption"); + } + +std::unique_ptr<PK_Ops::KEM_Decryption> +Private_Key::create_kem_decryption_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support KEM decryption"); + } + +std::unique_ptr<PK_Ops::Signature> +Private_Key::create_signature_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support signatures"); + } + +std::unique_ptr<PK_Ops::Key_Agreement> +Private_Key::create_key_agreement_op(RandomNumberGenerator& /*rng*/, + const std::string& /*params*/, + const std::string& /*provider*/) const + { + throw Lookup_Error(algo_name() + " does not support key agreement"); + } + } diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h index 1a3047a57..9de884103 100644 --- a/src/lib/pubkey/pk_keys.h +++ b/src/lib/pubkey/pk_keys.h @@ -15,6 +15,20 @@ namespace Botan { +class RandomNumberGenerator; + +namespace PK_Ops { + +class Encryption; +class Decryption; +class Key_Agreement; +class KEM_Encryption; +class KEM_Decryption; +class Verification; +class Signature; + +} + /** * Public Key Base Class. */ @@ -82,6 +96,42 @@ class BOTAN_DLL Public_Key */ virtual std::vector<byte> x509_subject_public_key() const = 0; + /** + * Return an encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::Encryption> + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * Return a KEM encryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::KEM_Encryption> + create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * Return a verification operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + virtual ~Public_Key() {} protected: /** @@ -113,6 +163,55 @@ class BOTAN_DLL Private_Key : public virtual Public_Key * @return Hash of the PKCS #8 encoding for this key object */ std::string fingerprint(const std::string& alg = "SHA") const; + + /** + * Return an decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::Decryption> + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * Return a KEM decryption operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::KEM_Decryption> + create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * Return a signature operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + + /** + * Return a key agreement operation for this key/params or throw + * + * @param rng a random number generator. The PK_Op may maintain a + * reference to the RNG and use it many times. The rng must outlive + * any operations which reference it. + */ + virtual std::unique_ptr<PK_Ops::Key_Agreement> + create_key_agreement_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const; + protected: /** * Self-test after loading a key @@ -142,7 +241,8 @@ class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key }; /* -* Typedefs +* Old compat typedefs +* TODO: remove these? */ typedef PK_Key_Agreement_Key PK_KA_Key; typedef Public_Key X509_PublicKey; diff --git a/src/lib/pubkey/pk_ops_fwd.h b/src/lib/pubkey/pk_ops_fwd.h new file mode 100644 index 000000000..16c2124fb --- /dev/null +++ b/src/lib/pubkey/pk_ops_fwd.h @@ -0,0 +1,27 @@ +/* +* PK Operation Types Forward Decls +* (C) 2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_PK_OPERATIONS_FWD_H__ +#define BOTAN_PK_OPERATIONS_FWD_H__ + +namespace Botan { + +namespace PK_Ops { + +class Encryption; +class Decryption; +class Verification; +class Signature; +class Key_Agreement; +class KEM_Encryption; +class KEM_Decryption; + +} + +} + +#endif diff --git a/src/lib/pubkey/pk_utils.h b/src/lib/pubkey/pk_utils.h deleted file mode 100644 index 04a0bf5ca..000000000 --- a/src/lib/pubkey/pk_utils.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* Public Key Algos Utility Header -* (C) 2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_PK_UTILS_H__ -#define BOTAN_PK_UTILS_H__ - -#include <botan/internal/algo_registry.h> -#include <botan/internal/pk_ops_impl.h> -#include <botan/numthry.h> -#include <botan/reducer.h> -#include <algorithm> - -namespace Botan { - -template<typename OP, typename T> -OP* make_pk_op(const typename T::Spec& spec) - { - if(auto* key = dynamic_cast<const typename T::Key_Type*>(&spec.key())) - return new T(*key, spec.padding()); - return nullptr; - } - -#define BOTAN_REGISTER_PK_OP(T, NAME, TYPE) BOTAN_REGISTER_NAMED_T(T, NAME, TYPE, (make_pk_op<T, TYPE>)) - -#define BOTAN_REGISTER_PK_ENCRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Encryption, NAME, TYPE) -#define BOTAN_REGISTER_PK_DECRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Decryption, NAME, TYPE) -#define BOTAN_REGISTER_PK_SIGNATURE_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Signature, NAME, TYPE) -#define BOTAN_REGISTER_PK_VERIFY_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Verification, NAME, TYPE) -#define BOTAN_REGISTER_PK_KEY_AGREE_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Key_Agreement, NAME, TYPE) - -#define BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::KEM_Encryption, NAME, TYPE) -#define BOTAN_REGISTER_PK_KEM_DECRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::KEM_Decryption, NAME, TYPE) - -} - -#endif diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index 8b24ee983..51869326a 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -8,29 +8,11 @@ #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/bigint.h> -#include <botan/internal/algo_registry.h> +#include <botan/pk_ops.h> #include <botan/internal/ct_utils.h> namespace Botan { -namespace { - -template<typename T, typename Key> -T* get_pk_op(const std::string& what, const Key& key, const std::string& pad, - const std::string& provider = "") - { - if(T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad), provider)) - return p; - - const std::string err = what + " with " + key.algo_name() + "/" + pad + " not supported"; - if(!provider.empty()) - throw Lookup_Error(err + " with provider " + provider); - else - throw Lookup_Error(err); - } - -} - secure_vector<byte> PK_Decryptor::decrypt(const byte in[], size_t length) const { byte valid_mask = 0; @@ -54,8 +36,6 @@ PK_Decryptor::decrypt_or_random(const byte in[], { const secure_vector<byte> fake_pms = rng.random_vec(expected_pt_len); - //CT::poison(in, length); - byte valid_mask = 0; secure_vector<byte> decoded = do_decrypt(valid_mask, in, length); @@ -90,9 +70,6 @@ PK_Decryptor::decrypt_or_random(const byte in[], /*from1*/fake_pms.data(), expected_pt_len); - //CT::unpoison(in, length); - //CT::unpoison(decoded.data(), decoded.size()); - return decoded; } @@ -107,10 +84,12 @@ PK_Decryptor::decrypt_or_random(const byte in[], } PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, + RandomNumberGenerator& rng, const std::string& padding, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, padding, provider)); + m_op = key.create_encryption_op(rng, padding, provider); + BOTAN_ASSERT_NONNULL(m_op); } std::vector<byte> @@ -124,10 +103,13 @@ size_t PK_Encryptor_EME::maximum_input_size() const return m_op->max_input_bits() / 8; } -PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& padding, +PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& padding, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, padding, provider)); + m_op = key.create_decryption_op(rng, padding, provider); + BOTAN_ASSERT_NONNULL(m_op); } secure_vector<byte> PK_Decryptor_EME::do_decrypt(byte& valid_mask, @@ -137,10 +119,12 @@ secure_vector<byte> PK_Decryptor_EME::do_decrypt(byte& valid_mask, } PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, + RandomNumberGenerator& rng, const std::string& param, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::KEM_Encryption>("KEM", key, param, provider)); + m_op = key.create_kem_encryption_op(rng, param, provider); + BOTAN_ASSERT_NONNULL(m_op); } void PK_KEM_Encryptor::encrypt(secure_vector<byte>& out_encapsulated_key, @@ -159,10 +143,12 @@ void PK_KEM_Encryptor::encrypt(secure_vector<byte>& out_encapsulated_key, } PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& param, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::KEM_Decryption>("KEM", key, param, provider)); + m_op = key.create_kem_decryption_op(rng, param, provider); + BOTAN_ASSERT_NONNULL(m_op); } secure_vector<byte> PK_KEM_Decryptor::decrypt(const byte encap_key[], @@ -177,10 +163,12 @@ secure_vector<byte> PK_KEM_Decryptor::decrypt(const byte encap_key[], } PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& kdf, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Key_Agreement>("Key agreement", key, kdf, provider)); + m_op = key.create_key_agreement_op(rng, kdf, provider); + BOTAN_ASSERT_NONNULL(m_op); } SymmetricKey PK_Key_Agreement::derive_key(size_t key_len, @@ -234,11 +222,13 @@ std::vector<byte> der_decode_signature(const byte sig[], size_t len, } PK_Signer::PK_Signer(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& emsa, Signature_Format format, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa, provider)); + m_op = key.create_signature_op(rng, emsa, provider); + BOTAN_ASSERT_NONNULL(m_op); m_sig_format = format; } @@ -262,11 +252,13 @@ std::vector<byte> PK_Signer::signature(RandomNumberGenerator& rng) } PK_Verifier::PK_Verifier(const Public_Key& key, - const std::string& emsa_name, + RandomNumberGenerator& rng, + const std::string& emsa, Signature_Format format, const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name, provider)); + m_op = key.create_verification_op(rng, emsa, provider); + BOTAN_ASSERT_NONNULL(m_op); m_sig_format = format; } diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index 26cbb1790..18b5d0f9b 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -16,6 +16,11 @@ #include <botan/emsa.h> #include <botan/kdf.h> +#if defined(BOTAN_HAS_SYSTEM_RNG) + #include <botan/system_rng.h> + #define BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS +#endif + namespace Botan { /** @@ -165,10 +170,28 @@ class BOTAN_DLL PK_Signer * @param format the signature format to use */ PK_Signer(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& emsa, Signature_Format format = IEEE_1363, const std::string& provider = ""); +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct a PK Signer. + * @param key the key to use inside this signer + * @param emsa the EMSA to use + * An example would be "EMSA1(SHA-224)". + * @param format the signature format to use + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Signer(const Private_Key& key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = "") : + PK_Signer(key, system_rng(), emsa, format, provider) + {} +#endif + /** * Sign a message all in one go * @param in the message to sign as a byte array @@ -258,10 +281,27 @@ class BOTAN_DLL PK_Verifier * @param format the signature format to use */ PK_Verifier(const Public_Key& pub_key, + RandomNumberGenerator& rng, const std::string& emsa, Signature_Format format = IEEE_1363, const std::string& provider = ""); +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct a PK Verifier. + * @param pub_key the public key to verify against + * @param emsa the EMSA to use (eg "EMSA3(SHA-1)") + * @param format the signature format to use + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Verifier(const Public_Key& pub_key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = "") : + PK_Verifier(pub_key, system_rng(), emsa, format, provider) + {} +#endif + /** * Verify a signature. * @param msg the message that the signature belongs to, as a byte array @@ -364,9 +404,25 @@ class BOTAN_DLL PK_Key_Agreement * @param provider the algo provider to use (or empty for default) */ PK_Key_Agreement(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& kdf, const std::string& provider = ""); +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + * @param provider the algo provider to use (or empty for default) + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Key_Agreement(const Private_Key& key, + const std::string& kdf, + const std::string& provider = "") : + PK_Key_Agreement(key, system_rng(), kdf, provider) + {} +#endif + /* * Perform Key Agreement Operation * @param key_len the desired key output size @@ -444,12 +500,27 @@ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor /** * Construct an instance. - * @param key the key to use inside the decryptor + * @param key the key to use inside the encryptor * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") */ PK_Encryptor_EME(const Public_Key& key, + RandomNumberGenerator& rng, const std::string& padding, const std::string& provider = ""); + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct an instance. + * @param key the key to use inside the encryptor + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Encryptor_EME(const Public_Key& key, + const std::string& padding, + const std::string& provider = "") : + PK_Encryptor_EME(key, system_rng(), padding, provider) {} +#endif + private: std::vector<byte> enc(const byte[], size_t, RandomNumberGenerator& rng) const override; @@ -465,12 +536,29 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor public: /** * Construct an instance. - * @param key the key to use inside the encryptor + * @param key the key to use inside the decryptor * @param eme the EME to use + * @param provider */ PK_Decryptor_EME(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& eme, const std::string& provider = ""); + + +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + /** + * Construct an instance. + * @param key the key to use inside the decryptor + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") + */ + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_Decryptor_EME(const Private_Key& key, + const std::string& eme, + const std::string& provider = "") : + PK_Decryptor_EME(key, system_rng(), eme, provider) {} +#endif + private: secure_vector<byte> do_decrypt(byte& valid_mask, const byte in[], @@ -483,9 +571,18 @@ class BOTAN_DLL PK_KEM_Encryptor { public: PK_KEM_Encryptor(const Public_Key& key, + RandomNumberGenerator& rng, const std::string& kem_param = "", const std::string& provider = ""); +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Encryptor(const Public_Key& key, + const std::string& kem_param = "", + const std::string& provider = "") : + PK_KEM_Encryptor(key, system_rng(), kem_param, provider) {} +#endif + void encrypt(secure_vector<byte>& out_encapsulated_key, secure_vector<byte>& out_shared_key, size_t desired_shared_key_len, @@ -528,9 +625,19 @@ class BOTAN_DLL PK_KEM_Decryptor { public: PK_KEM_Decryptor(const Private_Key& key, + RandomNumberGenerator& rng, const std::string& kem_param = "", const std::string& provider = ""); +#if defined(BOTAN_PUBKEY_INCLUDE_DEPRECATED_CONSTRUCTORS) + BOTAN_DEPRECATED("Use constructor taking a RNG object") + PK_KEM_Decryptor(const Private_Key& key, + const std::string& kem_param = "", + const std::string& provider = "") : + PK_KEM_Decryptor(key, system_rng(), kem_param, provider) + {} +#endif + secure_vector<byte> decrypt(const byte encap_key[], size_t encap_key_len, size_t desired_shared_key_len, diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index 7f72ba210..c8d1e7afc 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -5,8 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/internal/pk_utils.h> #include <botan/rsa.h> +#include <botan/internal/pk_ops_impl.h> #include <botan/parsing.h> #include <botan/keypair.h> #include <botan/blinding.h> @@ -16,6 +16,10 @@ #include <botan/ber_dec.h> #include <future> +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> +#endif + namespace Botan { size_t RSA_PublicKey::estimated_strength() const @@ -189,7 +193,7 @@ class RSA_Private_Operation protected: size_t get_max_input_bits() const { return (m_n.bits() - 1); } - explicit RSA_Private_Operation(const RSA_PrivateKey& rsa) : + explicit RSA_Private_Operation(const RSA_PrivateKey& rsa, RandomNumberGenerator& rng) : m_n(rsa.get_n()), m_q(rsa.get_q()), m_c(rsa.get_c()), @@ -198,6 +202,7 @@ class RSA_Private_Operation m_powermod_d2_q(rsa.get_d2(), rsa.get_q()), m_mod_p(rsa.get_p()), m_blinder(m_n, + rng, [this](const BigInt& k) { return m_powermod_e_n(k); }, [this](const BigInt& k) { return inverse_mod(k, m_n); }) { @@ -238,9 +243,9 @@ class RSA_Signature_Operation : public PK_Ops::Signature_with_EMSA, size_t max_input_bits() const override { return get_max_input_bits(); }; - RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) : + RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string& emsa, RandomNumberGenerator& rng) : PK_Ops::Signature_with_EMSA(emsa), - RSA_Private_Operation(rsa) + RSA_Private_Operation(rsa, rng) { } @@ -263,9 +268,9 @@ class RSA_Decryption_Operation : public PK_Ops::Decryption_with_EME, size_t max_raw_input_bits() const override { return get_max_input_bits(); }; - RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string& eme) : + RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string& eme, RandomNumberGenerator& rng) : PK_Ops::Decryption_with_EME(eme), - RSA_Private_Operation(rsa) + RSA_Private_Operation(rsa, rng) { } @@ -286,9 +291,10 @@ class RSA_KEM_Decryption_Operation : public PK_Ops::KEM_Decryption_with_KDF, typedef RSA_PrivateKey Key_Type; RSA_KEM_Decryption_Operation(const RSA_PrivateKey& key, - const std::string& kdf) : + const std::string& kdf, + RandomNumberGenerator& rng) : PK_Ops::KEM_Decryption_with_KDF(kdf), - RSA_Private_Operation(key) + RSA_Private_Operation(key, rng) {} secure_vector<byte> @@ -397,16 +403,90 @@ class RSA_KEM_Encryption_Operation : public PK_Ops::KEM_Encryption_with_KDF, } }; +} -BOTAN_REGISTER_PK_ENCRYPTION_OP("RSA", RSA_Encryption_Operation); -BOTAN_REGISTER_PK_DECRYPTION_OP("RSA", RSA_Decryption_Operation); +std::unique_ptr<PK_Ops::Encryption> +RSA_PublicKey::create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Encryption> res = make_openssl_rsa_enc_op(*this, params); + if(res) + return res; + } +#endif -BOTAN_REGISTER_PK_SIGNATURE_OP("RSA", RSA_Signature_Operation); -BOTAN_REGISTER_PK_VERIFY_OP("RSA", RSA_Verify_Operation); + return std::unique_ptr<PK_Ops::Encryption>(new RSA_Encryption_Operation(*this, params)); + } -BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP("RSA", RSA_KEM_Encryption_Operation); -BOTAN_REGISTER_PK_KEM_DECRYPTION_OP("RSA", RSA_KEM_Decryption_Operation); +std::unique_ptr<PK_Ops::KEM_Encryption> +RSA_PublicKey::create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::KEM_Encryption>(new RSA_KEM_Encryption_Operation(*this, params)); + } -} +std::unique_ptr<PK_Ops::Verification> +RSA_PublicKey::create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Verification> res = make_openssl_rsa_ver_op(*this, params); + if(res) + return res; + } +#endif + + return std::unique_ptr<PK_Ops::Verification>(new RSA_Verify_Operation(*this, params)); + } + +std::unique_ptr<PK_Ops::Decryption> +RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Decryption> res = make_openssl_rsa_dec_op(*this, params); + if(res) + return res; + } +#endif + + return std::unique_ptr<PK_Ops::Decryption>(new RSA_Decryption_Operation(*this, params, rng)); + } + +std::unique_ptr<PK_Ops::KEM_Decryption> +RSA_PrivateKey::create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& /*provider*/) const + { + return std::unique_ptr<PK_Ops::KEM_Decryption>(new RSA_KEM_Decryption_Operation(*this, params, rng)); + } + +std::unique_ptr<PK_Ops::Signature> +RSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const + { +#if defined(BOTAN_HAS_OPENSSL) + if(provider == "openssl") + { + std::unique_ptr<PK_Ops::Signature> res = make_openssl_rsa_sig_op(*this, params); + if(res) + return res; + } +#endif + + return std::unique_ptr<PK_Ops::Signature>(new RSA_Signature_Operation(*this, params, rng)); + } } diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h index 85bd7ce58..203a3a323 100644 --- a/src/lib/pubkey/rsa/rsa.h +++ b/src/lib/pubkey/rsa/rsa.h @@ -52,6 +52,21 @@ class BOTAN_DLL RSA_PublicKey : public virtual Public_Key size_t estimated_strength() const override; + std::unique_ptr<PK_Ops::Encryption> + create_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::KEM_Encryption> + create_kem_encryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::Verification> + create_verification_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + protected: RSA_PublicKey() {} @@ -119,6 +134,22 @@ class BOTAN_DLL RSA_PrivateKey : public Private_Key, public RSA_PublicKey const BigInt& get_d2() const { return m_d2; } secure_vector<byte> pkcs8_private_key() const override; + + std::unique_ptr<PK_Ops::Decryption> + create_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::KEM_Decryption> + create_kem_decryption_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + + std::unique_ptr<PK_Ops::Signature> + create_signature_op(RandomNumberGenerator& rng, + const std::string& params, + const std::string& provider) const override; + private: BigInt m_d, m_p, m_q, m_d1, m_d2, m_c; }; diff --git a/src/lib/tls/msg_cert_verify.cpp b/src/lib/tls/msg_cert_verify.cpp index 6b59e703f..cc162f8a0 100644 --- a/src/lib/tls/msg_cert_verify.cpp +++ b/src/lib/tls/msg_cert_verify.cpp @@ -28,7 +28,7 @@ Certificate_Verify::Certificate_Verify(Handshake_IO& io, std::pair<std::string, Signature_Format> format = state.choose_sig_format(*priv_key, m_hash_algo, m_sig_algo, true, policy); - PK_Signer signer(*priv_key, format.first, format.second); + PK_Signer signer(*priv_key, rng, format.first, format.second); m_signature = signer.sign_message(state.hash().get_contents(), rng); @@ -78,7 +78,8 @@ std::vector<byte> Certificate_Verify::serialize() const */ bool Certificate_Verify::verify(const X509_Certificate& cert, const Handshake_State& state, - const Policy& policy) const + const Policy& policy, + RandomNumberGenerator& rng) const { std::unique_ptr<Public_Key> key(cert.subject_public_key()); @@ -88,7 +89,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert, state.parse_sig_format(*key.get(), m_hash_algo, m_sig_algo, true, policy); - PK_Verifier verifier(*key, format.first, format.second); + PK_Verifier verifier(*key, rng, format.first, format.second); return verifier.verify_message(state.hash().get_contents(), m_signature); } diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index 0eceadb3b..02ebcc2c8 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -114,7 +114,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, DH_PrivateKey priv_key(rng, group); - PK_Key_Agreement ka(priv_key, "Raw"); + PK_Key_Agreement ka(priv_key, rng, "Raw"); secure_vector<byte> dh_secret = CT::strip_leading_zeros( ka.derive_key(0, counterparty_key.public_value()).bits_of()); @@ -159,7 +159,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, ECDH_PrivateKey priv_key(rng, group); - PK_Key_Agreement ka(priv_key, "Raw"); + PK_Key_Agreement ka(priv_key, rng, "Raw"); secure_vector<byte> ecdh_secret = ka.derive_key(0, counterparty_key.public_value()).bits_of(); @@ -232,7 +232,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, m_pre_master[0] = offered_version.major_version(); m_pre_master[1] = offered_version.minor_version(); - PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15"); + PK_Encryptor_EME encryptor(*rsa_pub, rng, "PKCS1v15"); const std::vector<byte> encrypted_key = encryptor.encrypt(m_pre_master, rng); @@ -273,7 +273,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents, TLS_Data_Reader reader("ClientKeyExchange", contents); const std::vector<byte> encrypted_pre_master = reader.get_range<byte>(2, 0, 65535); - PK_Decryptor_EME decryptor(*server_rsa_kex_key, "PKCS1v15"); + PK_Decryptor_EME decryptor(*server_rsa_kex_key, rng, "PKCS1v15"); const byte client_major = state.client_hello()->version().major_version(); const byte client_minor = state.client_hello()->version().minor_version(); @@ -350,7 +350,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents, try { - PK_Key_Agreement ka(*ka_key, "Raw"); + PK_Key_Agreement ka(*ka_key, rng, "Raw"); std::vector<byte> client_pubkey; diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index 33b980ba9..3df23955b 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -133,7 +133,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, std::pair<std::string, Signature_Format> format = state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy); - PK_Signer signer(*signing_key, format.first, format.second); + PK_Signer signer(*signing_key, rng, format.first, format.second); signer.update(state.client_hello()->random()); signer.update(state.server_hello()->random()); @@ -237,7 +237,8 @@ std::vector<byte> Server_Key_Exchange::serialize() const */ bool Server_Key_Exchange::verify(const Public_Key& server_key, const Handshake_State& state, - const Policy& policy) const + const Policy& policy, + RandomNumberGenerator& rng) const { policy.check_peer_key_acceptable(server_key); @@ -245,7 +246,7 @@ bool Server_Key_Exchange::verify(const Public_Key& server_key, state.parse_sig_format(server_key, m_hash_algo, m_sig_algo, false, policy); - PK_Verifier verifier(server_key, format.first, format.second); + PK_Verifier verifier(server_key, rng, format.first, format.second); verifier.update(state.client_hello()->random()); verifier.update(state.server_hello()->random()); diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index 0e72b9a28..6bfbdc008 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -415,7 +415,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state, { const Public_Key& server_key = state.get_server_public_Key(); - if(!state.server_kex()->verify(server_key, state, policy())) + if(!state.server_kex()->verify(server_key, state, policy(), rng())) { throw TLS_Exception(Alert::DECRYPT_ERROR, "Bad signature on server key exchange"); diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index 25228c865..76421bf4a 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -482,7 +482,8 @@ class BOTAN_DLL Certificate_Verify final : public Handshake_Message */ bool verify(const X509_Certificate& cert, const Handshake_State& state, - const Policy& policy) const; + const Policy& policy, + RandomNumberGenerator& rng) const; Certificate_Verify(Handshake_IO& io, Handshake_State& state, @@ -551,7 +552,8 @@ class Server_Key_Exchange final : public Handshake_Message bool verify(const Public_Key& server_key, const Handshake_State& state, - const Policy& policy) const; + const Policy& policy, + RandomNumberGenerator& rng) const; // Only valid for certain kex types const Private_Key& server_kex_key() const; diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 1676ef659..510a30421 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -509,7 +509,7 @@ void Server::process_certificate_verify_msg(Server_Handshake_State& pending_stat pending_state.client_certs()->cert_chain(); const bool sig_valid = - pending_state.client_verify()->verify ( client_certs[0], pending_state, policy() ); + pending_state.client_verify()->verify ( client_certs[0], pending_state, policy(), rng() ); pending_state.hash().update ( pending_state.handshake_io().format ( contents, type ) ); |