diff options
author | lloyd <[email protected]> | 2008-11-11 19:08:06 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-11-11 19:08:06 +0000 |
commit | 25d7b7aa9e9896df45f12fa59db4c44411bc21f0 (patch) | |
tree | c7ef12dbca65449bde6d4f5183dc2f400914e426 /src/algo_factory | |
parent | 1954e73dbf4e4984d33a45d6ce05ee5aecb84714 (diff) |
Use cache in Algorithm_Factory for ciphers
Diffstat (limited to 'src/algo_factory')
-rw-r--r-- | src/algo_factory/algo_cache.h | 64 | ||||
-rw-r--r-- | src/algo_factory/algo_factory.cpp | 173 | ||||
-rw-r--r-- | src/algo_factory/algo_factory.h | 16 |
3 files changed, 124 insertions, 129 deletions
diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index c6d2ebdac..dafa59c3e 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -22,43 +22,60 @@ class Algorithm_Cache const std::string& requested_name, const std::string& provider); + std::vector<std::string> providers_of(const std::string& algo_name); + Algorithm_Cache(Mutex* m) : mutex(m) {} ~Algorithm_Cache(); private: + typedef typename std::map<std::string, std::map<std::string, T*> >::iterator algorithms_iterator; + typedef typename std::map<std::string, T*>::iterator provider_iterator; + + algorithms_iterator find_algorithm(const std::string& algo_spec); + Mutex* mutex; std::map<std::string, std::string> aliases; std::map<std::string, std::map<std::string, T*> > algorithms; - typedef typename std::map<std::string, std::map<std::string, T*> >::iterator algorithms_iterator; - typedef typename std::map<std::string, T*>::iterator provider_iterator; }; /** -* Look for an algorithm implementation in the cache +* Look for an algorithm implementation in the cache, also checking aliases */ template<typename T> -const T* Algorithm_Cache<T>::get(const SCAN_Name& request) +typename Algorithm_Cache<T>::algorithms_iterator +Algorithm_Cache<T>::find_algorithm(const std::string& algo_spec) { - Mutex_Holder lock(mutex); - - algorithms_iterator algo = algorithms.find(request.as_string()); + // Assumes mutex is held + algorithms_iterator algo = algorithms.find(algo_spec); // Not found? Check if a known alias if(algo == algorithms.end()) { std::map<std::string, std::string>::const_iterator alias = - aliases.find(request.as_string()); + aliases.find(algo_spec); if(alias != aliases.end()) algo = algorithms.find(alias->second); } - if(algo == algorithms.end()) + return algo; + } + +/** +* Look for an algorithm implementation in the cache +*/ +template<typename T> +const T* Algorithm_Cache<T>::get(const SCAN_Name& request) + { + Mutex_Holder lock(mutex); + + algorithms_iterator algo = find_algorithm(request.as_string()); + if(algo == algorithms.end()) // not found at all return 0; const std::string requested_provider = request.provider(); - if(requested_provider != "") + if(requested_provider != "") // If a specific request, allow that provider or core { provider_iterator provider = algo->second.find(requested_provider); @@ -67,6 +84,7 @@ const T* Algorithm_Cache<T>::get(const SCAN_Name& request) } else // no specific provider requested: pick one { + printf("No specific provider requested for %s\n", request.as_string().c_str()); provider_iterator provider = algo->second.begin(); while(provider != algo->second.end()) @@ -102,6 +120,32 @@ void Algorithm_Cache<T>::add(T* algo, } /** +* Find the providers of this algo (if any) +*/ +template<typename T> std::vector<std::string> +Algorithm_Cache<T>::providers_of(const std::string& algo_name) + { + Mutex_Holder lock(mutex); + + std::vector<std::string> providers; + + algorithms_iterator algo = find_algorithm(algo_name); + + if(algo != algorithms.end()) + { + provider_iterator provider = algo->second.begin(); + + while(provider != algo->second.end()) + { + providers.push_back(provider->first); + ++provider; + } + } + + return providers; + } + +/** * Algorithm_Cache<T> Destructor */ template<typename T> diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 4f137d636..e2debf7c9 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -19,7 +19,10 @@ namespace Botan { Algorithm_Factory::Algorithm_Factory(Mutex_Factory& mf) : mutex_factory(mf), - hash_cache(mf.make()) + block_cipher_cache(mf.make()), + stream_cipher_cache(mf.make()), + hash_cache(mf.make()), + mac_cache(mf.make()) { } @@ -56,125 +59,95 @@ Engine* Algorithm_Factory::get_engine_n(u32bit n) const * Return the possible providers of a request */ std::vector<std::string> -Algorithm_Factory::providers_of(const SCAN_Name& request) +Algorithm_Factory::providers_of(const std::string& algo_name) { - std::vector<std::string> providers; - for(u32bit i = 0; i != engines.size(); ++i) - { - std::string provider = engines[i]->provider_name(); - if(request.provider_allowed(provider)) - { - if(engines[i]->prototype_block_cipher(request, *this) || - engines[i]->prototype_stream_cipher(request, *this) || - engines[i]->prototype_hash_function(request, *this) || - engines[i]->prototype_mac(request, *this)) - { - providers.push_back(provider); - } - } - } + if(prototype_block_cipher(algo_name)) + return block_cipher_cache.providers_of(algo_name); + + if(prototype_stream_cipher(algo_name)) + return stream_cipher_cache.providers_of(algo_name); + + if(prototype_hash_function(algo_name)) + return hash_cache.providers_of(algo_name); - return providers; + if(prototype_mac(algo_name)) + return mac_cache.providers_of(algo_name); + + return std::vector<std::string>(); } /** -* Return the prototypical object cooresponding to this request +* Return the prototypical block cipher cooresponding to this request */ const BlockCipher* Algorithm_Factory::prototype_block_cipher(const SCAN_Name& request) { + if(const BlockCipher* cache_hit = block_cipher_cache.get(request)) + return cache_hit; + for(u32bit i = 0; i != engines.size(); ++i) { - if(request.provider_allowed(engines[i]->provider_name())) - { - const BlockCipher* algo = - engines[i]->prototype_block_cipher(request, *this); - - if(algo) - return algo; - } + if(BlockCipher* impl = engines[i]->find_block_cipher(request, *this)) + block_cipher_cache.add(impl, request.as_string(), engines[i]->provider_name()); } - return 0; + return block_cipher_cache.get(request); } /** -* Return a new object cooresponding to this request +* Return a new block cipher cooresponding to this request */ BlockCipher* Algorithm_Factory::make_block_cipher(const SCAN_Name& request) { - const BlockCipher* prototype = prototype_block_cipher(request); - if(prototype) + if(const BlockCipher* prototype = prototype_block_cipher(request)) return prototype->clone(); - throw Algorithm_Not_Found(request.as_string()); } /** -* Add a new object +* Add a new block cipher */ -void Algorithm_Factory::add_block_cipher(BlockCipher* hash) +void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher, + const std::string& provider) { - for(u32bit i = 0; i != engines.size(); ++i) - { - if(engines[i]->can_add_algorithms()) - { - engines[i]->add_algorithm(hash); - return; - } - } - - throw Exception("Algorithm_Factory::add_block_cipher: No engine found"); + block_cipher_cache.add(block_cipher, block_cipher->name(), provider); } /** -* Return the prototypical object cooresponding to this request +* Return the prototypical stream cipher cooresponding to this request */ const StreamCipher* Algorithm_Factory::prototype_stream_cipher(const SCAN_Name& request) { + if(const StreamCipher* cache_hit = stream_cipher_cache.get(request)) + return cache_hit; + for(u32bit i = 0; i != engines.size(); ++i) { - if(request.provider_allowed(engines[i]->provider_name())) - { - const StreamCipher* algo = - engines[i]->prototype_stream_cipher(request, *this); - - if(algo) - return algo; - } + if(StreamCipher* impl = engines[i]->find_stream_cipher(request, *this)) + stream_cipher_cache.add(impl, request.as_string(), engines[i]->provider_name()); } - return 0; + return stream_cipher_cache.get(request); } /** -* Return a new object cooresponding to this request +* Return a new stream cipher cooresponding to this request */ StreamCipher* Algorithm_Factory::make_stream_cipher(const SCAN_Name& request) { - const StreamCipher* prototype = prototype_stream_cipher(request); - if(prototype) + if(const StreamCipher* prototype = prototype_stream_cipher(request)) return prototype->clone(); - throw Algorithm_Not_Found(request.as_string()); } /** -* Add a new object +* Add a new stream cipher */ -void Algorithm_Factory::add_stream_cipher(StreamCipher* hash) +void Algorithm_Factory::add_stream_cipher(StreamCipher* stream_cipher, + const std::string& provider) { - for(u32bit i = 0; i != engines.size(); ++i) - { - if(engines[i]->can_add_algorithms()) - { - engines[i]->add_algorithm(hash); - return; - } - } - - throw Exception("Algorithm_Factory::add_stream_cipher: No engine found"); + stream_cipher_cache.add(stream_cipher, stream_cipher->name(), provider); } /** @@ -183,16 +156,13 @@ void Algorithm_Factory::add_stream_cipher(StreamCipher* hash) const HashFunction* Algorithm_Factory::prototype_hash_function(const SCAN_Name& request) { - const HashFunction* cache_hit = hash_cache.get(request); - if(cache_hit) + if(const HashFunction* cache_hit = hash_cache.get(request)) return cache_hit; for(u32bit i = 0; i != engines.size(); ++i) { if(HashFunction* impl = engines[i]->find_hash(request, *this)) - { hash_cache.add(impl, request.as_string(), engines[i]->provider_name()); - } } return hash_cache.get(request); @@ -203,28 +173,18 @@ Algorithm_Factory::prototype_hash_function(const SCAN_Name& request) */ HashFunction* Algorithm_Factory::make_hash_function(const SCAN_Name& request) { - const HashFunction* prototype = prototype_hash_function(request); - if(prototype) + if(const HashFunction* prototype = prototype_hash_function(request)) return prototype->clone(); - throw Algorithm_Not_Found(request.as_string()); } /** -* Add a new object +* Add a new hash */ -void Algorithm_Factory::add_hash_function(HashFunction* hash) +void Algorithm_Factory::add_hash_function(HashFunction* hash, + const std::string& provider) { - for(u32bit i = 0; i != engines.size(); ++i) - { - if(engines[i]->can_add_algorithms()) - { - engines[i]->add_algorithm(hash); - return; - } - } - - throw Exception("Algorithm_Factory::add_hash_function: No engine found"); + hash_cache.add(hash, hash->name(), provider); } /** @@ -233,19 +193,16 @@ void Algorithm_Factory::add_hash_function(HashFunction* hash) const MessageAuthenticationCode* Algorithm_Factory::prototype_mac(const SCAN_Name& request) { + if(const MessageAuthenticationCode* cache_hit = mac_cache.get(request)) + return cache_hit; + for(u32bit i = 0; i != engines.size(); ++i) { - if(request.provider_allowed(engines[i]->provider_name())) - { - const MessageAuthenticationCode* algo = - engines[i]->prototype_mac(request, *this); - - if(algo) - return algo; - } + if(MessageAuthenticationCode* impl = engines[i]->find_mac(request, *this)) + mac_cache.add(impl, request.as_string(), engines[i]->provider_name()); } - return 0; + return mac_cache.get(request); } /** @@ -254,28 +211,18 @@ Algorithm_Factory::prototype_mac(const SCAN_Name& request) MessageAuthenticationCode* Algorithm_Factory::make_mac(const SCAN_Name& request) { - const MessageAuthenticationCode* prototype = prototype_mac(request); - if(prototype) + if(const MessageAuthenticationCode* prototype = prototype_mac(request)) return prototype->clone(); - throw Algorithm_Not_Found(request.as_string()); } /** -* Add a new object +* Add a new mac */ -void Algorithm_Factory::add_mac(MessageAuthenticationCode* hash) +void Algorithm_Factory::add_mac(MessageAuthenticationCode* mac, + const std::string& provider) { - for(u32bit i = 0; i != engines.size(); ++i) - { - if(engines[i]->can_add_algorithms()) - { - engines[i]->add_algorithm(hash); - return; - } - } - - throw Exception("Algorithm_Factory::add_mac: No engine found"); + mac_cache.add(mac, mac->name(), provider); } } diff --git a/src/algo_factory/algo_factory.h b/src/algo_factory/algo_factory.h index 2bbfde7d1..64b2128ec 100644 --- a/src/algo_factory/algo_factory.h +++ b/src/algo_factory/algo_factory.h @@ -45,35 +45,39 @@ class BOTAN_DLL Algorithm_Factory }; friend class Engine_Iterator; - std::vector<std::string> providers_of(const SCAN_Name& request); + std::vector<std::string> providers_of(const std::string& algo_spec); // Block cipher operations const BlockCipher* prototype_block_cipher(const SCAN_Name& request); BlockCipher* make_block_cipher(const SCAN_Name& request); - void add_block_cipher(BlockCipher* hash); + void add_block_cipher(BlockCipher* hash, const std::string& provider); // Stream cipher operations const StreamCipher* prototype_stream_cipher(const SCAN_Name& request); StreamCipher* make_stream_cipher(const SCAN_Name& request); - void add_stream_cipher(StreamCipher* hash); + void add_stream_cipher(StreamCipher* hash, const std::string& provider); // Hash function operations const HashFunction* prototype_hash_function(const SCAN_Name& request); HashFunction* make_hash_function(const SCAN_Name& request); - void add_hash_function(HashFunction* hash); + void add_hash_function(HashFunction* hash, const std::string& provider); // MAC operations const MessageAuthenticationCode* prototype_mac(const SCAN_Name& request); MessageAuthenticationCode* make_mac(const SCAN_Name& request); - void add_mac(MessageAuthenticationCode* mac); - + void add_mac(MessageAuthenticationCode* mac, + const std::string& provider); private: Mutex_Factory& mutex_factory; class Engine* get_engine_n(u32bit) const; std::vector<class Engine*> engines; + + Algorithm_Cache<BlockCipher> block_cipher_cache; + Algorithm_Cache<StreamCipher> stream_cipher_cache; Algorithm_Cache<HashFunction> hash_cache; + Algorithm_Cache<MessageAuthenticationCode> mac_cache; }; } |