aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-03-05 04:28:24 +0000
committerlloyd <[email protected]>2015-03-05 04:28:24 +0000
commit0c28ab5f95b444649fdaa417dd680ab28a6e7c85 (patch)
treef3da82aed7603f46feaa5444c2704b8515a39912 /src/lib
parent2591a2cd863696b91128ff4a8461bb96d497e7b4 (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.h83
-rw-r--r--src/lib/hash/tiger/tiger.cpp2
-rw-r--r--src/lib/mac/siphash/siphash.cpp2
-rw-r--r--src/lib/vendor/openssl/openssl_rc4.cpp8
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);
}