aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-10-14 19:23:55 -0400
committerJack Lloyd <[email protected]>2015-10-14 19:23:55 -0400
commit4e90017c204d3297df1444af59337db89f8180d9 (patch)
treef5a54d34b13035a4fda1a0ec7fd27c3791f6080d /src
parent4bfd5d6828f23e0eef04e5cf079c323274136499 (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.
Diffstat (limited to 'src')
-rw-r--r--src/cmd/implementation/speed.h4
-rw-r--r--src/cmd/implementation/speed_public_key.cpp30
-rw-r--r--src/cmd/speed.cpp13
-rw-r--r--src/lib/pubkey/pubkey.cpp36
-rw-r--r--src/lib/pubkey/pubkey.h68
-rw-r--r--src/lib/vendor/openssl/openssl_rsa.cpp9
-rw-r--r--src/tests/test_rsa.cpp4
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);
}