aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-02-03 08:11:45 +0000
committerlloyd <[email protected]>2015-02-03 08:11:45 +0000
commitf9a7c85b74be0f4a7273e8e0591703af83036e81 (patch)
tree075dbe119fc16863cad99b432ca6251778bd8fd1
parent69d2cd919c698a6b138b2ccba0de5d5aa2a33a03 (diff)
Convert PK operations to using Algo_Registry instead of Engine.
Remove global PRNG.
-rw-r--r--src/lib/algo_base/algo_registry.h45
-rw-r--r--src/lib/algo_base/scan_name.cpp4
-rw-r--r--src/lib/algo_base/scan_name.h5
-rw-r--r--src/lib/algo_factory/algo_factory.cpp55
-rw-r--r--src/lib/algo_factory/algo_factory.h56
-rw-r--r--src/lib/benchmark/benchmark.cpp4
-rw-r--r--src/lib/engine/core_engine/core_engine.h16
-rw-r--r--src/lib/engine/core_engine/def_pk_ops.cpp179
-rw-r--r--src/lib/engine/core_engine/def_powm.cpp24
-rw-r--r--src/lib/engine/core_engine/info.txt5
-rw-r--r--src/lib/engine/dyn_engine/dyn_engine.h36
-rw-r--r--src/lib/engine/engine.cpp37
-rw-r--r--src/lib/engine/engine.h50
-rw-r--r--src/lib/libstate/libstate.cpp19
-rw-r--r--src/lib/libstate/libstate.h7
-rw-r--r--src/lib/libstate/lookup.h1
-rw-r--r--src/lib/math/numbertheory/pow_mod.cpp24
-rw-r--r--src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp14
-rw-r--r--src/lib/pk_pad/get_pk_pad.cpp1
-rw-r--r--src/lib/pubkey/curve25519/curve25519.cpp28
-rw-r--r--src/lib/pubkey/curve25519/curve25519.h17
-rw-r--r--src/lib/pubkey/dh/dh.cpp41
-rw-r--r--src/lib/pubkey/dh/dh.h20
-rw-r--r--src/lib/pubkey/dsa/dsa.cpp85
-rw-r--r--src/lib/pubkey/dsa/dsa.h49
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp33
-rw-r--r--src/lib/pubkey/ecdh/ecdh.h16
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.cpp79
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.h48
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp66
-rw-r--r--src/lib/pubkey/elgamal/elgamal.h40
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp72
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.h44
-rw-r--r--src/lib/pubkey/info.txt1
-rw-r--r--src/lib/pubkey/mce/mceliece.cpp1
-rw-r--r--src/lib/pubkey/mce/mceliece.h198
-rw-r--r--src/lib/pubkey/nr/nr.cpp78
-rw-r--r--src/lib/pubkey/nr/nr.h47
-rw-r--r--src/lib/pubkey/pk_ops.h35
-rw-r--r--src/lib/pubkey/pubkey.cpp88
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp221
-rw-r--r--src/lib/pubkey/rsa/rsa.h71
-rw-r--r--src/lib/pubkey/rw/rw.cpp75
-rw-r--r--src/lib/pubkey/rw/rw.h46
-rw-r--r--src/lib/rng/rng.cpp18
-rw-r--r--src/lib/rng/rng.h6
-rw-r--r--src/lib/tls/msg_cert_verify.cpp2
-rw-r--r--src/lib/tls/msg_server_kex.cpp2
-rw-r--r--src/lib/tls/tls_handshake_state.cpp3
-rw-r--r--src/lib/tls/tls_handshake_state.h3
-rw-r--r--src/lib/utils/cpuid.h12
51 files changed, 879 insertions, 1248 deletions
diff --git a/src/lib/algo_base/algo_registry.h b/src/lib/algo_base/algo_registry.h
index 77ed3591f..5fa2eed71 100644
--- a/src/lib/algo_base/algo_registry.h
+++ b/src/lib/algo_base/algo_registry.h
@@ -11,7 +11,9 @@
#include <functional>
#include <stdexcept>
#include <mutex>
+#include <vector>
#include <map>
+#include <unordered_map>
namespace Botan {
@@ -34,14 +36,23 @@ class Algo_Registry
void add(const std::string& name, const std::string& provider, maker_fn fn)
{
std::unique_lock<std::mutex> lock(m_mutex);
+
if(!m_maker_fns[name][provider])
m_maker_fns[name][provider] = fn;
}
- T* make(const std::string& spec_str)
+ std::vector<std::string> providers(const std::string& basename) const
{
- const Spec spec(spec_str);
- return make(spec_str, "");
+ std::unique_lock<std::mutex> lock(m_mutex);
+
+ std::vector<std::string> v;
+ auto i = m_maker_fns.find(basename);
+ if(i != m_maker_fns.end())
+ {
+ for(auto&& prov : i->second)
+ v.push_back(prov);
+ }
+ return v;
}
T* make(const Spec& spec, const std::string& provider = "")
@@ -82,39 +93,40 @@ class Algo_Registry
const std::string basename = spec.algo_name();
std::unique_lock<std::mutex> lock(m_mutex);
- auto providers = m_maker_fns.find(basename);
+ auto makers = m_maker_fns.find(basename);
- if(providers != m_maker_fns.end() && !providers->second.empty())
+ if(makers != m_maker_fns.end() && !makers->second.empty())
{
- const std::map<std::string, maker_fn>& prov = providers->second;
+ const auto& providers = makers->second;
if(provider != "")
{
// find one explicit provider requested by user, or fail
- auto i = prov.find(provider);
- if(i != prov.end())
+ auto i = providers.find(provider);
+ if(i != providers.end())
return i->second;
}
else
{
- if(prov.size() == 1)
+ if(providers.size() == 1)
{
- return prov.begin()->second;
+ return providers.begin()->second;
}
- else if(prov.size() > 1)
+ else if(providers.size() > 1)
{
// TODO choose best of available options (how?)
//throw std::runtime_error("multiple choice not implemented");
- return prov.begin()->second;
+ return providers.begin()->second;
}
}
}
+
// Default result is a function producing a null pointer
return [](const Spec&) { return nullptr; };
}
std::mutex m_mutex;
- std::map<std::string, std::map<std::string, maker_fn>> m_maker_fns;
+ std::unordered_map<std::string, std::unordered_map<std::string, maker_fn>> m_maker_fns;
};
template<typename T> T*
@@ -124,13 +136,6 @@ make_a(const typename T::Spec& spec, const std::string provider = "")
}
template<typename T> T*
-make_a(const std::string& spec_str, const std::string provider = "")
- {
- typename T::Spec spec(spec_str);
- return make_a<T>(spec, provider);
- }
-
-template<typename T> T*
make_new_T(const typename Algo_Registry<T>::Spec&) { return new T; }
template<typename T, size_t DEF_VAL> T*
diff --git a/src/lib/algo_base/scan_name.cpp b/src/lib/algo_base/scan_name.cpp
index 6206ab60a..f433a10aa 100644
--- a/src/lib/algo_base/scan_name.cpp
+++ b/src/lib/algo_base/scan_name.cpp
@@ -70,6 +70,10 @@ SCAN_Name::SCAN_Name(std::string algo_spec, const std::string& extra) : SCAN_Nam
alg_name += extra;
}
+SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec))
+ {
+ }
+
SCAN_Name::SCAN_Name(std::string algo_spec)
{
orig_algo_spec = algo_spec;
diff --git a/src/lib/algo_base/scan_name.h b/src/lib/algo_base/scan_name.h
index 82be8d49c..f1a79816d 100644
--- a/src/lib/algo_base/scan_name.h
+++ b/src/lib/algo_base/scan_name.h
@@ -26,6 +26,11 @@ class BOTAN_DLL SCAN_Name
/**
* @param algo_spec A SCAN-format name
*/
+ SCAN_Name(const char* algo_spec);
+
+ /**
+ * @param algo_spec A SCAN-format name
+ */
SCAN_Name(std::string algo_spec);
/**
diff --git a/src/lib/algo_factory/algo_factory.cpp b/src/lib/algo_factory/algo_factory.cpp
index dcd1a3c5f..9c805f67a 100644
--- a/src/lib/algo_factory/algo_factory.cpp
+++ b/src/lib/algo_factory/algo_factory.cpp
@@ -146,16 +146,6 @@ void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec,
}
/*
-* Get an engine out of the list
-*/
-Engine* Algorithm_Factory::get_engine_n(size_t n) const
- {
- if(n >= engines.size())
- return nullptr;
- return engines[n];
- }
-
-/*
* Return the possible providers of a request
* Note: assumes you don't have different types by the same name
*/
@@ -298,49 +288,4 @@ Algorithm_Factory::make_pbkdf(const std::string& algo_spec,
throw Algorithm_Not_Found(algo_spec);
}
-/*
-* Add a new block cipher
-*/
-void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher,
- const std::string& provider)
- {
- block_cipher_cache->add(block_cipher, block_cipher->name(), provider);
- }
-
-/*
-* Add a new stream cipher
-*/
-void Algorithm_Factory::add_stream_cipher(StreamCipher* stream_cipher,
- const std::string& provider)
- {
- stream_cipher_cache->add(stream_cipher, stream_cipher->name(), provider);
- }
-
-/*
-* Add a new hash
-*/
-void Algorithm_Factory::add_hash_function(HashFunction* hash,
- const std::string& provider)
- {
- hash_cache->add(hash, hash->name(), provider);
- }
-
-/*
-* Add a new mac
-*/
-void Algorithm_Factory::add_mac(MessageAuthenticationCode* mac,
- const std::string& provider)
- {
- mac_cache->add(mac, mac->name(), provider);
- }
-
-/*
-* Add a new PBKDF
-*/
-void Algorithm_Factory::add_pbkdf(PBKDF* pbkdf,
- const std::string& provider)
- {
- pbkdf_cache->add(pbkdf, pbkdf->name(), provider);
- }
-
}
diff --git a/src/lib/algo_factory/algo_factory.h b/src/lib/algo_factory/algo_factory.h
index bff66d2fb..6d4084f53 100644
--- a/src/lib/algo_factory/algo_factory.h
+++ b/src/lib/algo_factory/algo_factory.h
@@ -84,12 +84,6 @@ class BOTAN_DLL Algorithm_Factory
const std::string& provider = "");
/**
- * @param algo the algorithm to add
- * @param provider the provider of this algorithm
- */
- void add_block_cipher(BlockCipher* algo, const std::string& provider);
-
- /**
* @param algo_spec the algorithm we want
* @param provider the provider we would like to use
* @returns pointer to const prototype object, ready to clone(), or NULL
@@ -107,12 +101,6 @@ class BOTAN_DLL Algorithm_Factory
const std::string& provider = "");
/**
- * @param algo the algorithm to add
- * @param provider the provider of this algorithm
- */
- void add_stream_cipher(StreamCipher* algo, const std::string& provider);
-
- /**
* @param algo_spec the algorithm we want
* @param provider the provider we would like to use
* @returns pointer to const prototype object, ready to clone(), or NULL
@@ -130,12 +118,6 @@ class BOTAN_DLL Algorithm_Factory
const std::string& provider = "");
/**
- * @param algo the algorithm to add
- * @param provider the provider of this algorithm
- */
- void add_hash_function(HashFunction* algo, const std::string& provider);
-
- /**
* @param algo_spec the algorithm we want
* @param provider the provider we would like to use
* @returns pointer to const prototype object, ready to clone(), or NULL
@@ -153,13 +135,6 @@ class BOTAN_DLL Algorithm_Factory
const std::string& provider = "");
/**
- * @param algo the algorithm to add
- * @param provider the provider of this algorithm
- */
- void add_mac(MessageAuthenticationCode* algo,
- const std::string& provider);
-
- /**
* @param algo_spec the algorithm we want
* @param provider the provider we would like to use
* @returns pointer to const prototype object, ready to clone(), or NULL
@@ -175,38 +150,7 @@ class BOTAN_DLL Algorithm_Factory
PBKDF* make_pbkdf(const std::string& algo_spec,
const std::string& provider = "");
- /**
- * @param algo the algorithm to add
- * @param provider the provider of this algorithm
- */
- void add_pbkdf(PBKDF* algo, const std::string& provider);
-
- /**
- * An iterator for the engines in this factory
- * @deprecated Avoid in new code
- */
- class BOTAN_DLL Engine_Iterator
- {
- public:
- /**
- * @return next engine in the sequence
- */
- Engine* next() { return af.get_engine_n(n++); }
-
- /**
- * @param a an algorithm factory
- */
- Engine_Iterator(const Algorithm_Factory& a) :
- af(a) { n = 0; }
- private:
- const Algorithm_Factory& af;
- size_t n;
- };
- friend class Engine_Iterator;
-
private:
- Engine* get_engine_n(size_t n) const;
-
std::vector<Engine*> engines;
std::unique_ptr<Algorithm_Cache<BlockCipher>> block_cipher_cache;
diff --git a/src/lib/benchmark/benchmark.cpp b/src/lib/benchmark/benchmark.cpp
index 0508af79d..8e0c9fdf2 100644
--- a/src/lib/benchmark/benchmark.cpp
+++ b/src/lib/benchmark/benchmark.cpp
@@ -97,8 +97,8 @@ time_algorithm_ops(const std::string& name,
}
else
{
- std::unique_ptr<AEAD_Mode> enc(get_aead(name, ENCRYPTION));
- std::unique_ptr<AEAD_Mode> dec(get_aead(name, DECRYPTION));
+ std::unique_ptr<Cipher_Mode> enc(get_cipher_mode(name, ENCRYPTION));
+ std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(name, DECRYPTION));
if(enc && dec)
{
diff --git a/src/lib/engine/core_engine/core_engine.h b/src/lib/engine/core_engine/core_engine.h
index 9c914da66..c98ee031b 100644
--- a/src/lib/engine/core_engine/core_engine.h
+++ b/src/lib/engine/core_engine/core_engine.h
@@ -20,22 +20,6 @@ class Core_Engine : public Engine
public:
std::string provider_name() const override { return "core"; }
- PK_Ops::Key_Agreement*
- get_key_agreement_op(const Private_Key& key, RandomNumberGenerator& rng) const override;
-
- PK_Ops::Signature* get_signature_op(const Private_Key& key, const std::string& emsa,
- RandomNumberGenerator& rng) const override;
-
- PK_Ops::Verification* get_verify_op(const Public_Key& key, const std::string& emsa,
- RandomNumberGenerator& rng) const override;
-
- PK_Ops::Encryption* get_encryption_op(const Public_Key& key, RandomNumberGenerator& rng) const override;
-
- PK_Ops::Decryption* get_decryption_op(const Private_Key& key, RandomNumberGenerator& rng) const override;
-
- Modular_Exponentiator* mod_exp(const BigInt& n,
- Power_Mod::Usage_Hints) const override;
-
BlockCipher* find_block_cipher(const SCAN_Name&,
Algorithm_Factory&) const override;
diff --git a/src/lib/engine/core_engine/def_pk_ops.cpp b/src/lib/engine/core_engine/def_pk_ops.cpp
deleted file mode 100644
index f941245fb..000000000
--- a/src/lib/engine/core_engine/def_pk_ops.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-* PK Operations
-* (C) 1999-2010 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/core_engine.h>
-
-#if defined(BOTAN_HAS_RSA)
- #include <botan/rsa.h>
-#endif
-
-#if defined(BOTAN_HAS_RW)
- #include <botan/rw.h>
-#endif
-
-#if defined(BOTAN_HAS_DSA)
- #include <botan/dsa.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDSA)
- #include <botan/ecdsa.h>
-#endif
-
-#if defined(BOTAN_HAS_ELGAMAL)
- #include <botan/elgamal.h>
-#endif
-
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- #include <botan/gost_3410.h>
-#endif
-
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- #include <botan/nr.h>
-#endif
-
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- #include <botan/dh.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDH)
- #include <botan/ecdh.h>
-#endif
-
-#if defined(BOTAN_HAS_CURVE_25519)
- #include <botan/curve25519.h>
-#endif
-
-namespace Botan {
-
-PK_Ops::Encryption*
-Core_Engine::get_encryption_op(const Public_Key& key, RandomNumberGenerator&) const
- {
-#if defined(BOTAN_HAS_RSA)
- if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
- return new RSA_Public_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_ELGAMAL)
- if(const ElGamal_PublicKey* s = dynamic_cast<const ElGamal_PublicKey*>(&key))
- return new ElGamal_Encryption_Operation(*s);
-#endif
-
- return nullptr;
- }
-
-PK_Ops::Decryption*
-Core_Engine::get_decryption_op(const Private_Key& key, RandomNumberGenerator& rng) const
- {
-#if defined(BOTAN_HAS_RSA)
- if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
- return new RSA_Private_Operation(*s, rng);
-#endif
-
-#if defined(BOTAN_HAS_ELGAMAL)
- if(const ElGamal_PrivateKey* s = dynamic_cast<const ElGamal_PrivateKey*>(&key))
- return new ElGamal_Decryption_Operation(*s, rng);
-#endif
-
- return nullptr;
- }
-
-PK_Ops::Key_Agreement*
-Core_Engine::get_key_agreement_op(const Private_Key& key, RandomNumberGenerator& rng) const
- {
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- if(const DH_PrivateKey* dh = dynamic_cast<const DH_PrivateKey*>(&key))
- return new DH_KA_Operation(*dh, rng);
-#endif
-
-#if defined(BOTAN_HAS_ECDH)
- if(const ECDH_PrivateKey* ecdh = dynamic_cast<const ECDH_PrivateKey*>(&key))
- return new ECDH_KA_Operation(*ecdh);
-#endif
-
-#if defined(BOTAN_HAS_CURVE_25519)
- if(const Curve25519_PrivateKey* c25519 = dynamic_cast<const Curve25519_PrivateKey*>(&key))
- return new Curve25519_KA_Operation(*c25519);
-#endif
-
- return nullptr;
- }
-
-PK_Ops::Signature*
-Core_Engine::get_signature_op(const Private_Key& key, const std::string& emsa, RandomNumberGenerator& rng) const
- {
-#if defined(BOTAN_HAS_RSA)
- if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
- return new RSA_Private_Operation(*s, rng);
-#endif
-
-#if defined(BOTAN_HAS_RW)
- if(const RW_PrivateKey* s = dynamic_cast<const RW_PrivateKey*>(&key))
- return new RW_Signature_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_DSA)
- if(const DSA_PrivateKey* s = dynamic_cast<const DSA_PrivateKey*>(&key))
- return new DSA_Signature_Operation(*s, emsa);
-#endif
-
-#if defined(BOTAN_HAS_ECDSA)
- if(const ECDSA_PrivateKey* s = dynamic_cast<const ECDSA_PrivateKey*>(&key))
- return new ECDSA_Signature_Operation(*s, emsa);
-#endif
-
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- if(const GOST_3410_PrivateKey* s =
- dynamic_cast<const GOST_3410_PrivateKey*>(&key))
- return new GOST_3410_Signature_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- if(const NR_PrivateKey* s = dynamic_cast<const NR_PrivateKey*>(&key))
- return new NR_Signature_Operation(*s);
-#endif
-
- return nullptr;
- }
-
-PK_Ops::Verification*
-Core_Engine::get_verify_op(const Public_Key& key, const std::string& emsa, RandomNumberGenerator&) const
- {
-#if defined(BOTAN_HAS_RSA)
- if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
- return new RSA_Public_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_RW)
- if(const RW_PublicKey* s = dynamic_cast<const RW_PublicKey*>(&key))
- return new RW_Verification_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_DSA)
- if(const DSA_PublicKey* s = dynamic_cast<const DSA_PublicKey*>(&key))
- return new DSA_Verification_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_ECDSA)
- if(const ECDSA_PublicKey* s = dynamic_cast<const ECDSA_PublicKey*>(&key))
- return new ECDSA_Verification_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- if(const GOST_3410_PublicKey* s =
- dynamic_cast<const GOST_3410_PublicKey*>(&key))
- return new GOST_3410_Verification_Operation(*s);
-#endif
-
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- if(const NR_PublicKey* s = dynamic_cast<const NR_PublicKey*>(&key))
- return new NR_Verification_Operation(*s);
-#endif
-
- return nullptr;
- }
-
-}
diff --git a/src/lib/engine/core_engine/def_powm.cpp b/src/lib/engine/core_engine/def_powm.cpp
deleted file mode 100644
index 541f18c04..000000000
--- a/src/lib/engine/core_engine/def_powm.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-* Modular Exponentiation
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/core_engine.h>
-#include <botan/internal/def_powm.h>
-
-namespace Botan {
-
-/*
-* Choose a modular exponentation algorithm
-*/
-Modular_Exponentiator*
-Core_Engine::mod_exp(const BigInt& n, Power_Mod::Usage_Hints hints) const
- {
- if(n.is_odd())
- return new Montgomery_Exponentiator(n, hints);
- return new Fixed_Window_Exponentiator(n, hints);
- }
-
-}
diff --git a/src/lib/engine/core_engine/info.txt b/src/lib/engine/core_engine/info.txt
index 1343ad5e7..c726464f4 100644
--- a/src/lib/engine/core_engine/info.txt
+++ b/src/lib/engine/core_engine/info.txt
@@ -5,8 +5,6 @@ core_engine.h
</header:internal>
<source>
-def_pk_ops.cpp
-def_powm.cpp
lookup_block.cpp
lookup_hash.cpp
lookup_mac.cpp
@@ -16,8 +14,5 @@ lookup_pbkdf.cpp
<requires>
algo_factory
-filters
libstate
-mode_pad
-numbertheory
</requires>
diff --git a/src/lib/engine/dyn_engine/dyn_engine.h b/src/lib/engine/dyn_engine/dyn_engine.h
index d559a518a..d40df5663 100644
--- a/src/lib/engine/dyn_engine/dyn_engine.h
+++ b/src/lib/engine/dyn_engine/dyn_engine.h
@@ -62,42 +62,6 @@ class BOTAN_DLL Dynamically_Loaded_Engine : public Engine
return engine->find_pbkdf(algo_spec, af);
}
- Modular_Exponentiator* mod_exp(const BigInt& n,
- Power_Mod::Usage_Hints hints) const override
- {
- return engine->mod_exp(n, hints);
- }
-
- PK_Ops::Key_Agreement*
- get_key_agreement_op(const Private_Key& key, RandomNumberGenerator& rng) const override
- {
- return engine->get_key_agreement_op(key, rng);
- }
-
- PK_Ops::Signature*
- get_signature_op(const Private_Key& key, const std::string& emsa, RandomNumberGenerator& rng) const override
- {
- return engine->get_signature_op(key, emsa, rng);
- }
-
- PK_Ops::Verification*
- get_verify_op(const Public_Key& key, const std::string& emsa, RandomNumberGenerator& rng) const override
- {
- return engine->get_verify_op(key, emsa, rng);
- }
-
- PK_Ops::Encryption*
- get_encryption_op(const Public_Key& key, RandomNumberGenerator& rng) const override
- {
- return engine->get_encryption_op(key, rng);
- }
-
- PK_Ops::Decryption*
- get_decryption_op(const Private_Key& key, RandomNumberGenerator& rng) const override
- {
- return engine->get_decryption_op(key, rng);
- }
-
private:
class Dynamically_Loaded_Library* lib;
Engine* engine;
diff --git a/src/lib/engine/engine.cpp b/src/lib/engine/engine.cpp
index 15543b289..7aab64cad 100644
--- a/src/lib/engine/engine.cpp
+++ b/src/lib/engine/engine.cpp
@@ -44,41 +44,4 @@ Engine::find_pbkdf(const SCAN_Name&,
return nullptr;
}
-Modular_Exponentiator*
-Engine::mod_exp(const BigInt&,
- Power_Mod::Usage_Hints) const
- {
- return nullptr;
- }
-
-PK_Ops::Key_Agreement*
-Engine::get_key_agreement_op(const Private_Key&, RandomNumberGenerator&) const
- {
- return nullptr;
- }
-
-PK_Ops::Signature*
-Engine::get_signature_op(const Private_Key&, const std::string&, RandomNumberGenerator&) const
- {
- return nullptr;
- }
-
-PK_Ops::Verification*
-Engine::get_verify_op(const Public_Key&, const std::string&, RandomNumberGenerator&) const
- {
- return nullptr;
- }
-
-PK_Ops::Encryption*
-Engine::get_encryption_op(const Public_Key&, RandomNumberGenerator&) const
- {
- return nullptr;
- }
-
-PK_Ops::Decryption*
-Engine::get_decryption_op(const Private_Key&, RandomNumberGenerator&) const
- {
- return nullptr;
- }
-
}
diff --git a/src/lib/engine/engine.h b/src/lib/engine/engine.h
index ba8c02f93..7fe11c12e 100644
--- a/src/lib/engine/engine.h
+++ b/src/lib/engine/engine.h
@@ -16,7 +16,6 @@
#include <botan/pbkdf.h>
#include <botan/pow_mod.h>
#include <botan/pk_keys.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -82,55 +81,6 @@ class BOTAN_DLL Engine
*/
virtual PBKDF* find_pbkdf(const SCAN_Name& algo_spec,
Algorithm_Factory& af) const;
-
- /**
- * @param n the modulus
- * @param hints any use hints
- * @return newly allocated object, or NULL
- */
- virtual Modular_Exponentiator*
- mod_exp(const BigInt& n,
- Power_Mod::Usage_Hints hints) const;
-
- /**
- * Return a new operator object for this key, if possible
- * @param key the key we want an operator for
- * @return newly allocated operator object, or NULL
- */
- virtual PK_Ops::Key_Agreement*
- get_key_agreement_op(const Private_Key& key, RandomNumberGenerator& rng) const;
-
- /**
- * Return a new operator object for this key, if possible
- * @param key the key we want an operator for
- * @return newly allocated operator object, or NULL
- */
- virtual PK_Ops::Signature*
- get_signature_op(const Private_Key& key, const std::string& hash, RandomNumberGenerator& rng) const;
-
- /**
- * Return a new operator object for this key, if possible
- * @param key the key we want an operator for
- * @return newly allocated operator object, or NULL
- */
- virtual PK_Ops::Verification*
- get_verify_op(const Public_Key& key, const std::string& hash, RandomNumberGenerator& rng) const;
-
- /**
- * Return a new operator object for this key, if possible
- * @param key the key we want an operator for
- * @return newly allocated operator object, or NULL
- */
- virtual PK_Ops::Encryption*
- get_encryption_op(const Public_Key& key, RandomNumberGenerator& rng) const;
-
- /**
- * Return a new operator object for this key, if possible
- * @param key the key we want an operator for
- * @return newly allocated operator object, or NULL
- */
- virtual PK_Ops::Decryption*
- get_decryption_op(const Private_Key& key, RandomNumberGenerator& rng) const;
};
}
diff --git a/src/lib/libstate/libstate.cpp b/src/lib/libstate/libstate.cpp
index 67ee7d358..a5010fc1a 100644
--- a/src/lib/libstate/libstate.cpp
+++ b/src/lib/libstate/libstate.cpp
@@ -8,7 +8,6 @@
#include <botan/libstate.h>
#include <botan/charset.h>
#include <botan/engine.h>
-#include <botan/cpuid.h>
#include <botan/oids.h>
#include <botan/internal/core_engine.h>
#include <botan/internal/stl_util.h>
@@ -46,28 +45,18 @@ Algorithm_Factory& Library_State::algorithm_factory() const
return *m_algorithm_factory;
}
-/*
-* Return a reference to the global PRNG
-*/
-RandomNumberGenerator& Library_State::global_rng()
- {
- return *m_global_prng;
- }
-
Library_State::~Library_State()
{
}
void Library_State::initialize()
{
- if(m_algorithm_factory.get())
- throw Invalid_State("Library_State has already been initialized");
-
- CPUID::initialize();
-
SCAN_Name::set_default_aliases();
OIDS::set_defaults();
+ if(m_algorithm_factory.get())
+ throw Invalid_State("Library_State has already been initialized");
+
m_algorithm_factory.reset(new Algorithm_Factory());
#if defined(BOTAN_HAS_ENGINE_GNU_MP)
@@ -93,8 +82,6 @@ void Library_State::initialize()
algorithm_factory().add_engine(new Core_Engine);
m_sources = entropy_sources();
-
- m_global_prng.reset(new Serialized_RNG());
}
}
diff --git a/src/lib/libstate/libstate.h b/src/lib/libstate/libstate.h
index 09884df24..908f92f4d 100644
--- a/src/lib/libstate/libstate.h
+++ b/src/lib/libstate/libstate.h
@@ -38,18 +38,11 @@ class BOTAN_DLL Library_State
*/
Algorithm_Factory& algorithm_factory() const;
- /**
- * @return global RandomNumberGenerator
- */
- RandomNumberGenerator& global_rng();
-
void poll_available_sources(class Entropy_Accumulator& accum);
private:
static std::vector<std::unique_ptr<EntropySource>> entropy_sources();
- std::unique_ptr<Serialized_RNG> m_global_prng;
-
std::mutex m_entropy_src_mutex;
std::vector<std::unique_ptr<EntropySource>> m_sources;
diff --git a/src/lib/libstate/lookup.h b/src/lib/libstate/lookup.h
index b716c03bb..4350fbbd5 100644
--- a/src/lib/libstate/lookup.h
+++ b/src/lib/libstate/lookup.h
@@ -9,7 +9,6 @@
#define BOTAN_LOOKUP_H__
#include <botan/libstate.h>
-#include <botan/engine.h>
#include <botan/filters.h>
#include <botan/mode_pad.h>
#include <botan/kdf.h>
diff --git a/src/lib/math/numbertheory/pow_mod.cpp b/src/lib/math/numbertheory/pow_mod.cpp
index b5fc3747e..9a9bff2ad 100644
--- a/src/lib/math/numbertheory/pow_mod.cpp
+++ b/src/lib/math/numbertheory/pow_mod.cpp
@@ -6,8 +6,7 @@
*/
#include <botan/pow_mod.h>
-#include <botan/libstate.h>
-#include <botan/engine.h>
+#include <botan/internal/def_powm.h>
namespace Botan {
@@ -48,6 +47,7 @@ Power_Mod& Power_Mod::operator=(const Power_Mod& other)
Power_Mod::~Power_Mod()
{
delete core;
+ core = nullptr;
}
/*
@@ -56,23 +56,11 @@ Power_Mod::~Power_Mod()
void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints) const
{
delete core;
- core = nullptr;
-
- if(n != 0)
- {
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
-
- while(const Engine* engine = i.next())
- {
- core = engine->mod_exp(n, hints);
- if(core)
- break;
- }
-
- if(!core)
- throw Lookup_Error("Power_Mod: Unable to find a working engine");
- }
+ if(n.is_odd())
+ core = new Montgomery_Exponentiator(n, hints);
+ else if(n != 0)
+ core = new Fixed_Window_Exponentiator(n, hints);
}
/*
diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
index 1b46e3f13..8f6255b23 100644
--- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
+++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
@@ -10,7 +10,19 @@
namespace Botan {
-BOTAN_REGISTER_EMSA_1HASH(EMSA_PKCS1v15, "EMSA_PKCS1");
+namespace {
+
+EMSA* make_pkcs1v15(const EMSA::Spec& spec)
+ {
+ if(spec.arg(0) == "Raw")
+ return new EMSA_PKCS1v15_Raw;
+ else
+ return new EMSA_PKCS1v15(make_a<HashFunction>(spec.arg(0)));
+ }
+
+}
+
+BOTAN_REGISTER_NAMED_T(EMSA, "EMSA_PKCS1", EMSA_PCS1v15, make_pkcs1v15);
namespace {
diff --git a/src/lib/pk_pad/get_pk_pad.cpp b/src/lib/pk_pad/get_pk_pad.cpp
index e64c4e9d8..e7f234f48 100644
--- a/src/lib/pk_pad/get_pk_pad.cpp
+++ b/src/lib/pk_pad/get_pk_pad.cpp
@@ -19,7 +19,6 @@ EMSA* get_emsa(const std::string& algo_spec)
if(EMSA* emsa = make_a<EMSA>(algo_spec))
return emsa;
- printf("EMSA missing? %s\n", algo_spec.c_str());
throw Algorithm_Not_Found(algo_spec);
}
diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp
index 7a39db134..8fdd5b2c6 100644
--- a/src/lib/pubkey/curve25519/curve25519.cpp
+++ b/src/lib/pubkey/curve25519/curve25519.cpp
@@ -5,6 +5,7 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/curve25519.h>
#include <botan/ber_dec.h>
#include <botan/der_enc.h>
@@ -108,8 +109,33 @@ bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
secure_vector<byte> Curve25519_PrivateKey::agree(const byte w[], size_t w_len) const
{
size_check(w_len, "public value");
-
return curve25519(m_private, w);
}
+namespace {
+
+/**
+* Curve25519 operation
+*/
+class Curve25519_KA_Operation : public PK_Ops::Key_Agreement
+ {
+ public:
+ typedef Curve25519_PrivateKey Key_Type;
+
+ Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string&) :
+ m_key(key) {}
+
+ secure_vector<byte> agree(const byte w[], size_t w_len)
+ {
+ return m_key.agree(w, w_len);
+ }
+ private:
+ const Curve25519_PrivateKey& m_key;
+ };
+
+BOTAN_REGISTER_PK_KEY_AGREE_OP("Curve25519", Curve25519_KA_Operation);
+
+}
+
+
}
diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h
index 2baf0af26..849940505 100644
--- a/src/lib/pubkey/curve25519/curve25519.h
+++ b/src/lib/pubkey/curve25519/curve25519.h
@@ -9,7 +9,6 @@
#define BOTAN_CURVE_25519_H__
#include <botan/pk_keys.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -65,22 +64,6 @@ class BOTAN_DLL Curve25519_PrivateKey : public Curve25519_PublicKey,
secure_vector<byte> m_private;
};
-/**
-* Curve25519 operation
-*/
-class BOTAN_DLL Curve25519_KA_Operation : public PK_Ops::Key_Agreement
- {
- public:
- Curve25519_KA_Operation(const Curve25519_PrivateKey& key) : m_key(key) {}
-
- secure_vector<byte> agree(const byte w[], size_t w_len)
- {
- return m_key.agree(w, w_len);
- }
- private:
- const Curve25519_PrivateKey& m_key;
- };
-
/*
* The types above are just wrappers for curve25519_donna, plus defining
* encodings for public and private keys.
diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp
index b5fd4e643..8f44895ae 100644
--- a/src/lib/pubkey/dh/dh.cpp
+++ b/src/lib/pubkey/dh/dh.cpp
@@ -5,9 +5,17 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/dh.h>
-#include <botan/numthry.h>
#include <botan/workfactor.h>
+#include <botan/pow_mod.h>
+#include <botan/blinding.h>
+
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
namespace Botan {
@@ -75,10 +83,33 @@ std::vector<byte> DH_PrivateKey::public_value() const
return DH_PublicKey::public_value();
}
-DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh,
- RandomNumberGenerator& rng) :
+namespace {
+
+/**
+* DH operation
+*/
+class DH_KA_Operation : public PK_Ops::Key_Agreement
+ {
+ public:
+ typedef DH_PrivateKey Key_Type;
+ DH_KA_Operation(const DH_PrivateKey& key, const std::string&);
+
+ secure_vector<byte> agree(const byte w[], size_t w_len);
+ private:
+ const BigInt& p;
+
+ Fixed_Exponent_Power_Mod powermod_x_p;
+ Blinder blinder;
+ };
+
+DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh, const std::string&) :
p(dh.group_p()), powermod_x_p(dh.get_x(), p)
{
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ auto& rng = system_rng();
+#else
+ AutoSeeded_RNG rng;
+#endif
BigInt k(rng, p.bits() - 1);
blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p);
}
@@ -96,3 +127,7 @@ secure_vector<byte> DH_KA_Operation::agree(const byte w[], size_t w_len)
}
}
+
+BOTAN_REGISTER_PK_KEY_AGREE_OP("DH", DH_KA_Operation);
+
+}
diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h
index 3fa4fe694..32ca21440 100644
--- a/src/lib/pubkey/dh/dh.h
+++ b/src/lib/pubkey/dh/dh.h
@@ -9,9 +9,6 @@
#define BOTAN_DIFFIE_HELLMAN_H__
#include <botan/dl_algo.h>
-#include <botan/pow_mod.h>
-#include <botan/blinding.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -72,23 +69,6 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey,
const BigInt& x = 0);
};
-/**
-* DH operation
-*/
-class BOTAN_DLL DH_KA_Operation : public PK_Ops::Key_Agreement
- {
- public:
- DH_KA_Operation(const DH_PrivateKey& key,
- RandomNumberGenerator& rng);
-
- secure_vector<byte> agree(const byte w[], size_t w_len);
- private:
- const BigInt& p;
-
- Fixed_Exponent_Power_Mod powermod_x_p;
- Blinder blinder;
- };
-
}
#endif
diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp
index dcb8f2a64..ca5e93f4e 100644
--- a/src/lib/pubkey/dsa/dsa.cpp
+++ b/src/lib/pubkey/dsa/dsa.cpp
@@ -5,9 +5,11 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/dsa.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
+#include <botan/pow_mod.h>
+#include <botan/reducer.h>
#include <botan/rfc6979.h>
#include <future>
@@ -67,15 +69,37 @@ bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)");
}
-DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa,
- const std::string& emsa) :
- q(dsa.group_q()),
- x(dsa.get_x()),
- powermod_g_p(dsa.group_g(), dsa.group_p()),
- mod_q(dsa.group_q()),
- m_hash(hash_for_deterministic_signature(emsa))
+namespace {
+
+/**
+* Object that can create a DSA signature
+*/
+class DSA_Signature_Operation : public PK_Ops::Signature
{
- }
+ public:
+ typedef DSA_PrivateKey Key_Type;
+ DSA_Signature_Operation(const DSA_PrivateKey& dsa, const std::string& emsa) :
+ q(dsa.group_q()),
+ x(dsa.get_x()),
+ powermod_g_p(dsa.group_g(), dsa.group_p()),
+ mod_q(dsa.group_q()),
+ m_hash(hash_for_deterministic_signature(emsa))
+ {
+ }
+
+ size_t message_parts() const override { return 2; }
+ size_t message_part_size() const override { return q.bytes(); }
+ size_t max_input_bits() const override { return q.bits(); }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng) override;
+ private:
+ const BigInt& q;
+ const BigInt& x;
+ Fixed_Base_Power_Mod powermod_g_p;
+ Modular_Reducer mod_q;
+ std::string m_hash;
+ };
secure_vector<byte>
DSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
@@ -105,14 +129,38 @@ DSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
return output;
}
-DSA_Verification_Operation::DSA_Verification_Operation(const DSA_PublicKey& dsa) :
- q(dsa.group_q()), y(dsa.get_y())
+/**
+* Object that can verify a DSA signature
+*/
+class DSA_Verification_Operation : public PK_Ops::Verification
{
- powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p());
- powermod_y_p = Fixed_Base_Power_Mod(y, dsa.group_p());
- mod_p = Modular_Reducer(dsa.group_p());
- mod_q = Modular_Reducer(dsa.group_q());
- }
+ public:
+ typedef DSA_PublicKey Key_Type;
+ DSA_Verification_Operation(const DSA_PublicKey& dsa,
+ const std::string&) :
+ q(dsa.group_q()), y(dsa.get_y())
+ {
+ powermod_g_p = Fixed_Base_Power_Mod(dsa.group_g(), dsa.group_p());
+ powermod_y_p = Fixed_Base_Power_Mod(y, dsa.group_p());
+ mod_p = Modular_Reducer(dsa.group_p());
+ mod_q = Modular_Reducer(dsa.group_q());
+ }
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return q.bytes(); }
+ size_t max_input_bits() const { return q.bits(); }
+
+ bool with_recovery() const override { return false; }
+
+ bool verify(const byte msg[], size_t msg_len,
+ const byte sig[], size_t sig_len) override;
+ private:
+ const BigInt& q;
+ const BigInt& y;
+
+ Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
+ Modular_Reducer mod_p, mod_q;
+ };
bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
const byte sig[], size_t sig_len)
@@ -140,4 +188,9 @@ bool DSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
return (mod_q.reduce(s) == r);
}
+BOTAN_REGISTER_PK_SIGNATURE_OP("DSA", DSA_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("DSA", DSA_Verification_Operation);
+
+}
+
}
diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h
index 67ac26dec..294774bf0 100644
--- a/src/lib/pubkey/dsa/dsa.h
+++ b/src/lib/pubkey/dsa/dsa.h
@@ -9,9 +9,6 @@
#define BOTAN_DSA_H__
#include <botan/dl_algo.h>
-#include <botan/pk_ops.h>
-#include <botan/reducer.h>
-#include <botan/pow_mod.h>
namespace Botan {
@@ -57,52 +54,6 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey,
bool check_key(RandomNumberGenerator& rng, bool strong) const;
};
-/**
-* Object that can create a DSA signature
-*/
-class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature
- {
- public:
- DSA_Signature_Operation(const DSA_PrivateKey& dsa, const std::string& hash);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return q.bytes(); }
- size_t max_input_bits() const { return q.bits(); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
- private:
- const BigInt& q;
- const BigInt& x;
- Fixed_Base_Power_Mod powermod_g_p;
- Modular_Reducer mod_q;
- std::string m_hash;
- };
-
-/**
-* Object that can verify a DSA signature
-*/
-class BOTAN_DLL DSA_Verification_Operation : public PK_Ops::Verification
- {
- public:
- DSA_Verification_Operation(const DSA_PublicKey& dsa);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return q.bytes(); }
- size_t max_input_bits() const { return q.bits(); }
-
- bool with_recovery() const { return false; }
-
- bool verify(const byte msg[], size_t msg_len,
- const byte sig[], size_t sig_len);
- private:
- const BigInt& q;
- const BigInt& y;
-
- Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
- Modular_Reducer mod_p, mod_q;
- };
-
}
#endif
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index 418240a4c..3b0502a36 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -7,17 +7,34 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/ecdh.h>
namespace Botan {
-ECDH_KA_Operation::ECDH_KA_Operation(const ECDH_PrivateKey& key) :
- curve(key.domain().get_curve()),
- cofactor(key.domain().get_cofactor())
+namespace {
+
+/**
+* ECDH operation
+*/
+class ECDH_KA_Operation : public PK_Ops::Key_Agreement
{
- l_times_priv = inverse_mod(cofactor, key.domain().get_order()) *
- key.private_value();
- }
+ public:
+ typedef ECDH_PrivateKey Key_Type;
+
+ ECDH_KA_Operation(const ECDH_PrivateKey& key, const std::string&) :
+ curve(key.domain().get_curve()),
+ cofactor(key.domain().get_cofactor())
+ {
+ l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * key.private_value();
+ }
+
+ secure_vector<byte> agree(const byte w[], size_t w_len);
+ private:
+ const CurveGFp& curve;
+ const BigInt& cofactor;
+ BigInt l_times_priv;
+ };
secure_vector<byte> ECDH_KA_Operation::agree(const byte w[], size_t w_len)
{
@@ -33,3 +50,7 @@ secure_vector<byte> ECDH_KA_Operation::agree(const byte w[], size_t w_len)
}
}
+
+BOTAN_REGISTER_PK_KEY_AGREE_OP("ECDH", ECDH_KA_Operation);
+
+}
diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h
index 6dfa4efe6..1e806f119 100644
--- a/src/lib/pubkey/ecdh/ecdh.h
+++ b/src/lib/pubkey/ecdh/ecdh.h
@@ -11,7 +11,6 @@
#define BOTAN_ECDH_KEY_H__
#include <botan/ecc_key.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -87,21 +86,6 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey,
{ return ECDH_PublicKey::public_value(); }
};
-/**
-* ECDH operation
-*/
-class BOTAN_DLL ECDH_KA_Operation : public PK_Ops::Key_Agreement
- {
- public:
- ECDH_KA_Operation(const ECDH_PrivateKey& key);
-
- secure_vector<byte> agree(const byte w[], size_t w_len);
- private:
- const CurveGFp& curve;
- const BigInt& cofactor;
- BigInt l_times_priv;
- };
-
}
#endif
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index 1b7318f1b..6b8e5fa67 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -7,7 +7,9 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/ecdsa.h>
+#include <botan/reducer.h>
#include <botan/keypair.h>
#include <botan/rfc6979.h>
@@ -25,14 +27,40 @@ bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)");
}
-ECDSA_Signature_Operation::ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) :
- base_point(ecdsa.domain().get_base_point()),
- order(ecdsa.domain().get_order()),
- x(ecdsa.private_value()),
- mod_order(order),
- m_hash(hash_for_deterministic_signature(emsa))
+namespace {
+
+/**
+* ECDSA signature operation
+*/
+class ECDSA_Signature_Operation : public PK_Ops::Signature
{
- }
+ public:
+ typedef ECDSA_PrivateKey Key_Type;
+
+ ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa,
+ const std::string& emsa) :
+ base_point(ecdsa.domain().get_base_point()),
+ order(ecdsa.domain().get_order()),
+ x(ecdsa.private_value()),
+ mod_order(order),
+ m_hash(hash_for_deterministic_signature(emsa))
+ {
+ }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return order.bytes(); }
+ size_t max_input_bits() const { return order.bits(); }
+
+ private:
+ const PointGFp& base_point;
+ const BigInt& order;
+ const BigInt& x;
+ Modular_Reducer mod_order;
+ std::string m_hash;
+ };
secure_vector<byte>
ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
@@ -56,12 +84,34 @@ ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
return output;
}
-ECDSA_Verification_Operation::ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa) :
- base_point(ecdsa.domain().get_base_point()),
- public_point(ecdsa.public_point()),
- order(ecdsa.domain().get_order())
+/**
+* ECDSA verification operation
+*/
+class ECDSA_Verification_Operation : public PK_Ops::Verification
{
- }
+ public:
+ typedef ECDSA_PublicKey Key_Type;
+ ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa,
+ const std::string&) :
+ base_point(ecdsa.domain().get_base_point()),
+ public_point(ecdsa.public_point()),
+ order(ecdsa.domain().get_order())
+ {
+ }
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return order.bytes(); }
+ size_t max_input_bits() const { return order.bits(); }
+
+ bool with_recovery() const { return false; }
+
+ bool verify(const byte msg[], size_t msg_len,
+ const byte sig[], size_t sig_len);
+ private:
+ const PointGFp& base_point;
+ const PointGFp& public_point;
+ const BigInt& order;
+ };
bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
const byte sig[], size_t sig_len)
@@ -88,4 +138,9 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
return (R.get_affine_x() % order == r);
}
+BOTAN_REGISTER_PK_SIGNATURE_OP("ECDSA", ECDSA_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("ECDSA", ECDSA_Verification_Operation);
+
+}
+
}
diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h
index c0245e8bc..91ddb500d 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.h
+++ b/src/lib/pubkey/ecdsa/ecdsa.h
@@ -11,8 +11,6 @@
#define BOTAN_ECDSA_KEY_H__
#include <botan/ecc_key.h>
-#include <botan/reducer.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -89,52 +87,6 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey,
bool check_key(RandomNumberGenerator& rng, bool) const;
};
-/**
-* ECDSA signature operation
-*/
-class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature
- {
- public:
- ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa,
- const std::string& hash);
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return order.bytes(); }
- size_t max_input_bits() const { return order.bits(); }
-
- private:
- const PointGFp& base_point;
- const BigInt& order;
- const BigInt& x;
- Modular_Reducer mod_order;
- std::string m_hash;
- };
-
-/**
-* ECDSA verification operation
-*/
-class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification
- {
- public:
- ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return order.bytes(); }
- size_t max_input_bits() const { return order.bits(); }
-
- bool with_recovery() const { return false; }
-
- bool verify(const byte msg[], size_t msg_len,
- const byte sig[], size_t sig_len);
- private:
- const PointGFp& base_point;
- const PointGFp& public_point;
- const BigInt& order;
- };
-
}
#endif
diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp
index b3bd23c48..d59fc1f6b 100644
--- a/src/lib/pubkey/elgamal/elgamal.cpp
+++ b/src/lib/pubkey/elgamal/elgamal.cpp
@@ -5,11 +5,19 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/elgamal.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
+#include <botan/reducer.h>
+#include <botan/blinding.h>
#include <botan/workfactor.h>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
+
namespace Botan {
/*
@@ -66,7 +74,30 @@ bool ElGamal_PrivateKey::check_key(RandomNumberGenerator& rng,
return KeyPair::encryption_consistency_check(rng, *this, "EME1(SHA-1)");
}
-ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key)
+namespace {
+
+/**
+* ElGamal encryption operation
+*/
+class ElGamal_Encryption_Operation : public PK_Ops::Encryption
+ {
+ public:
+ typedef ElGamal_PublicKey Key_Type;
+
+ size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
+
+ ElGamal_Encryption_Operation(const ElGamal_PublicKey& key, const std::string&);
+
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+
+ private:
+ Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
+ Modular_Reducer mod_p;
+ };
+
+ElGamal_Encryption_Operation::ElGamal_Encryption_Operation(const ElGamal_PublicKey& key,
+ const std::string&)
{
const BigInt& p = key.group_p();
@@ -97,14 +128,38 @@ ElGamal_Encryption_Operation::encrypt(const byte msg[], size_t msg_len,
return output;
}
+/**
+* ElGamal decryption operation
+*/
+class ElGamal_Decryption_Operation : public PK_Ops::Decryption
+ {
+ public:
+ typedef ElGamal_PrivateKey Key_Type;
+
+ size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
+
+ ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& emsa);
+
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
+ private:
+ Fixed_Exponent_Power_Mod powermod_x_p;
+ Modular_Reducer mod_p;
+ Blinder blinder;
+ };
+
ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
- RandomNumberGenerator& rng)
+ const std::string&)
{
const BigInt& p = key.group_p();
powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p);
mod_p = Modular_Reducer(p);
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ auto& rng = system_rng();
+#else
+ AutoSeeded_RNG rng;
+#endif
BigInt k(rng, p.bits() - 1);
blinder = Blinder(k, powermod_x_p(k), p);
}
@@ -132,4 +187,9 @@ ElGamal_Decryption_Operation::decrypt(const byte msg[], size_t msg_len)
return BigInt::encode_locked(blinder.unblind(r));
}
+BOTAN_REGISTER_PK_ENCRYPTION_OP("ElGamal", ElGamal_Encryption_Operation);
+BOTAN_REGISTER_PK_DECRYPTION_OP("ElGamal", ElGamal_Decryption_Operation);
+
+}
+
}
diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h
index 1bef91579..90940b609 100644
--- a/src/lib/pubkey/elgamal/elgamal.h
+++ b/src/lib/pubkey/elgamal/elgamal.h
@@ -9,10 +9,6 @@
#define BOTAN_ELGAMAL_H__
#include <botan/dl_algo.h>
-#include <botan/numthry.h>
-#include <botan/reducer.h>
-#include <botan/blinding.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -55,42 +51,6 @@ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey,
const BigInt& priv_key = 0);
};
-/**
-* ElGamal encryption operation
-*/
-class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption
- {
- public:
- size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
-
- ElGamal_Encryption_Operation(const ElGamal_PublicKey& key);
-
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
-
- private:
- Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
- Modular_Reducer mod_p;
- };
-
-/**
-* ElGamal decryption operation
-*/
-class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption
- {
- public:
- size_t max_input_bits() const { return mod_p.get_modulus().bits() - 1; }
-
- ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key,
- RandomNumberGenerator& rng);
-
- secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
- private:
- Fixed_Exponent_Power_Mod powermod_x_p;
- Modular_Reducer mod_p;
- Blinder blinder;
- };
-
}
#endif
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index aeaa5735e..497712fd9 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -7,6 +7,7 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/gost_3410.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
@@ -90,16 +91,30 @@ BigInt decode_le(const byte msg[], size_t msg_len)
return BigInt(&msg_le[0], msg_le.size());
}
-}
-
-GOST_3410_Signature_Operation::GOST_3410_Signature_Operation(
- const GOST_3410_PrivateKey& gost_3410) :
-
- base_point(gost_3410.domain().get_base_point()),
- order(gost_3410.domain().get_order()),
- x(gost_3410.private_value())
+/**
+* GOST-34.10 signature operation
+*/
+class GOST_3410_Signature_Operation : public PK_Ops::Signature
{
- }
+ public:
+ typedef GOST_3410_PrivateKey Key_Type;
+ GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410, const std::string&):
+ base_point(gost_3410.domain().get_base_point()),
+ order(gost_3410.domain().get_order()),
+ x(gost_3410.private_value()) {}
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return order.bytes(); }
+ size_t max_input_bits() const { return order.bits(); }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+
+ private:
+ const PointGFp& base_point;
+ const BigInt& order;
+ const BigInt& x;
+ };
secure_vector<byte>
GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len,
@@ -117,9 +132,7 @@ GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len,
e = 1;
PointGFp k_times_P = base_point * k;
-
- BOTAN_ASSERT(k_times_P.on_the_curve(),
- "GOST 34.10 k*g is on the curve");
+ BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve");
BigInt r = k_times_P.get_affine_x() % order;
@@ -134,12 +147,32 @@ GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len,
return output;
}
-GOST_3410_Verification_Operation::GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost) :
- base_point(gost.domain().get_base_point()),
- public_point(gost.public_point()),
- order(gost.domain().get_order())
+/**
+* GOST-34.10 verification operation
+*/
+class GOST_3410_Verification_Operation : public PK_Ops::Verification
{
- }
+ public:
+ typedef GOST_3410_PublicKey Key_Type;
+
+ GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost, const std::string&) :
+ base_point(gost.domain().get_base_point()),
+ public_point(gost.public_point()),
+ order(gost.domain().get_order()) {}
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return order.bytes(); }
+ size_t max_input_bits() const { return order.bits(); }
+
+ bool with_recovery() const { return false; }
+
+ bool verify(const byte msg[], size_t msg_len,
+ const byte sig[], size_t sig_len);
+ private:
+ const PointGFp& base_point;
+ const PointGFp& public_point;
+ const BigInt& order;
+ };
bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len,
const byte sig[], size_t sig_len)
@@ -174,3 +207,8 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len,
}
}
+
+BOTAN_REGISTER_PK_SIGNATURE_OP("GOST-34.10", GOST_3410_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("GOST-34.10", GOST_3410_Verification_Operation);
+
+}
diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h
index d74ea08d7..2356d8e3d 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.h
+++ b/src/lib/pubkey/gost_3410/gost_3410.h
@@ -11,7 +11,6 @@
#define BOTAN_GOST_3410_KEY_H__
#include <botan/ecc_key.h>
-#include <botan/pk_ops.h>
namespace Botan {
@@ -91,49 +90,6 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey,
{ return EC_PublicKey::algorithm_identifier(); }
};
-/**
-* GOST-34.10 signature operation
-*/
-class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature
- {
- public:
- GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return order.bytes(); }
- size_t max_input_bits() const { return order.bits(); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
-
- private:
- const PointGFp& base_point;
- const BigInt& order;
- const BigInt& x;
- };
-
-/**
-* GOST-34.10 verification operation
-*/
-class BOTAN_DLL GOST_3410_Verification_Operation : public PK_Ops::Verification
- {
- public:
- GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return order.bytes(); }
- size_t max_input_bits() const { return order.bits(); }
-
- bool with_recovery() const { return false; }
-
- bool verify(const byte msg[], size_t msg_len,
- const byte sig[], size_t sig_len);
- private:
- const PointGFp& base_point;
- const PointGFp& public_point;
- const BigInt& order;
- };
-
}
#endif
diff --git a/src/lib/pubkey/info.txt b/src/lib/pubkey/info.txt
index 760f9c5cc..4e95c3742 100644
--- a/src/lib/pubkey/info.txt
+++ b/src/lib/pubkey/info.txt
@@ -22,6 +22,7 @@ workfactor.h
<header:internal>
pk_algs.h
+pk_utils.h
</header:internal>
<requires>
diff --git a/src/lib/pubkey/mce/mceliece.cpp b/src/lib/pubkey/mce/mceliece.cpp
index 15a6f5ea8..4986254b1 100644
--- a/src/lib/pubkey/mce/mceliece.cpp
+++ b/src/lib/pubkey/mce/mceliece.cpp
@@ -17,7 +17,6 @@
#include <botan/goppa_code.h>
#include <botan/internal/bit_ops.h>
#include <botan/internal/xor_buf.h>
-#include <iostream>
namespace Botan {
diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h
index c77dfe5b1..19de27d8e 100644
--- a/src/lib/pubkey/mce/mceliece.h
+++ b/src/lib/pubkey/mce/mceliece.h
@@ -23,123 +23,119 @@
namespace Botan {
-
-
secure_vector<gf2m> BOTAN_DLL create_random_error_positions(unsigned code_length, unsigned error_weight, RandomNumberGenerator& rng);
-
class mceliece_message_parts
-{
- public:
-
- mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length)
- :m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
- m_code_length(code_length)
- {
- m_message_word.resize(message_length);
- copy_mem(&m_message_word[0], message, message_length);
- };
-
- mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length)
- :m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
- m_message_word(message),
- m_code_length(code_length)
- {};
- static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length)
- {
- secure_vector<byte> result((code_length+7)/8);
- for(unsigned i = 0; i < err_pos_len; i++)
- {
- u16bit pos = err_pos[i];
- u32bit byte_pos = _BITP_TO_BYTEP(pos);
- if(byte_pos > result.size())
- {
- throw Invalid_Argument("error position larger than code size");
- }
- result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos));
- }
- return result;
- };
- mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length)
- :m_code_length(code_length)
- {
- size_t err_vec_len = (code_length+7)/8;
- if(message_concat_errors_len < err_vec_len )
- {
- throw Invalid_Argument("cannot split McEliece message parts");
- }
- size_t err_vec_start_pos = message_concat_errors_len - err_vec_len;
- m_message_word = secure_vector<byte>(err_vec_start_pos );
- copy_mem(&m_message_word[0], &message_concat_errors[0], err_vec_start_pos);
- m_error_vector = secure_vector<byte>(err_vec_len );
- copy_mem(&m_error_vector[0], &message_concat_errors[err_vec_start_pos], err_vec_len);
-
- };
- secure_vector<byte> get_concat() const
- {
- secure_vector<byte> result(m_error_vector.size() + m_message_word.size());
- copy_mem(&result[0], &m_message_word[0], m_message_word.size());
- copy_mem(&result[m_message_word.size()], &m_error_vector[0], m_error_vector.size());
- return result;
- };
- secure_vector<gf2m> get_error_positions() const
- {
- secure_vector<gf2m> result;
- for(unsigned i = 0; i < m_code_length; i++)
- {
-
- if ( i >= m_code_length)
- {
- throw Invalid_Argument("index out of range in get_error_positions()");
- }
- if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1)
- {
- result.push_back(i);
- }
- }
- return result;
- };
- secure_vector<byte> get_error_vector() const { return m_error_vector; };
- secure_vector<byte> get_message_word() const { return m_message_word; };
- private:
- secure_vector<byte> m_error_vector;
- secure_vector<byte> m_message_word;
- unsigned m_code_length;
-};
+ {
+ public:
+
+ mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length) :
+ m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
+ m_code_length(code_length)
+ {
+ m_message_word.resize(message_length);
+ copy_mem(&m_message_word[0], message, message_length);
+ }
+
+ mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length) :
+ m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
+ m_message_word(message),
+ m_code_length(code_length)
+ {}
+
+ static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length)
+ {
+ secure_vector<byte> result((code_length+7)/8);
+ for(unsigned i = 0; i < err_pos_len; i++)
+ {
+ u16bit pos = err_pos[i];
+ u32bit byte_pos = _BITP_TO_BYTEP(pos);
+ if(byte_pos > result.size())
+ {
+ throw Invalid_Argument("error position larger than code size");
+ }
+ result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos));
+ }
+ return result;
+ }
+
+ mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length) :
+ m_code_length(code_length)
+ {
+ size_t err_vec_len = (code_length+7)/8;
+ if(message_concat_errors_len < err_vec_len )
+ {
+ throw Invalid_Argument("cannot split McEliece message parts");
+ }
+ size_t err_vec_start_pos = message_concat_errors_len - err_vec_len;
+ m_message_word = secure_vector<byte>(err_vec_start_pos );
+ copy_mem(&m_message_word[0], &message_concat_errors[0], err_vec_start_pos);
+ m_error_vector = secure_vector<byte>(err_vec_len );
+ copy_mem(&m_error_vector[0], &message_concat_errors[err_vec_start_pos], err_vec_len);
+ }
+
+ secure_vector<byte> get_concat() const
+ {
+ secure_vector<byte> result(m_error_vector.size() + m_message_word.size());
+ copy_mem(&result[0], &m_message_word[0], m_message_word.size());
+ copy_mem(&result[m_message_word.size()], &m_error_vector[0], m_error_vector.size());
+ return result;
+ }
+
+ secure_vector<gf2m> get_error_positions() const
+ {
+ secure_vector<gf2m> result;
+ for(unsigned i = 0; i < m_code_length; i++)
+ {
+ if(i >= m_code_length)
+ {
+ throw Invalid_Argument("index out of range in get_error_positions()");
+ }
+ if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1)
+ {
+ result.push_back(i);
+ }
+ }
+ return result;
+ }
+
+ secure_vector<byte> get_error_vector() const { return m_error_vector; }
+ secure_vector<byte> get_message_word() const { return m_message_word; }
+ private:
+ secure_vector<byte> m_error_vector;
+ secure_vector<byte> m_message_word;
+ unsigned m_code_length;
+ };
class BOTAN_DLL McEliece_Private_Operation : public PK_Ops::Decryption
- {
- public:
+ {
+ public:
McEliece_Private_Operation(const McEliece_PrivateKey& mce_key);
- size_t max_input_bits() const {
- return m_priv_key.max_input_bits();
-
- };
-
+ size_t max_input_bits() const { return m_priv_key.max_input_bits(); }
-secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
- McEliece_PrivateKey const& get_key() const { return m_priv_key; };
+ McEliece_PrivateKey const& get_key() const { return m_priv_key; }
- private:
+ private:
const McEliece_PrivateKey m_priv_key;
- };
+ };
class BOTAN_DLL McEliece_Public_Operation : public PK_Ops::Encryption
-{
- public:
- McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length);
+ {
+ public:
+ McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length);
- size_t max_input_bits() const { return m_pub_key.max_input_bits(); };
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&);
+ size_t max_input_bits() const { return m_pub_key.max_input_bits(); }
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&);
- McEliece_PublicKey const& get_key() const { return m_pub_key; };
+ McEliece_PublicKey const& get_key() const { return m_pub_key; }
- private:
- McEliece_PublicKey m_pub_key;
- u32bit m_code_length;
-};
+ private:
+ McEliece_PublicKey m_pub_key;
+ u32bit m_code_length;
+ };
/**
* Estimate work factor for McEliece
diff --git a/src/lib/pubkey/nr/nr.cpp b/src/lib/pubkey/nr/nr.cpp
index f100efb26..6e3a8f0c1 100644
--- a/src/lib/pubkey/nr/nr.cpp
+++ b/src/lib/pubkey/nr/nr.cpp
@@ -5,9 +5,10 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/nr.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
+#include <botan/reducer.h>
#include <future>
namespace Botan {
@@ -72,13 +73,35 @@ bool NR_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)");
}
-NR_Signature_Operation::NR_Signature_Operation(const NR_PrivateKey& nr) :
- q(nr.group_q()),
- x(nr.get_x()),
- powermod_g_p(nr.group_g(), nr.group_p()),
- mod_q(nr.group_q())
+namespace {
+
+/**
+* Nyberg-Rueppel signature operation
+*/
+class NR_Signature_Operation : public PK_Ops::Signature
{
- }
+ public:
+ typedef NR_PrivateKey Key_Type;
+ NR_Signature_Operation(const NR_PrivateKey& nr, const std::string&) :
+ q(nr.group_q()),
+ x(nr.get_x()),
+ powermod_g_p(nr.group_g(), nr.group_p()),
+ mod_q(nr.group_q())
+ {
+ }
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return q.bytes(); }
+ size_t max_input_bits() const { return (q.bits() - 1); }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+ private:
+ const BigInt& q;
+ const BigInt& x;
+ Fixed_Base_Power_Mod powermod_g_p;
+ Modular_Reducer mod_q;
+ };
secure_vector<byte>
NR_Signature_Operation::sign(const byte msg[], size_t msg_len,
@@ -110,14 +133,37 @@ NR_Signature_Operation::sign(const byte msg[], size_t msg_len,
return output;
}
-NR_Verification_Operation::NR_Verification_Operation(const NR_PublicKey& nr) :
- q(nr.group_q()), y(nr.get_y())
+
+/**
+* Nyberg-Rueppel verification operation
+*/
+class NR_Verification_Operation : public PK_Ops::Verification
{
- powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p());
- powermod_y_p = Fixed_Base_Power_Mod(y, nr.group_p());
- mod_p = Modular_Reducer(nr.group_p());
- mod_q = Modular_Reducer(nr.group_q());
- }
+ public:
+ typedef NR_PublicKey Key_Type;
+ NR_Verification_Operation(const NR_PublicKey& nr, const std::string&) :
+ q(nr.group_q()), y(nr.get_y())
+ {
+ powermod_g_p = Fixed_Base_Power_Mod(nr.group_g(), nr.group_p());
+ powermod_y_p = Fixed_Base_Power_Mod(y, nr.group_p());
+ mod_p = Modular_Reducer(nr.group_p());
+ mod_q = Modular_Reducer(nr.group_q());
+ }
+
+ size_t message_parts() const { return 2; }
+ size_t message_part_size() const { return q.bytes(); }
+ size_t max_input_bits() const { return (q.bits() - 1); }
+
+ bool with_recovery() const { return true; }
+
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len);
+ private:
+ const BigInt& q;
+ const BigInt& y;
+
+ Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
+ Modular_Reducer mod_p, mod_q;
+ };
secure_vector<byte>
NR_Verification_Operation::verify_mr(const byte msg[], size_t msg_len)
@@ -139,5 +185,9 @@ NR_Verification_Operation::verify_mr(const byte msg[], size_t msg_len)
BigInt i = mod_p.multiply(g_d, future_y_c.get());
return BigInt::encode_locked(mod_q.reduce(c - i));
}
+}
+
+BOTAN_REGISTER_PK_SIGNATURE_OP("NR", NR_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("NR", NR_Verification_Operation);
}
diff --git a/src/lib/pubkey/nr/nr.h b/src/lib/pubkey/nr/nr.h
index 76f689079..51752f8ce 100644
--- a/src/lib/pubkey/nr/nr.h
+++ b/src/lib/pubkey/nr/nr.h
@@ -9,9 +9,6 @@
#define BOTAN_NYBERG_RUEPPEL_H__
#include <botan/dl_algo.h>
-#include <botan/pk_ops.h>
-#include <botan/numthry.h>
-#include <botan/reducer.h>
namespace Botan {
@@ -55,50 +52,6 @@ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey,
const BigInt& x = 0);
};
-/**
-* Nyberg-Rueppel signature operation
-*/
-class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature
- {
- public:
- NR_Signature_Operation(const NR_PrivateKey& nr);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return q.bytes(); }
- size_t max_input_bits() const { return (q.bits() - 1); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
- private:
- const BigInt& q;
- const BigInt& x;
- Fixed_Base_Power_Mod powermod_g_p;
- Modular_Reducer mod_q;
- };
-
-/**
-* Nyberg-Rueppel verification operation
-*/
-class BOTAN_DLL NR_Verification_Operation : public PK_Ops::Verification
- {
- public:
- NR_Verification_Operation(const NR_PublicKey& nr);
-
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return q.bytes(); }
- size_t max_input_bits() const { return (q.bits() - 1); }
-
- bool with_recovery() const { return true; }
-
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len);
- private:
- const BigInt& q;
- const BigInt& y;
-
- Fixed_Base_Power_Mod powermod_g_p, powermod_y_p;
- Modular_Reducer mod_p, mod_q;
- };
-
}
#endif
diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h
index 7965e7464..7277c7ad5 100644
--- a/src/lib/pubkey/pk_ops.h
+++ b/src/lib/pubkey/pk_ops.h
@@ -8,6 +8,7 @@
#ifndef BOTAN_PK_OPERATIONS_H__
#define BOTAN_PK_OPERATIONS_H__
+#include <botan/pk_keys.h>
#include <botan/secmem.h>
#include <botan/rng.h>
@@ -15,6 +16,24 @@ namespace Botan {
namespace PK_Ops {
+template<typename Key>
+struct PK_Spec
+ {
+ public:
+ PK_Spec(const Key& key, const std::string& pad) :
+ m_key(key), m_pad(pad) {}
+
+ std::string algo_name() const { return m_key.algo_name(); }
+
+ std::string as_string() const { return algo_name() + "/" + padding(); }
+
+ const Key& key() const { return m_key; }
+ const std::string& padding() const { return m_pad; }
+ private:
+ const Key& m_key;
+ const std::string m_pad;
+ };
+
/**
* Public key encryption interface
*/
@@ -23,8 +42,9 @@ class BOTAN_DLL Encryption
public:
virtual size_t max_input_bits() const = 0;
- virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng) = 0;
+ virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) = 0;
+
+ typedef PK_Spec<Public_Key> Spec;
virtual ~Encryption() {}
};
@@ -37,8 +57,9 @@ class BOTAN_DLL Decryption
public:
virtual size_t max_input_bits() const = 0;
- virtual secure_vector<byte> decrypt(const byte msg[],
- size_t msg_len) = 0;
+ virtual secure_vector<byte> decrypt(const byte msg[], size_t msg_len) = 0;
+
+ typedef PK_Spec<Private_Key> Spec;
virtual ~Decryption() {}
};
@@ -76,6 +97,8 @@ class BOTAN_DLL Signature
virtual secure_vector<byte> sign(const byte msg[], size_t msg_len,
RandomNumberGenerator& rng) = 0;
+ typedef PK_Spec<Private_Key> Spec;
+
virtual ~Signature() {}
};
@@ -136,6 +159,8 @@ class BOTAN_DLL Verification
throw Invalid_State("Message recovery not supported");
}
+ typedef PK_Spec<Public_Key> Spec;
+
virtual ~Verification() {}
};
@@ -153,6 +178,8 @@ class BOTAN_DLL Key_Agreement
*/
virtual secure_vector<byte> agree(const byte w[], size_t w_len) = 0;
+ typedef PK_Spec<Private_Key> Spec;
+
virtual ~Key_Agreement() {}
};
diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp
index 07f02d3e0..95d61ad4c 100644
--- a/src/lib/pubkey/pubkey.cpp
+++ b/src/lib/pubkey/pubkey.cpp
@@ -10,27 +10,34 @@
#include <botan/ber_dec.h>
#include <botan/bigint.h>
#include <botan/parsing.h>
-#include <botan/libstate.h>
-#include <botan/engine.h>
+#include <botan/algo_registry.h>
#include <botan/internal/bit_ops.h>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
+
namespace Botan {
+namespace {
+
+template<typename T, typename Key>
+T* get_pk_op(const Key& key, const std::string& pad)
+ {
+ return Algo_Registry<T>::global_registry().make(typename T::Spec(key, pad));
+ }
+
+}
+
/*
* PK_Encryptor_EME Constructor
*/
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
const std::string& eme_name)
{
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
- RandomNumberGenerator& rng = global_state().global_rng();
-
- while(const Engine* engine = i.next())
- {
- m_op.reset(engine->get_encryption_op(key, rng));
- if(m_op)
- break;
- }
+ m_op.reset(get_pk_op<PK_Ops::Encryption>(key, eme_name));
if(!m_op)
throw Lookup_Error("Encryption with " + key.algo_name() + " not supported");
@@ -82,19 +89,7 @@ size_t PK_Encryptor_EME::maximum_input_size() const
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
const std::string& eme_name)
{
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
- RandomNumberGenerator& rng = global_state().global_rng();
-
- while(const Engine* engine = i.next())
- {
- m_op.reset(engine->get_decryption_op(key, rng));
- if(m_op)
- break;
- }
-
- if(!m_op)
- throw Lookup_Error("Decryption with " + key.algo_name() + " not supported");
-
+ m_op.reset(get_pk_op<PK_Ops::Decryption>(key, eme_name));
m_eme.reset(get_eme(eme_name));
}
@@ -105,7 +100,7 @@ secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[],
size_t length) const
{
try {
- secure_vector<byte> decrypted = m_op->decrypt(msg, length);
+ const secure_vector<byte> decrypted = m_op->decrypt(msg, length);
if(m_eme)
return m_eme->decode(decrypted, m_op->max_input_bits());
else
@@ -125,25 +120,12 @@ PK_Signer::PK_Signer(const Private_Key& key,
Signature_Format format,
Fault_Protection prot)
{
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
- RandomNumberGenerator& rng = global_state().global_rng();
+ m_op.reset(get_pk_op<PK_Ops::Signature>(key, emsa_name));
- m_op = nullptr;
- m_verify_op = nullptr;
-
- while(const Engine* engine = i.next())
- {
- if(!m_op)
- m_op.reset(engine->get_signature_op(key, emsa_name, rng));
-
- if(!m_verify_op && prot == ENABLE_FAULT_PROTECTION)
- m_verify_op.reset(engine->get_verify_op(key, emsa_name, rng));
-
- if(m_op && (m_verify_op || prot == DISABLE_FAULT_PROTECTION))
- break;
- }
+ if(prot == ENABLE_FAULT_PROTECTION)
+ m_verify_op.reset(get_pk_op<PK_Ops::Verification>(key, emsa_name));
- if(!m_op || (!m_verify_op && prot == ENABLE_FAULT_PROTECTION))
+ if(!m_op || (prot == ENABLE_FAULT_PROTECTION && !m_verify_op))
throw Lookup_Error("Signing with " + key.algo_name() + " not supported");
m_emsa.reset(get_emsa(emsa_name));
@@ -244,15 +226,7 @@ PK_Verifier::PK_Verifier(const Public_Key& key,
const std::string& emsa_name,
Signature_Format format)
{
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
- RandomNumberGenerator& rng = global_state().global_rng();
-
- while(const Engine* engine = i.next())
- {
- m_op.reset(engine->get_verify_op(key, emsa_name, rng));
- if(m_op)
- break;
- }
+ m_op.reset(get_pk_op<PK_Ops::Verification>(key, emsa_name));
if(!m_op)
throw Lookup_Error("Verification with " + key.algo_name() + " not supported");
@@ -338,7 +312,7 @@ bool PK_Verifier::validate_signature(const secure_vector<byte>& msg,
}
else
{
- RandomNumberGenerator& rng = global_state().global_rng();
+ Null_RNG rng;
secure_vector<byte> encoded =
m_emsa->encoding_of(msg, m_op->max_input_bits(), rng);
@@ -353,15 +327,7 @@ bool PK_Verifier::validate_signature(const secure_vector<byte>& msg,
PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key,
const std::string& kdf_name)
{
- Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory());
- RandomNumberGenerator& rng = global_state().global_rng();
-
- while(const Engine* engine = i.next())
- {
- m_op.reset(engine->get_key_agreement_op(key, rng));
- if(m_op)
- break;
- }
+ m_op.reset(get_pk_op<PK_Ops::Key_Agreement>(key, kdf_name));
if(!m_op)
throw Lookup_Error("Key agreement with " + key.algo_name() + " not supported");
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index 2a0e8253e..9393cb954 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -5,12 +5,20 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/rsa.h>
#include <botan/parsing.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
+#include <botan/blinding.h>
+#include <botan/reducer.h>
#include <future>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
+
namespace Botan {
/*
@@ -59,63 +67,182 @@ bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-1)");
}
-RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa,
- RandomNumberGenerator& rng) :
- n(rsa.get_n()),
- q(rsa.get_q()),
- c(rsa.get_c()),
- powermod_e_n(rsa.get_e(), rsa.get_n()),
- powermod_d1_p(rsa.get_d1(), rsa.get_p()),
- powermod_d2_q(rsa.get_d2(), rsa.get_q()),
- mod_p(rsa.get_p())
- {
- BigInt k(rng, n.bits() - 1);
- blinder = Blinder(powermod_e_n(k), inverse_mod(k, n), n);
- }
+namespace {
-BigInt RSA_Private_Operation::private_op(const BigInt& m) const
+/**
+* RSA private (decrypt/sign) operation
+*/
+class RSA_Private_Operation
+ {
+ protected:
+ size_t get_max_input_bits() const { return (n.bits() - 1); }
+
+ RSA_Private_Operation(const RSA_PrivateKey& rsa) :
+ n(rsa.get_n()),
+ q(rsa.get_q()),
+ c(rsa.get_c()),
+ m_powermod_e_n(rsa.get_e(), rsa.get_n()),
+ m_powermod_d1_p(rsa.get_d1(), rsa.get_p()),
+ m_powermod_d2_q(rsa.get_d2(), rsa.get_q()),
+ m_mod_p(rsa.get_p())
+ {
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ auto& rng = system_rng();
+#else
+ AutoSeeded_RNG rng;
+#endif
+ BigInt k(rng, n.bits() - 1);
+ m_blinder = Blinder(m_powermod_e_n(k), inverse_mod(k, n), n);
+ }
+
+ BigInt blinded_private_op(const BigInt& m) const
+ {
+ return m_blinder.unblind(private_op(m_blinder.blind(m)));
+ }
+
+ BigInt private_op(const BigInt& m) const
+ {
+ if(m >= n)
+ throw Invalid_Argument("RSA private op - input is too large");
+
+ auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m);
+ BigInt j2 = m_powermod_d2_q(m);
+ BigInt j1 = future_j1.get();
+
+ j1 = m_mod_p.reduce(sub_mul(j1, j2, c));
+
+ return mul_add(j1, q, j2);
+ }
+
+ const BigInt& n;
+ const BigInt& q;
+ const BigInt& c;
+ Fixed_Exponent_Power_Mod m_powermod_e_n, m_powermod_d1_p, m_powermod_d2_q;
+ Modular_Reducer m_mod_p;
+ Blinder m_blinder;
+ };
+
+class RSA_Signature_Operation : public PK_Ops::Signature,
+ private RSA_Private_Operation
{
- if(m >= n)
- throw Invalid_Argument("RSA private op - input is too large");
+ public:
+ typedef RSA_PrivateKey Key_Type;
+
+ size_t max_input_bits() const override { return get_max_input_bits(); };
+
+ RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string&) :
+ RSA_Private_Operation(rsa)
+ {
+ }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator&) override
+ {
+ /* We don't check signatures against powermod_e_n here because
+ PK_Signer checks verification consistency for all signature
+ algorithms.
+ */
+ const BigInt m(msg, msg_len);
+ const BigInt x = blinded_private_op(m);
+ return BigInt::encode_1363(x, n.bytes());
+ }
+ };
+
+class RSA_Decryption_Operation : public PK_Ops::Decryption,
+ private RSA_Private_Operation
+ {
+ public:
+ typedef RSA_PrivateKey Key_Type;
- auto future_j1 = std::async(std::launch::async, powermod_d1_p, m);
- BigInt j2 = powermod_d2_q(m);
- BigInt j1 = future_j1.get();
+ size_t max_input_bits() const override { return get_max_input_bits(); };
- j1 = mod_p.reduce(sub_mul(j1, j2, c));
+ RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string&) :
+ RSA_Private_Operation(rsa)
+ {
+ }
- return mul_add(j1, q, j2);
- }
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override
+ {
+ const BigInt m(msg, msg_len);
+ const BigInt x = blinded_private_op(m);
+ BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA decrypt consistency check");
+ return BigInt::encode_locked(x);
+ }
+ };
-secure_vector<byte>
-RSA_Private_Operation::sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng)
+
+/**
+* RSA public (encrypt/verify) operation
+*/
+class RSA_Public_Operation
{
- rng.add_entropy(msg, msg_len);
+ public:
+ RSA_Public_Operation(const RSA_PublicKey& rsa) :
+ n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n())
+ {}
+
+ size_t get_max_input_bits() const { return (n.bits() - 1); }
+
+ protected:
+ BigInt public_op(const BigInt& m) const
+ {
+ if(m >= n)
+ throw Invalid_Argument("RSA public op - input is too large");
+ return powermod_e_n(m);
+ }
+
+ const BigInt& n;
+ Fixed_Exponent_Power_Mod powermod_e_n;
+ };
+
+class RSA_Encryption_Operation : public PK_Ops::Encryption,
+ private RSA_Public_Operation
+ {
+ public:
+ typedef RSA_PublicKey Key_Type;
+
+ RSA_Encryption_Operation(const RSA_PublicKey& rsa, const std::string&) :
+ RSA_Public_Operation(rsa)
+ {
+ }
+
+ size_t max_input_bits() const override { return get_max_input_bits(); };
+
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
+ RandomNumberGenerator&)
+ {
+ BigInt m(msg, msg_len);
+ return BigInt::encode_1363(public_op(m), n.bytes());
+ }
+ };
+
+class RSA_Verify_Operation : public PK_Ops::Verification,
+ private RSA_Public_Operation
+ {
+ public:
+ typedef RSA_PublicKey Key_Type;
- /* We don't check signatures against powermod_e_n here because
- PK_Signer checks verification consistency for all signature
- algorithms.
- */
+ size_t max_input_bits() const override { return get_max_input_bits(); };
- const BigInt m(msg, msg_len);
- const BigInt x = blinder.unblind(private_op(blinder.blind(m)));
- return BigInt::encode_1363(x, n.bytes());
- }
+ RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string&) :
+ RSA_Public_Operation(rsa)
+ {
+ }
-/*
-* RSA Decryption Operation
-*/
-secure_vector<byte>
-RSA_Private_Operation::decrypt(const byte msg[], size_t msg_len)
- {
- const BigInt m(msg, msg_len);
- const BigInt x = blinder.unblind(private_op(blinder.blind(m)));
+ bool with_recovery() const override { return true; }
- BOTAN_ASSERT(m == powermod_e_n(x),
- "RSA decrypt passed consistency check");
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override
+ {
+ BigInt m(msg, msg_len);
+ return BigInt::encode_locked(public_op(m));
+ }
+ };
- return BigInt::encode_locked(x);
- }
+BOTAN_REGISTER_PK_ENCRYPTION_OP("RSA", RSA_Encryption_Operation);
+BOTAN_REGISTER_PK_DECRYPTION_OP("RSA", RSA_Decryption_Operation);
+BOTAN_REGISTER_PK_SIGNATURE_OP("RSA", RSA_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("RSA", RSA_Verify_Operation);
+
+}
}
diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h
index 8a599d2ab..67357d859 100644
--- a/src/lib/pubkey/rsa/rsa.h
+++ b/src/lib/pubkey/rsa/rsa.h
@@ -9,9 +9,7 @@
#define BOTAN_RSA_H__
#include <botan/if_algo.h>
-#include <botan/pk_ops.h>
-#include <botan/reducer.h>
-#include <botan/blinding.h>
+
namespace Botan {
@@ -83,73 +81,6 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey,
size_t bits, size_t exp = 65537);
};
-/**
-* RSA private (decrypt/sign) operation
-*/
-class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature,
- public PK_Ops::Decryption
- {
- public:
- RSA_Private_Operation(const RSA_PrivateKey& rsa,
- RandomNumberGenerator& rng);
-
- size_t max_input_bits() const { return (n.bits() - 1); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
-
- secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
-
- private:
- BigInt private_op(const BigInt& m) const;
-
- const BigInt& n;
- const BigInt& q;
- const BigInt& c;
- Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q;
- Modular_Reducer mod_p;
- Blinder blinder;
- };
-
-/**
-* RSA public (encrypt/verify) operation
-*/
-class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification,
- public PK_Ops::Encryption
- {
- public:
- RSA_Public_Operation(const RSA_PublicKey& rsa) :
- n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n())
- {}
-
- size_t max_input_bits() const { return (n.bits() - 1); }
- bool with_recovery() const { return true; }
-
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
- RandomNumberGenerator&)
- {
- BigInt m(msg, msg_len);
- return BigInt::encode_1363(public_op(m), n.bytes());
- }
-
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len)
- {
- BigInt m(msg, msg_len);
- return BigInt::encode_locked(public_op(m));
- }
-
- private:
- BigInt public_op(const BigInt& m) const
- {
- if(m >= n)
- throw Invalid_Argument("RSA public op - input is too large");
- return powermod_e_n(m);
- }
-
- const BigInt& n;
- Fixed_Exponent_Power_Mod powermod_e_n;
- };
-
}
#endif
diff --git a/src/lib/pubkey/rw/rw.cpp b/src/lib/pubkey/rw/rw.cpp
index a2f21ecb8..3c7a6250b 100644
--- a/src/lib/pubkey/rw/rw.cpp
+++ b/src/lib/pubkey/rw/rw.cpp
@@ -5,10 +5,12 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/rw.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
#include <botan/parsing.h>
+#include <botan/reducer.h>
+#include <botan/blinding.h>
#include <algorithm>
#include <future>
@@ -60,16 +62,42 @@ bool RW_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return KeyPair::signature_consistency_check(rng, *this, "EMSA2(SHA-1)");
}
-RW_Signature_Operation::RW_Signature_Operation(const RW_PrivateKey& rw) :
- n(rw.get_n()),
- e(rw.get_e()),
- q(rw.get_q()),
- c(rw.get_c()),
- powermod_d1_p(rw.get_d1(), rw.get_p()),
- powermod_d2_q(rw.get_d2(), rw.get_q()),
- mod_p(rw.get_p())
+namespace {
+
+/**
+* Rabin-Williams Signature Operation
+*/
+class RW_Signature_Operation : public PK_Ops::Signature
{
- }
+ public:
+ typedef RW_PrivateKey Key_Type;
+
+ RW_Signature_Operation(const RW_PrivateKey& rw,
+ const std::string&) :
+ n(rw.get_n()),
+ e(rw.get_e()),
+ q(rw.get_q()),
+ c(rw.get_c()),
+ powermod_d1_p(rw.get_d1(), rw.get_p()),
+ powermod_d2_q(rw.get_d2(), rw.get_q()),
+ mod_p(rw.get_p())
+ {
+ }
+
+ size_t max_input_bits() const { return (n.bits() - 1); }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator& rng);
+ private:
+ const BigInt& n;
+ const BigInt& e;
+ const BigInt& q;
+ const BigInt& c;
+
+ Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q;
+ Modular_Reducer mod_p;
+ Blinder blinder;
+ };
secure_vector<byte>
RW_Signature_Operation::sign(const byte msg[], size_t msg_len,
@@ -104,6 +132,28 @@ RW_Signature_Operation::sign(const byte msg[], size_t msg_len,
return BigInt::encode_1363(std::min(r, n - r), n.bytes());
}
+/**
+* Rabin-Williams Verification Operation
+*/
+class RW_Verification_Operation : public PK_Ops::Verification
+ {
+ public:
+ typedef RW_PublicKey Key_Type;
+
+ RW_Verification_Operation(const RW_PublicKey& rw, const std::string&) :
+ n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n())
+ {}
+
+ size_t max_input_bits() const { return (n.bits() - 1); }
+ bool with_recovery() const { return true; }
+
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len);
+
+ private:
+ const BigInt& n;
+ Fixed_Exponent_Power_Mod powermod_e_n;
+ };
+
secure_vector<byte>
RW_Verification_Operation::verify_mr(const byte msg[], size_t msg_len)
{
@@ -127,4 +177,9 @@ RW_Verification_Operation::verify_mr(const byte msg[], size_t msg_len)
throw Invalid_Argument("RW signature verification: Invalid signature");
}
+BOTAN_REGISTER_PK_SIGNATURE_OP("RW", RW_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("RW", RW_Verification_Operation);
+
+}
+
}
diff --git a/src/lib/pubkey/rw/rw.h b/src/lib/pubkey/rw/rw.h
index b42d26b64..5d754e817 100644
--- a/src/lib/pubkey/rw/rw.h
+++ b/src/lib/pubkey/rw/rw.h
@@ -9,9 +9,6 @@
#define BOTAN_RW_H__
#include <botan/if_algo.h>
-#include <botan/pk_ops.h>
-#include <botan/reducer.h>
-#include <botan/blinding.h>
namespace Botan {
@@ -59,49 +56,6 @@ class BOTAN_DLL RW_PrivateKey : public RW_PublicKey,
bool check_key(RandomNumberGenerator& rng, bool) const;
};
-/**
-* Rabin-Williams Signature Operation
-*/
-class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature
- {
- public:
- RW_Signature_Operation(const RW_PrivateKey& rw);
-
- size_t max_input_bits() const { return (n.bits() - 1); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
- private:
- const BigInt& n;
- const BigInt& e;
- const BigInt& q;
- const BigInt& c;
-
- Fixed_Exponent_Power_Mod powermod_d1_p, powermod_d2_q;
- Modular_Reducer mod_p;
- Blinder blinder;
- };
-
-/**
-* Rabin-Williams Verification Operation
-*/
-class BOTAN_DLL RW_Verification_Operation : public PK_Ops::Verification
- {
- public:
- RW_Verification_Operation(const RW_PublicKey& rw) :
- n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n())
- {}
-
- size_t max_input_bits() const { return (n.bits() - 1); }
- bool with_recovery() const { return true; }
-
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len);
-
- private:
- const BigInt& n;
- Fixed_Exponent_Power_Mod powermod_e_n;
- };
-
}
#endif
diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp
index 14c7196d1..8989c5026 100644
--- a/src/lib/rng/rng.cpp
+++ b/src/lib/rng/rng.cpp
@@ -1,5 +1,5 @@
/*
-* Random Number Generator Base
+* Random Number Generator
* (C) 1999-2008 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
@@ -7,28 +7,20 @@
#include <botan/rng.h>
#include <botan/hmac_rng.h>
-#include <botan/libstate.h>
+#include <botan/algo_registry.h>
namespace Botan {
RandomNumberGenerator* RandomNumberGenerator::make_rng()
{
- return make_rng(global_state().algorithm_factory()).release();
- }
-
-/*
-* Create and seed a new RNG object
-*/
-std::unique_ptr<RandomNumberGenerator> RandomNumberGenerator::make_rng(Algorithm_Factory& af)
- {
std::unique_ptr<RandomNumberGenerator> rng(
- new HMAC_RNG(af.make_mac("HMAC(SHA-512)"),
- af.make_mac("HMAC(SHA-256)"))
+ new HMAC_RNG(make_a<MessageAuthenticationCode>("HMAC(SHA-512)"),
+ make_a<MessageAuthenticationCode>("HMAC(SHA-256)"))
);
rng->reseed(256);
- return rng;
+ return rng.release();
}
}
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index 9621fb3da..836eb1006 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -28,12 +28,6 @@ class BOTAN_DLL RandomNumberGenerator
static RandomNumberGenerator* make_rng();
/**
- * Create a seeded and active RNG object for general application use
- * Added in 1.11.5
- */
- static std::unique_ptr<RandomNumberGenerator> make_rng(class Algorithm_Factory& af);
-
- /**
* Randomize a byte array.
* @param output the byte array to hold the random output.
* @param length the length of the byte array output.
diff --git a/src/lib/tls/msg_cert_verify.cpp b/src/lib/tls/msg_cert_verify.cpp
index 3837e3871..74565e29b 100644
--- a/src/lib/tls/msg_cert_verify.cpp
+++ b/src/lib/tls/msg_cert_verify.cpp
@@ -82,7 +82,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert,
std::unique_ptr<Public_Key> key(cert.subject_public_key());
std::pair<std::string, Signature_Format> format =
- state.understand_sig_format(*key.get(), m_hash_algo, m_sig_algo, true);
+ state.understand_sig_format(*key.get(), m_hash_algo, m_sig_algo);
PK_Verifier verifier(*key, format.first, format.second);
diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp
index 2950f1906..3fcdb5ab2 100644
--- a/src/lib/tls/msg_server_kex.cpp
+++ b/src/lib/tls/msg_server_kex.cpp
@@ -256,7 +256,7 @@ bool Server_Key_Exchange::verify(const Public_Key& server_key,
const Handshake_State& state) const
{
std::pair<std::string, Signature_Format> format =
- state.understand_sig_format(server_key, m_hash_algo, m_sig_algo, false);
+ state.understand_sig_format(server_key, m_hash_algo, m_sig_algo);
PK_Verifier verifier(server_key, format.first, format.second);
diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp
index 64d35fd6b..883527810 100644
--- a/src/lib/tls/tls_handshake_state.cpp
+++ b/src/lib/tls/tls_handshake_state.cpp
@@ -367,8 +367,7 @@ Handshake_State::choose_sig_format(const Private_Key& key,
std::pair<std::string, Signature_Format>
Handshake_State::understand_sig_format(const Public_Key& key,
std::string hash_algo,
- std::string sig_algo,
- bool for_client_auth) const
+ std::string sig_algo) const
{
const std::string algo_name = key.algo_name();
diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h
index bb2abc209..3ad44c613 100644
--- a/src/lib/tls/tls_handshake_state.h
+++ b/src/lib/tls/tls_handshake_state.h
@@ -83,8 +83,7 @@ class Handshake_State
std::pair<std::string, Signature_Format>
understand_sig_format(const Public_Key& key,
std::string hash_algo,
- std::string sig_algo,
- bool for_client_auth) const;
+ std::string sig_algo) const;
std::pair<std::string, Signature_Format>
choose_sig_format(const Private_Key& key,
diff --git a/src/lib/utils/cpuid.h b/src/lib/utils/cpuid.h
index 14901199c..5d8093753 100644
--- a/src/lib/utils/cpuid.h
+++ b/src/lib/utils/cpuid.h
@@ -27,7 +27,12 @@ class BOTAN_DLL CPUID
/**
* Return a best guess of the cache line size
*/
- static size_t cache_line_size() { return g_cache_line_size; }
+ static size_t cache_line_size() { initialize(); return g_cache_line_size; }
+
+ /**
+ * Check if the processor supports AltiVec/VMX
+ */
+ static bool has_altivec() { initialize(); return g_altivec_capable; }
/**
* Check if the processor supports RDTSC
@@ -113,11 +118,6 @@ class BOTAN_DLL CPUID
static bool has_rdseed()
{ return x86_processor_flags_has(CPUID_RDSEED_BIT); }
- /**
- * Check if the processor supports AltiVec/VMX
- */
- static bool has_altivec() { return g_altivec_capable; }
-
static void print(std::ostream& o);
private:
enum CPUID_bits {