From 0dd060fed07b0060f94e3bae62e125a85c1bb877 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 4 Feb 2015 04:03:38 +0000 Subject: Remove algo factory, engines, global RNG, global state, etc. Convert all uses of Algorithm_Factory and the engines to using Algo_Registry The shared pool of entropy sources remains but is moved to EntropySource. With that and few remaining initializations (default OIDs and aliases) moved elsewhere, the global state is empty and init and shutdown are no-ops. Remove almost all of the headers and code for handling the global state, except LibraryInitializer which remains as a compatability stub. Update seeding for blinding so only one hacky almost-global RNG instance needs to be setup instead of across all pubkey uses (it uses either the system RNG or an AutoSeeded_RNG if the system RNG is not available). --- src/lib/algo_factory/algo_cache.h | 239 ---------------------------- src/lib/algo_factory/algo_factory.cpp | 291 ---------------------------------- src/lib/algo_factory/algo_factory.h | 165 ------------------- src/lib/algo_factory/info.txt | 24 --- src/lib/algo_factory/prov_weight.cpp | 34 ---- 5 files changed, 753 deletions(-) delete mode 100644 src/lib/algo_factory/algo_cache.h delete mode 100644 src/lib/algo_factory/algo_factory.cpp delete mode 100644 src/lib/algo_factory/algo_factory.h delete mode 100644 src/lib/algo_factory/info.txt delete mode 100644 src/lib/algo_factory/prov_weight.cpp (limited to 'src/lib/algo_factory') diff --git a/src/lib/algo_factory/algo_cache.h b/src/lib/algo_factory/algo_cache.h deleted file mode 100644 index 66c62da67..000000000 --- a/src/lib/algo_factory/algo_cache.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -* An algorithm cache (used by Algorithm_Factory) -* (C) 2008-2009,2011 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_ALGORITHM_CACHE_TEMPLATE_H__ -#define BOTAN_ALGORITHM_CACHE_TEMPLATE_H__ - -#include -#include -#include -#include -#include -#include - -namespace Botan { - -/** -* @param prov_name a provider name -* @return weight for this provider -*/ -size_t static_provider_weight(const std::string& prov_name); - -/** -* Algorithm_Cache (used by Algorithm_Factory) -*/ -template -class Algorithm_Cache - { - public: - /** - * @param algo_spec names the requested algorithm - * @param pref_provider suggests a preferred provider - * @return prototype object, or NULL - */ - const T* get(const std::string& algo_spec, - const std::string& pref_provider); - - /** - * Add a new algorithm implementation to the cache - * @param algo the algorithm prototype object - * @param requested_name how this name will be requested - * @param provider_name is the name of the provider of this prototype - */ - void add(T* algo, - const std::string& requested_name, - const std::string& provider_name); - - /** - * Set the preferred provider - * @param algo_spec names the algorithm - * @param provider names the preferred provider - */ - void set_preferred_provider(const std::string& algo_spec, - const std::string& provider); - - /** - * Return the list of providers of this algorithm - * @param algo_name names the algorithm - * @return list of providers of this algorithm - */ - std::vector providers_of(const std::string& algo_name); - - /** - * Clear the cache - */ - void clear_cache(); - - ~Algorithm_Cache() { clear_cache(); } - private: - typename std::map >::const_iterator - find_algorithm(const std::string& algo_spec); - - std::mutex mutex; - std::map aliases; - std::map pref_providers; - std::map > algorithms; - }; - -/* -* Look for an algorithm implementation in the cache, also checking aliases -* Assumes object lock is held -*/ -template -typename std::map >::const_iterator -Algorithm_Cache::find_algorithm(const std::string& algo_spec) - { - auto algo = algorithms.find(algo_spec); - - // Not found? Check if a known alias - if(algo == algorithms.end()) - { - auto alias = aliases.find(algo_spec); - - if(alias != aliases.end()) - algo = algorithms.find(alias->second); - } - - return algo; - } - -/* -* Look for an algorithm implementation by a particular provider -*/ -template -const T* Algorithm_Cache::get(const std::string& algo_spec, - const std::string& requested_provider) - { - std::lock_guard lock(mutex); - - auto algo = find_algorithm(algo_spec); - if(algo == algorithms.end()) // algo not found at all (no providers) - return nullptr; - - // If a provider is requested specifically, return it or fail entirely - if(requested_provider != "") - { - auto prov = algo->second.find(requested_provider); - if(prov != algo->second.end()) - return prov->second; - return nullptr; - } - - const T* prototype = nullptr; - std::string prototype_provider; - size_t prototype_prov_weight = 0; - - const std::string pref_provider = search_map(pref_providers, algo_spec); - - for(auto i = algo->second.begin(); i != algo->second.end(); ++i) - { - // preferred prov exists, return immediately - if(i->first == pref_provider) - return i->second; - - const size_t prov_weight = static_provider_weight(i->first); - - if(prototype == nullptr || prov_weight > prototype_prov_weight) - { - prototype = i->second; - prototype_provider = i->first; - prototype_prov_weight = prov_weight; - } - } - - return prototype; - } - -/* -* Add an implementation to the cache -*/ -template -void Algorithm_Cache::add(T* algo, - const std::string& requested_name, - const std::string& provider) - { - if(!algo) - return; - - std::lock_guard lock(mutex); - - if(algo->name() != requested_name && - aliases.find(requested_name) == aliases.end()) - { - aliases[requested_name] = algo->name(); - } - - if(!algorithms[algo->name()][provider]) - algorithms[algo->name()][provider] = algo; - else - delete algo; - } - -/* -* Find the providers of this algo (if any) -*/ -template std::vector -Algorithm_Cache::providers_of(const std::string& algo_name) - { - std::lock_guard lock(mutex); - - std::vector providers; - - auto algo = find_algorithm(algo_name); - if(algo != algorithms.end()) - { - auto provider = algo->second.begin(); - - while(provider != algo->second.end()) - { - providers.push_back(provider->first); - ++provider; - } - } - - return providers; - } - -/* -* Set the preferred provider for an algorithm -*/ -template -void Algorithm_Cache::set_preferred_provider(const std::string& algo_spec, - const std::string& provider) - { - std::lock_guard lock(mutex); - - pref_providers[algo_spec] = provider; - } - -/* -* Clear out the cache -*/ -template -void Algorithm_Cache::clear_cache() - { - auto algo = algorithms.begin(); - - while(algo != algorithms.end()) - { - auto provider = algo->second.begin(); - - while(provider != algo->second.end()) - { - delete provider->second; - ++provider; - } - - ++algo; - } - - algorithms.clear(); - } - -} - -#endif diff --git a/src/lib/algo_factory/algo_factory.cpp b/src/lib/algo_factory/algo_factory.cpp deleted file mode 100644 index 9c805f67a..000000000 --- a/src/lib/algo_factory/algo_factory.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* -* Algorithm Factory -* (C) 2008-2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -namespace Botan { - -namespace { - -/* -* Template functions for the factory prototype/search algorithm -*/ -template -T* engine_get_algo(Engine*, - const SCAN_Name&, - Algorithm_Factory&) - { return nullptr; } - -template<> -BlockCipher* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_block_cipher(request, af); } - -template<> -StreamCipher* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_stream_cipher(request, af); } - -template<> -HashFunction* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_hash(request, af); } - -template<> -MessageAuthenticationCode* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_mac(request, af); } - -template<> -PBKDF* engine_get_algo(Engine* engine, - const SCAN_Name& request, - Algorithm_Factory& af) - { return engine->find_pbkdf(request, af); } - -template -const T* factory_prototype(const std::string& algo_spec, - const std::string& provider, - const std::vector& engines, - Algorithm_Factory& af, - Algorithm_Cache& cache) - { - if(const T* cache_hit = cache.get(algo_spec, provider)) - return cache_hit; - - SCAN_Name scan_name(algo_spec); - - if(scan_name.cipher_mode() != "") - return nullptr; - - for(size_t i = 0; i != engines.size(); ++i) - { - if(provider == "" || engines[i]->provider_name() == provider) - { - if(T* impl = engine_get_algo(engines[i], scan_name, af)) - cache.add(impl, algo_spec, engines[i]->provider_name()); - } - } - - return cache.get(algo_spec, provider); - } - -} - -/* -* Setup caches -*/ -Algorithm_Factory::Algorithm_Factory() - { - block_cipher_cache.reset(new Algorithm_Cache()); - stream_cipher_cache.reset(new Algorithm_Cache()); - hash_cache.reset(new Algorithm_Cache()); - mac_cache.reset(new Algorithm_Cache()); - pbkdf_cache.reset(new Algorithm_Cache()); - } - -/* -* Delete all engines -*/ -Algorithm_Factory::~Algorithm_Factory() - { - for(auto i = engines.begin(); i != engines.end(); ++i) - delete *i; - } - -void Algorithm_Factory::clear_caches() - { - block_cipher_cache->clear_cache(); - stream_cipher_cache->clear_cache(); - hash_cache->clear_cache(); - mac_cache->clear_cache(); - pbkdf_cache->clear_cache(); - } - -void Algorithm_Factory::add_engine(Engine* engine) - { - clear_caches(); - engines.push_back(engine); - } - -/* -* Set the preferred provider for an algorithm -*/ -void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec, - const std::string& provider) - { - if(prototype_block_cipher(algo_spec)) - block_cipher_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_stream_cipher(algo_spec)) - stream_cipher_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_hash_function(algo_spec)) - hash_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_mac(algo_spec)) - mac_cache->set_preferred_provider(algo_spec, provider); - else if(prototype_pbkdf(algo_spec)) - pbkdf_cache->set_preferred_provider(algo_spec, provider); - } - -/* -* Return the possible providers of a request -* Note: assumes you don't have different types by the same name -*/ -std::vector -Algorithm_Factory::providers_of(const std::string& algo_spec) - { - /* The checks with if(prototype_X(algo_spec)) have the effect of - forcing a full search, since otherwise there might not be any - providers at all in the cache. - */ - - if(prototype_block_cipher(algo_spec)) - return block_cipher_cache->providers_of(algo_spec); - else if(prototype_stream_cipher(algo_spec)) - return stream_cipher_cache->providers_of(algo_spec); - else if(prototype_hash_function(algo_spec)) - return hash_cache->providers_of(algo_spec); - else if(prototype_mac(algo_spec)) - return mac_cache->providers_of(algo_spec); - else if(prototype_pbkdf(algo_spec)) - return pbkdf_cache->providers_of(algo_spec); - else - return std::vector(); - } - -/* -* Return the prototypical block cipher corresponding to this request -*/ -const BlockCipher* -Algorithm_Factory::prototype_block_cipher(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, *block_cipher_cache); - } - -/* -* Return the prototypical stream cipher corresponding to this request -*/ -const StreamCipher* -Algorithm_Factory::prototype_stream_cipher(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, *stream_cipher_cache); - } - -/* -* Return the prototypical object corresponding to this request (if found) -*/ -const HashFunction* -Algorithm_Factory::prototype_hash_function(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, engines, - *this, *hash_cache); - } - -/* -* Return the prototypical object corresponding to this request -*/ -const MessageAuthenticationCode* -Algorithm_Factory::prototype_mac(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, - engines, - *this, *mac_cache); - } - -/* -* Return the prototypical object corresponding to this request -*/ -const PBKDF* -Algorithm_Factory::prototype_pbkdf(const std::string& algo_spec, - const std::string& provider) - { - return factory_prototype(algo_spec, provider, - engines, - *this, *pbkdf_cache); - } - -/* -* Return a new block cipher corresponding to this request -*/ -BlockCipher* -Algorithm_Factory::make_block_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(const BlockCipher* proto = prototype_block_cipher(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new stream cipher corresponding to this request -*/ -StreamCipher* -Algorithm_Factory::make_stream_cipher(const std::string& algo_spec, - const std::string& provider) - { - if(const StreamCipher* proto = prototype_stream_cipher(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -HashFunction* -Algorithm_Factory::make_hash_function(const std::string& algo_spec, - const std::string& provider) - { - if(const HashFunction* proto = prototype_hash_function(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -MessageAuthenticationCode* -Algorithm_Factory::make_mac(const std::string& algo_spec, - const std::string& provider) - { - if(const MessageAuthenticationCode* proto = prototype_mac(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -/* -* Return a new object corresponding to this request -*/ -PBKDF* -Algorithm_Factory::make_pbkdf(const std::string& algo_spec, - const std::string& provider) - { - if(const PBKDF* proto = prototype_pbkdf(algo_spec, provider)) - return proto->clone(); - throw Algorithm_Not_Found(algo_spec); - } - -} diff --git a/src/lib/algo_factory/algo_factory.h b/src/lib/algo_factory/algo_factory.h deleted file mode 100644 index 6d4084f53..000000000 --- a/src/lib/algo_factory/algo_factory.h +++ /dev/null @@ -1,165 +0,0 @@ -/* -* Algorithm Factory -* (C) 2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_ALGORITHM_FACTORY_H__ -#define BOTAN_ALGORITHM_FACTORY_H__ - -#include -#include -#include - -namespace Botan { - -/** -* Forward declarations (don't need full definitions here) -*/ -class BlockCipher; -class StreamCipher; -class HashFunction; -class MessageAuthenticationCode; -class PBKDF; - -template class Algorithm_Cache; - -class Engine; - -/** -* Algorithm Factory -*/ -class BOTAN_DLL Algorithm_Factory - { - public: - /** - * Constructor - */ - Algorithm_Factory(); - - /** - * Destructor - */ - ~Algorithm_Factory(); - - /** - * @param engine to add (Algorithm_Factory takes ownership) - */ - void add_engine(Engine* engine); - - /** - * Clear out any cached objects - */ - void clear_caches(); - - /** - * @param algo_spec the algorithm we are querying - * @returns list of providers of this algorithm - */ - std::vector providers_of(const std::string& algo_spec); - - /** - * @param algo_spec the algorithm we are setting a provider for - * @param provider the provider we would like to use - */ - void set_preferred_provider(const std::string& algo_spec, - 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 - */ - const BlockCipher* - prototype_block_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - BlockCipher* make_block_cipher(const std::string& algo_spec, - 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 - */ - const StreamCipher* - prototype_stream_cipher(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - StreamCipher* make_stream_cipher(const std::string& algo_spec, - 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 - */ - const HashFunction* - prototype_hash_function(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - HashFunction* make_hash_function(const std::string& algo_spec, - 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 - */ - const MessageAuthenticationCode* - prototype_mac(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - MessageAuthenticationCode* make_mac(const std::string& algo_spec, - 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 - */ - const PBKDF* prototype_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - /** - * @param algo_spec the algorithm we want - * @param provider the provider we would like to use - * @returns pointer to freshly created instance of the request algorithm - */ - PBKDF* make_pbkdf(const std::string& algo_spec, - const std::string& provider = ""); - - private: - std::vector engines; - - std::unique_ptr> block_cipher_cache; - std::unique_ptr> stream_cipher_cache; - std::unique_ptr> hash_cache; - std::unique_ptr> mac_cache; - std::unique_ptr> pbkdf_cache; - }; - -} - -#endif diff --git a/src/lib/algo_factory/info.txt b/src/lib/algo_factory/info.txt deleted file mode 100644 index 837ced1d0..000000000 --- a/src/lib/algo_factory/info.txt +++ /dev/null @@ -1,24 +0,0 @@ -load_on auto - -define ALGORITHM_FACTORY 20131128 - - -algo_factory.h - - - -algo_cache.h - - - -algo_factory.cpp -prov_weight.cpp - - - -block -engine -hash -mac -stream - diff --git a/src/lib/algo_factory/prov_weight.cpp b/src/lib/algo_factory/prov_weight.cpp deleted file mode 100644 index 3c793a299..000000000 --- a/src/lib/algo_factory/prov_weight.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* -* Default provider weights for Algorithm_Cache -* (C) 2008 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include - -namespace Botan { - -/** -* Return a static provider weighing -*/ -size_t static_provider_weight(const std::string& prov_name) - { - /* - * Prefer asm over C++, but prefer anything over OpenSSL or GNU MP; to use - * them, set the provider explicitly for the algorithms you want - */ - - if(prov_name == "aes_isa") return 9; - if(prov_name == "simd") return 8; - if(prov_name == "asm") return 7; - - if(prov_name == "core") return 5; - - if(prov_name == "openssl") return 2; - if(prov_name == "gmp") return 1; - - return 0; // other/unknown - } - -} -- cgit v1.2.3