diff options
author | lloyd <[email protected]> | 2015-03-05 04:28:24 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2015-03-05 04:28:24 +0000 |
commit | 0c28ab5f95b444649fdaa417dd680ab28a6e7c85 (patch) | |
tree | f3da82aed7603f46feaa5444c2704b8515a39912 /src/lib | |
parent | 2591a2cd863696b91128ff4a8461bb96d497e7b4 (diff) |
In Algo_Registry if a maker func fails, try the next most preferred one
instead of bailing out immediately.
Rename the 'builtin' provider to 'base' since really they are all built in.
Fix MARK-4 when OpenSSL was enabled - it did not respect the skip param.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/base/algo_registry.h | 83 | ||||
-rw-r--r-- | src/lib/hash/tiger/tiger.cpp | 2 | ||||
-rw-r--r-- | src/lib/mac/siphash/siphash.cpp | 2 | ||||
-rw-r--r-- | src/lib/vendor/openssl/openssl_rc4.cpp | 8 |
4 files changed, 60 insertions, 35 deletions
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index 63f376cc9..0ae91c218 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -47,18 +47,32 @@ class Algo_Registry return std::vector<std::string>(); } + void set_provider_preference(const Spec& spec, const std::string& provider, byte pref) + { + std::unique_lock<std::mutex> lock(m_mutex); + auto i = m_algo_info.find(spec.algo_name()); + if(i != m_algo_info.end()) + i->second.set_pref(provider, pref); + } + T* make(const Spec& spec, const std::string& provider = "") { - maker_fn maker = find_maker(spec, provider); + const std::vector<maker_fn> makers = get_makers(spec, provider); try { - return maker(spec); + for(auto&& maker : makers) + { + if(T* t = maker(spec)) + return t; + } } catch(std::exception& e) { throw std::runtime_error("Creating '" + spec.as_string() + "' failed: " + e.what()); } + + return nullptr; } class Add @@ -79,65 +93,67 @@ class Algo_Registry private: Algo_Registry() {} - maker_fn find_maker(const Spec& spec, const std::string& provider) + std::vector<maker_fn> get_makers(const Spec& spec, const std::string& provider) { std::unique_lock<std::mutex> lock(m_mutex); - return m_algo_info[spec.algo_name()].get_maker(provider); + return m_algo_info[spec.algo_name()].get_makers(provider); } struct Algo_Info { public: - void add_provider(const std::string& provider, maker_fn fn, byte pref = 128) + void add_provider(const std::string& provider, maker_fn fn, byte pref) { if(m_maker_fns.count(provider) > 0) throw std::runtime_error("Duplicated registration of '" + provider + "'"); - m_maker_fns[provider] = std::make_pair(pref, fn); + m_maker_fns[provider] = fn; + m_prefs.insert(std::make_pair(pref, provider)); } std::vector<std::string> providers() const { std::vector<std::string> v; - for(auto&& k : m_maker_fns) - v.push_back(k.first); + for(auto&& k : m_prefs) + v.push_back(k.second); return v; } - void set_pref(const std::string& provider, byte val) + void set_pref(const std::string& provider, byte pref) { - m_maker_fns[provider].first = val; + auto i = m_prefs.begin(); + while(i != m_prefs.end()) + { + if(i->second == provider) + i = m_prefs.erase(i); + else + ++i; + } + m_prefs.insert(std::make_pair(pref, provider)); } - maker_fn get_maker(const std::string& req_provider) + std::vector<maker_fn> get_makers(const std::string& req_provider) { - maker_fn null_result = [](const Spec&) { return nullptr; }; + std::vector<maker_fn> r; if(req_provider != "") { // find one explicit provider requested by user or fail auto i = m_maker_fns.find(req_provider); if(i != m_maker_fns.end()) - return i->second.second; - return null_result; + r.push_back(i->second); } - - size_t pref = 255; - maker_fn result = null_result; - - for(auto&& i : m_maker_fns) + else { - if(i.second.first < pref) - { - pref = i.second.first; - result = i.second.second; - } + for(auto&& pref : m_prefs) + r.push_back(m_maker_fns[pref.second]); } - return result; + return r; } private: - std::unordered_map<std::string, std::pair<byte, maker_fn>> m_maker_fns; // provider -> (pref, creator fn) + std::multimap<byte, std::string> m_prefs; + std::unordered_map<std::string, maker_fn> m_maker_fns; }; std::mutex m_mutex; @@ -156,7 +172,12 @@ template<typename T> std::vector<std::string> providers_of(const typename T::Spe } template<typename T> T* -make_new_T(const typename Algo_Registry<T>::Spec&) { return new T; } +make_new_T(const typename Algo_Registry<T>::Spec& spec) + { + if(spec.arg_count() == 0) + return new T; + return nullptr; + } template<typename T, size_t DEF_VAL> T* make_new_T_1len(const typename Algo_Registry<T>::Spec& spec) @@ -198,15 +219,15 @@ make_new_T_1X(const typename Algo_Registry<T>::Spec& spec) namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, maker, provider, pref); } #define BOTAN_REGISTER_NAMED_T(T, name, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, name, maker, "builtin", 128) + BOTAN_REGISTER_TYPE(T, type, name, maker, "base", 128) #define BOTAN_REGISTER_T(T, type, maker) \ - BOTAN_REGISTER_TYPE(T, type, #type, maker, "builtin", 128) + BOTAN_REGISTER_TYPE(T, type, #type, maker, "base", 128) #define BOTAN_REGISTER_T_NOARGS(T, type) \ - BOTAN_REGISTER_TYPE(T, type, #type, make_new_T<type>, "builtin", 128) + BOTAN_REGISTER_TYPE(T, type, #type, make_new_T<type>, "base", 128) #define BOTAN_REGISTER_T_1LEN(T, type, def) \ - BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len<type,def>), "builtin", 128) + BOTAN_REGISTER_TYPE(T, type, #type, (make_new_T_1len<type,def>), "base", 128) #define BOTAN_REGISTER_NAMED_T_NOARGS(T, type, name, provider) \ BOTAN_REGISTER_TYPE(T, type, name, make_new_T<type>, provider, 128) diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp index d1deb75c9..86da18d24 100644 --- a/src/lib/hash/tiger/tiger.cpp +++ b/src/lib/hash/tiger/tiger.cpp @@ -12,7 +12,7 @@ namespace Botan { -BOTAN_REGISTER_NAMED_T_2LEN(HashFunction, Tiger, "Tiger", "builtin", 24, 3); +BOTAN_REGISTER_NAMED_T_2LEN(HashFunction, Tiger, "Tiger", "base", 24, 3); namespace { diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp index 3fafb35a9..f8ed28a84 100644 --- a/src/lib/mac/siphash/siphash.cpp +++ b/src/lib/mac/siphash/siphash.cpp @@ -10,7 +10,7 @@ namespace Botan { -BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "builtin", 2, 4); +BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "base", 2, 4); namespace { diff --git a/src/lib/vendor/openssl/openssl_rc4.cpp b/src/lib/vendor/openssl/openssl_rc4.cpp index 9a11ca949..494b30974 100644 --- a/src/lib/vendor/openssl/openssl_rc4.cpp +++ b/src/lib/vendor/openssl/openssl_rc4.cpp @@ -26,7 +26,7 @@ class OpenSSL_RC4 : public StreamCipher return Key_Length_Specification(1, 32); } - OpenSSL_RC4() { clear(); } + OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); } ~OpenSSL_RC4() { clear(); } private: void cipher(const byte in[], byte out[], size_t length) @@ -37,13 +37,17 @@ class OpenSSL_RC4 : public StreamCipher void key_schedule(const byte key[], size_t length) { ::RC4_set_key(&m_rc4, length, key); + byte d = 0; + for(size_t i = 0; i != m_skip; ++i) + ::RC4(&m_rc4, 1, &d, &d); } + size_t m_skip; RC4_KEY m_rc4; }; } -BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", make_new_T<OpenSSL_RC4>, "openssl", 64); +BOTAN_REGISTER_TYPE(StreamCipher, OpenSSL_RC4, "RC4", (make_new_T_1len<OpenSSL_RC4,0>), "openssl", 64); } |