diff options
author | Jack Lloyd <[email protected]> | 2015-10-14 19:23:55 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-10-14 19:23:55 -0400 |
commit | 4e90017c204d3297df1444af59337db89f8180d9 (patch) | |
tree | f5a54d34b13035a4fda1a0ec7fd27c3791f6080d | |
parent | 4bfd5d6828f23e0eef04e5cf079c323274136499 (diff) |
Expose providers for public key operations
For PK_Encryptor and company they are requested via a new provider param
to the constructors.
The speed command gets a --provider option so you can see benchmark results
with the different versions.
-rw-r--r-- | src/cmd/implementation/speed.h | 4 | ||||
-rw-r--r-- | src/cmd/implementation/speed_public_key.cpp | 30 | ||||
-rw-r--r-- | src/cmd/speed.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.cpp | 36 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.h | 68 | ||||
-rw-r--r-- | src/lib/vendor/openssl/openssl_rsa.cpp | 9 | ||||
-rw-r--r-- | src/tests/test_rsa.cpp | 4 |
7 files changed, 97 insertions, 67 deletions
diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h index 1f082eb52..3cfd0ef61 100644 --- a/src/cmd/implementation/speed.h +++ b/src/cmd/implementation/speed.h @@ -13,7 +13,9 @@ #include <chrono> void benchmark_public_key(Botan::RandomNumberGenerator& rng, - const std::string& algo, double seconds); + const std::string& algo, + const std::string& provider, + double seconds); std::map<std::string, double> benchmark_is_prime(Botan::RandomNumberGenerator &rng, const std::chrono::milliseconds runtime); diff --git a/src/cmd/implementation/speed_public_key.cpp b/src/cmd/implementation/speed_public_key.cpp index 83c0156ae..00bf4b438 100644 --- a/src/cmd/implementation/speed_public_key.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -202,7 +202,8 @@ void benchmark_sig_ver(PK_Verifier& ver, PK_Signer& sig, */ #if defined(BOTAN_HAS_RSA) -void benchmark_rsa(RandomNumberGenerator& rng, +void benchmark_rsa(const std::string& provider, + RandomNumberGenerator& rng, double seconds, Benchmark_Report& report) { @@ -213,8 +214,8 @@ void benchmark_rsa(RandomNumberGenerator& rng, { size_t keylen = keylens[i]; - //const std::string sig_padding = "EMSA4(SHA-1)"; - //const std::string enc_padding = "EME1(SHA-1)"; + //const std::string sig_padding = "PSSR(SHA-256)"; + //const std::string enc_padding = "OAEP(SHA-1)"; const std::string sig_padding = "EMSA-PKCS1-v1_5(SHA-1)"; const std::string enc_padding = "EME-PKCS1-v1_5"; @@ -243,14 +244,14 @@ void benchmark_rsa(RandomNumberGenerator& rng, while(verify_timer.seconds() < seconds || sig_timer.seconds() < seconds) { - PK_Encryptor_EME enc(key, enc_padding); - PK_Decryptor_EME dec(key, enc_padding); + PK_Encryptor_EME enc(key, enc_padding, provider); + PK_Decryptor_EME dec(key, enc_padding, provider); benchmark_enc_dec(enc, dec, enc_timer, dec_timer, rng, 10000, seconds); - PK_Signer sig(key, sig_padding); - PK_Verifier ver(key, sig_padding); + PK_Signer sig(key, sig_padding, IEEE_1363); + PK_Verifier ver(key, sig_padding, IEEE_1363); benchmark_sig_ver(ver, sig, verify_timer, sig_timer, rng, 10000, seconds); @@ -318,7 +319,8 @@ void benchmark_rw(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_ECDSA) -void benchmark_ecdsa(RandomNumberGenerator& rng, +void benchmark_ecdsa(const std::string& provider, + RandomNumberGenerator& rng, double seconds, Benchmark_Report& report) { @@ -348,8 +350,8 @@ void benchmark_ecdsa(RandomNumberGenerator& rng, ECDSA_PrivateKey key(rng, params); keygen_timer.stop(); - PK_Signer sig(key, padding, IEEE_1363); - PK_Verifier ver(key, padding); + PK_Signer sig(key, padding, IEEE_1363, provider); + PK_Verifier ver(key, padding, IEEE_1363, provider); benchmark_sig_ver(ver, sig, verify_timer, sig_timer, rng, 1000, seconds); @@ -791,7 +793,9 @@ void benchmark_mce(RandomNumberGenerator& rng, } void benchmark_public_key(RandomNumberGenerator& rng, - const std::string& algo, double seconds) + const std::string& algo, + const std::string& provider, + double seconds) { /* There is some strangeness going on here. It looks like algorithms @@ -823,7 +827,7 @@ void benchmark_public_key(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_RSA) if(algo == "All" || algo == "RSA") - benchmark_rsa(rng, seconds, report); + benchmark_rsa(provider, rng, seconds, report); #endif #if defined(BOTAN_HAS_DSA) @@ -833,7 +837,7 @@ void benchmark_public_key(RandomNumberGenerator& rng, #if defined(BOTAN_HAS_ECDSA) if(algo == "All" || algo == "ECDSA") - benchmark_ecdsa(rng, seconds, report); + benchmark_ecdsa(provider, rng, seconds, report); #endif #if defined(BOTAN_HAS_ECDH) diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp index 91b2f4fbd..990c6a364 100644 --- a/src/cmd/speed.cpp +++ b/src/cmd/speed.cpp @@ -118,6 +118,7 @@ void report_results(const std::string& algo, } void bench_algo(const std::string& algo, + const std::string& provider, RandomNumberGenerator& rng, double seconds, size_t buf_size) @@ -151,7 +152,7 @@ void bench_algo(const std::string& algo, catch (No_Provider_Found) { #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - benchmark_public_key(rng, algo, seconds); + benchmark_public_key(rng, algo, provider, seconds); #endif } } @@ -159,7 +160,7 @@ void bench_algo(const std::string& algo, int speed(int argc, char* argv[]) { BOTAN_UNUSED(argc); - OptionParser opts("seconds=|buf-size="); + OptionParser opts("seconds=|buf-size=|provider="); opts.parse(argv); double seconds = .5; @@ -185,7 +186,9 @@ int speed(int argc, char* argv[]) } } - auto args = opts.arguments(); + const std::string provider = opts.value_if_set("provider"); + + std::vector<std::string> args = opts.arguments(); if(args.empty()) args = default_benchmark_list; @@ -199,7 +202,9 @@ int speed(int argc, char* argv[]) AutoSeeded_RNG rng; for(auto alg: args) - bench_algo(alg, rng, seconds, buf_size); + { + bench_algo(alg, provider, rng, seconds, buf_size); + } return 0; } diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index 74b6a2053..b9923f54b 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -15,19 +15,26 @@ namespace Botan { namespace { template<typename T, typename Key> -T* get_pk_op(const std::string& what, const Key& key, const std::string& pad) +T* get_pk_op(const std::string& what, const Key& key, const std::string& pad, + const std::string& provider = "") { - T* p = Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad)); - if(!p) - throw Lookup_Error(what + " with " + key.algo_name() + "/" + pad + " not supported"); - return p; + 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 != "") + throw Lookup_Error(err + " with provider " + provider); + else + throw Lookup_Error(err); } } -PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, const std::string& eme) +PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key, + const std::string& padding, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, eme)); + m_op.reset(get_pk_op<PK_Ops::Encryption>("Encryption", key, padding, provider)); } std::vector<byte> @@ -41,9 +48,10 @@ 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& eme) +PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key, const std::string& padding, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, eme)); + m_op.reset(get_pk_op<PK_Ops::Decryption>("Decryption", key, padding, provider)); } secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[], size_t length) const @@ -108,9 +116,10 @@ std::vector<byte> der_decode_signature(const byte sig[], size_t len, PK_Signer::PK_Signer(const Private_Key& key, const std::string& emsa, - Signature_Format format) + Signature_Format format, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa)); + m_op.reset(get_pk_op<PK_Ops::Signature>("Signing", key, emsa, provider)); m_sig_format = format; } @@ -135,9 +144,10 @@ std::vector<byte> PK_Signer::signature(RandomNumberGenerator& rng) PK_Verifier::PK_Verifier(const Public_Key& key, const std::string& emsa_name, - Signature_Format format) + Signature_Format format, + const std::string& provider) { - m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name)); + m_op.reset(get_pk_op<PK_Ops::Verification>("Verification", key, emsa_name, provider)); m_sig_format = format; } diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index 687485c68..67116a9ec 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -120,6 +120,19 @@ class BOTAN_DLL PK_Decryptor class BOTAN_DLL PK_Signer { public: + + /** + * 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 + */ + PK_Signer(const Private_Key& key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + /** * Sign a message. * @param in the message to sign as a byte array @@ -180,17 +193,6 @@ class BOTAN_DLL PK_Signer * @param format the signature format to use */ void set_output_format(Signature_Format format) { m_sig_format = format; } - - /** - * 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 - */ - PK_Signer(const Private_Key& key, - const std::string& emsa, - Signature_Format format = IEEE_1363); private: std::unique_ptr<PK_Ops::Signature> m_op; Signature_Format m_sig_format; @@ -205,6 +207,17 @@ class BOTAN_DLL PK_Verifier { public: /** + * 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 + */ + PK_Verifier(const Public_Key& pub_key, + const std::string& emsa, + Signature_Format format = IEEE_1363, + const std::string& provider = ""); + + /** * Verify a signature. * @param msg the message that the signature belongs to, as a byte array * @param msg_length the length of the above byte array msg @@ -278,15 +291,6 @@ class BOTAN_DLL PK_Verifier */ void set_input_format(Signature_Format format); - /** - * 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 - */ - PK_Verifier(const Public_Key& pub_key, - const std::string& emsa, - Signature_Format format = IEEE_1363); private: std::unique_ptr<PK_Ops::Verification> m_op; Signature_Format m_sig_format; @@ -299,6 +303,13 @@ class BOTAN_DLL PK_Key_Agreement { public: + /** + * Construct a PK Key Agreement. + * @param key the key to use + * @param kdf name of the KDF to use (or 'Raw' for no KDF) + */ + PK_Key_Agreement(const Private_Key& key, const std::string& kdf); + /* * Perform Key Agreement Operation * @param key_len the desired key output size @@ -361,18 +372,13 @@ class BOTAN_DLL PK_Key_Agreement params.length()); } - /** - * Construct a PK Key Agreement. - * @param key the key to use - * @param kdf name of the KDF to use (or 'Raw' for no KDF) - */ - PK_Key_Agreement(const Private_Key& key, const std::string& kdf); private: std::unique_ptr<PK_Ops::Key_Agreement> m_op; }; /** -* Encryption with an MR algorithm and an EME. +* Encryption using a standard message recovery algorithm like RSA or +* ElGamal, paired with an encoding scheme like OAEP. */ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor { @@ -382,10 +388,11 @@ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor /** * Construct an instance. * @param key the key to use inside the decryptor - * @param eme the EME to use + * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)") */ PK_Encryptor_EME(const Public_Key& key, - const std::string& eme); + const std::string& padding, + const std::string& provider = ""); private: std::vector<byte> enc(const byte[], size_t, RandomNumberGenerator& rng) const override; @@ -405,7 +412,8 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor * @param eme the EME to use */ PK_Decryptor_EME(const Private_Key& key, - const std::string& eme); + const std::string& eme, + const std::string& provider = ""); private: secure_vector<byte> dec(const byte[], size_t) const override; diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp index f8ab2bcd1..ac8416405 100644 --- a/src/lib/vendor/openssl/openssl_rsa.cpp +++ b/src/lib/vendor/openssl/openssl_rsa.cpp @@ -24,11 +24,12 @@ namespace { std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme) { + ERR_load_crypto_strings(); if(eme == "Raw") return std::make_pair(RSA_NO_PADDING, 0); else if(eme == "EME-PKCS1-v1_5") return std::make_pair(RSA_PKCS1_PADDING, 11); - else if(eme == "EME1(SHA-1)") + else if(eme == "OAEP(SHA-1)") return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41); else throw Lookup_Error("OpenSSL RSA does not support EME " + eme); @@ -63,10 +64,10 @@ class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption if(!m_openssl_rsa) throw OpenSSL_Error("d2i_RSAPublicKey"); - m_bits = 8 * n_size() - pad_overhead; + m_bits = 8 * (n_size() - pad_overhead); } - size_t max_input_bits() const override { return m_bits; }; + size_t max_input_bits() const override { return m_bits - 1; }; secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override @@ -137,7 +138,7 @@ class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption m_bits = 8 * ::RSA_size(m_openssl_rsa.get()); } - size_t max_input_bits() const override { return m_bits; }; + size_t max_input_bits() const override { return m_bits - 1; } secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override { diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp index 940525574..dcc741bd2 100644 --- a/src/tests/test_rsa.cpp +++ b/src/tests/test_rsa.cpp @@ -37,7 +37,7 @@ size_t rsaes_kat(const std::string& e, if(padding == "") padding = "Raw"; - PK_Encryptor_EME enc(pubkey, padding); + PK_Encryptor_EME enc(pubkey, padding, "base"); PK_Decryptor_EME dec(privkey, padding); return validate_encryption(enc, dec, "RSAES/" + padding, msg, nonce, output); @@ -61,7 +61,7 @@ size_t rsa_sig_kat(const std::string& e, padding = "Raw"; PK_Verifier verify(pubkey, padding); - PK_Signer sign(privkey, padding); + PK_Signer sign(privkey, padding, IEEE_1363, "base"); return validate_signature(verify, sign, "RSA/" + padding, msg, rng, nonce, output); } |