aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/hash
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-10-11 13:00:57 -0400
committerJack Lloyd <[email protected]>2016-10-21 16:53:16 -0400
commit558808900bffc3c48da5e6d79ba602e88e619154 (patch)
treefd76ee2d009c2b707d888683cbd767351c4ff6b3 /src/lib/hash
parent6aa855bba613c7b6fedfbe71d15930964acb1633 (diff)
Remove Algo_Registry
I repent my use of global constructors. I repent my use of global locks. Hopefully I will never touch this code again. :)
Diffstat (limited to 'src/lib/hash')
-rw-r--r--src/lib/hash/blake2/blake2b.cpp5
-rw-r--r--src/lib/hash/blake2/blake2b.h2
-rw-r--r--src/lib/hash/comb4p/comb4p.cpp13
-rw-r--r--src/lib/hash/comb4p/comb4p.h2
-rw-r--r--src/lib/hash/hash.cpp219
-rw-r--r--src/lib/hash/hash.h21
-rw-r--r--src/lib/hash/par_hash/par_hash.cpp28
-rw-r--r--src/lib/hash/par_hash/par_hash.h5
-rw-r--r--src/lib/hash/skein/skein_512.cpp5
-rw-r--r--src/lib/hash/skein/skein_512.h2
10 files changed, 181 insertions, 121 deletions
diff --git a/src/lib/hash/blake2/blake2b.cpp b/src/lib/hash/blake2/blake2b.cpp
index 10ccbf5c0..928f344d7 100644
--- a/src/lib/hash/blake2/blake2b.cpp
+++ b/src/lib/hash/blake2/blake2b.cpp
@@ -39,11 +39,6 @@ const u64bit blake2b_sigma[12][16] = {
};
}
-Blake2b* Blake2b::make(const Spec& spec)
- {
- return new Blake2b(spec.arg_as_integer(0, 512));
- }
-
Blake2b::Blake2b(size_t output_bits) :
m_output_bits(output_bits),
m_buffer(BLAKE2B_BLOCKBYTES),
diff --git a/src/lib/hash/blake2/blake2b.h b/src/lib/hash/blake2/blake2b.h
index 290db10f0..343f276b5 100644
--- a/src/lib/hash/blake2/blake2b.h
+++ b/src/lib/hash/blake2/blake2b.h
@@ -34,8 +34,6 @@ class BOTAN_DLL Blake2b final : public HashFunction
size_t hash_block_size() const override { return BLAKE2B_BLOCKBYTES; }
size_t output_length() const override { return m_output_bits / 8; }
- static Blake2b* make(const Spec& spec);
-
HashFunction* clone() const override;
std::string name() const override;
void clear() override;
diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp
index 015873473..4659ace77 100644
--- a/src/lib/hash/comb4p/comb4p.cpp
+++ b/src/lib/hash/comb4p/comb4p.cpp
@@ -33,19 +33,6 @@ void comb4p_round(secure_vector<byte>& out,
}
-Comb4P* Comb4P::make(const Spec& spec)
- {
- if(spec.arg_count() == 2)
- {
- std::unique_ptr<HashFunction> h1(HashFunction::create(spec.arg(0)));
- std::unique_ptr<HashFunction> h2(HashFunction::create(spec.arg(1)));
-
- if(h1 && h2)
- return new Comb4P(h1.release(), h2.release());
- }
- return nullptr;
- }
-
Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) :
m_hash1(h1), m_hash2(h2)
{
diff --git a/src/lib/hash/comb4p/comb4p.h b/src/lib/hash/comb4p/comb4p.h
index c05953ea5..cb78914e7 100644
--- a/src/lib/hash/comb4p/comb4p.h
+++ b/src/lib/hash/comb4p/comb4p.h
@@ -32,8 +32,6 @@ class BOTAN_DLL Comb4P final : public HashFunction
return m_hash1->output_length() + m_hash2->output_length();
}
- static Comb4P* make(const Spec& spec);
-
HashFunction* clone() const override
{
return new Comb4P(m_hash1->clone(), m_hash2->clone());
diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp
index 016f60df1..dc95099b8 100644
--- a/src/lib/hash/hash.cpp
+++ b/src/lib/hash/hash.cpp
@@ -6,8 +6,7 @@
*/
#include <botan/hash.h>
-#include <botan/cpuid.h>
-#include <botan/internal/algo_registry.h>
+#include <botan/scan_name.h>
#if defined(BOTAN_HAS_ADLER32)
#include <botan/adler32.h>
@@ -81,109 +80,213 @@
#include <botan/blake2b.h>
#endif
+#if defined(BOTAN_HAS_OPENSSL)
+ #include <botan/internal/openssl.h>
+#endif
+
namespace Botan {
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
const std::string& provider)
{
- return std::unique_ptr<HashFunction>(make_a<HashFunction>(Botan::HashFunction::Spec(algo_spec), provider));
- }
+ const SCAN_Name req(algo_spec);
-std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
- {
- return providers_of<HashFunction>(HashFunction::Spec(algo_spec));
- }
+#if defined(BOTAN_HAS_OPENSSL)
+ if(provider.empty() || provider == "openssl")
+ {
+ if(auto hash = make_openssl_hash(algo_spec))
+ return hash;
-HashFunction::HashFunction() {}
+ if(!provider.empty())
+ return nullptr;
+ }
+#endif
-HashFunction::~HashFunction() {}
+ if(provider.empty() == false && provider != "base")
+ return nullptr; // unknown provider
-#define BOTAN_REGISTER_HASH(name, maker) BOTAN_REGISTER_T(HashFunction, name, maker)
-#define BOTAN_REGISTER_HASH_NOARGS(name) BOTAN_REGISTER_T_NOARGS(HashFunction, name)
+#if defined(BOTAN_HAS_SHA1)
+ if(req.algo_name() == "SHA-160")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_160);
+ }
+#endif
-#define BOTAN_REGISTER_HASH_1LEN(name, def) BOTAN_REGISTER_T_1LEN(HashFunction, name, def)
+#if defined(BOTAN_HAS_SHA2_32)
+ if(req.algo_name() == "SHA-224")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_224);
+ }
-#define BOTAN_REGISTER_HASH_NAMED_NOARGS(type, name) \
- BOTAN_REGISTER_NAMED_T(HashFunction, name, type, make_new_T<type>)
-#define BOTAN_REGISTER_HASH_NAMED_1LEN(type, name, def) \
- BOTAN_REGISTER_NAMED_T(HashFunction, name, type, (make_new_T_1len<type,def>))
+ if(req.algo_name() == "SHA-256")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_256);
+ }
+#endif
-#define BOTAN_REGISTER_HASH_NOARGS_IF(cond, type, name, provider, pref) \
- BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, HashFunction, type, name, provider, pref)
+#if defined(BOTAN_HAS_SHA2_64)
+ if(req.algo_name() == "SHA-384")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_384);
+ }
-#if defined(BOTAN_HAS_ADLER32)
-BOTAN_REGISTER_HASH_NOARGS(Adler32);
-#endif
+ if(req.algo_name() == "SHA-512")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_512);
+ }
-#if defined(BOTAN_HAS_CRC24)
-BOTAN_REGISTER_HASH_NOARGS(CRC24);
+ if(req.algo_name() == "SHA-512-256")
+ {
+ return std::unique_ptr<HashFunction>(new SHA_512_256);
+ }
#endif
-#if defined(BOTAN_HAS_CRC32)
-BOTAN_REGISTER_HASH_NOARGS(CRC32);
+#if defined(BOTAN_HAS_RIPEMD_160)
+ if(req.algo_name() == "RIPEMD-160")
+ {
+ return std::unique_ptr<HashFunction>(new RIPEMD_160);
+ }
#endif
-#if defined(BOTAN_HAS_COMB4P)
-BOTAN_REGISTER_NAMED_T(HashFunction, "Comb4P", Comb4P, Comb4P::make);
+#if defined(BOTAN_HAS_TIGER)
+ if(req.algo_name() == "Tiger")
+ {
+ return std::unique_ptr<HashFunction>(
+ new Tiger(req.arg_as_integer(0, 24),
+ req.arg_as_integer(1, 3)));
+ }
#endif
-#if defined(BOTAN_HAS_PARALLEL_HASH)
-BOTAN_REGISTER_NAMED_T(HashFunction, "Parallel", Parallel, Parallel::make);
+#if defined(BOTAN_HAS_SKEIN_512)
+ if(req.algo_name() == "Skein-512")
+ {
+ return std::unique_ptr<HashFunction>(
+ new Skein_512(req.arg_as_integer(0, 512), req.arg(1, "")));
+ }
#endif
-#if defined(BOTAN_HAS_GOST_34_11)
-BOTAN_REGISTER_HASH_NAMED_NOARGS(GOST_34_11, "GOST-R-34.11-94");
+#if defined(BOTAN_HAS_BLAKE2B)
+ if(req.algo_name() == "Blake2b")
+ {
+ return std::unique_ptr<HashFunction>(
+ new Blake2b(req.arg_as_integer(0, 512)));
+ }
#endif
#if defined(BOTAN_HAS_KECCAK)
-BOTAN_REGISTER_HASH_NAMED_1LEN(Keccak_1600, "Keccak-1600", 512);
+ if(req.algo_name() == "Keccak-1600")
+ {
+ return std::unique_ptr<HashFunction>(
+ new Keccak_1600(req.arg_as_integer(0, 512)));
+ }
#endif
#if defined(BOTAN_HAS_SHA3)
-BOTAN_REGISTER_HASH_NAMED_1LEN(SHA_3, "SHA-3", 512);
+ if(req.algo_name() == "SHA-3")
+ {
+ return std::unique_ptr<HashFunction>(
+ new SHA_3(req.arg_as_integer(0, 512)));
+ }
#endif
-#if defined(BOTAN_HAS_MD4)
-BOTAN_REGISTER_HASH_NOARGS(MD4);
+#if defined(BOTAN_HAS_WHIRLPOOL)
+ if(req.algo_name() == "Whirlpool")
+ {
+ return std::unique_ptr<HashFunction>(new Whirlpool);
+ }
#endif
-#if defined(BOTAN_HAS_MD5)
-BOTAN_REGISTER_HASH_NOARGS(MD5);
-#endif
+#if defined(BOTAN_HAS_PARALLEL_HASH)
+ if(req.algo_name() == "Parallel")
+ {
+ std::vector<std::unique_ptr<HashFunction>> hashes;
-#if defined(BOTAN_HAS_RIPEMD_160)
-BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_160, "RIPEMD-160");
+ for(size_t i = 0; i != req.arg_count(); ++i)
+ {
+ auto h = HashFunction::create(req.arg(i));
+ if(!h)
+ {
+ return nullptr;
+ }
+ hashes.push_back(std::move(h));
+ }
+
+ return std::unique_ptr<HashFunction>(new Parallel(hashes));
+ }
#endif
-#if defined(BOTAN_HAS_SHA1)
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_160, "SHA-160");
+#if defined(BOTAN_HAS_COMB4P)
+ if(req.algo_name() == "Comb4p" && req.arg_count() == 2)
+ {
+ std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0)));
+ std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1)));
+
+ if(h1 && h2)
+ return std::unique_ptr<HashFunction>(new Comb4P(h1.release(), h2.release()));
+ }
#endif
-#if defined(BOTAN_HAS_SHA2_32)
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_224, "SHA-224");
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_256, "SHA-256");
+#if defined(BOTAN_HAS_MD5)
+ if(req.algo_name() == "MD5")
+ {
+ return std::unique_ptr<HashFunction>(new MD5);
+ }
#endif
-#if defined(BOTAN_HAS_SHA2_64)
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_384, "SHA-384");
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512, "SHA-512");
-BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_512_256, "SHA-512-256");
+#if defined(BOTAN_HAS_MD4)
+ if(req.algo_name() == "MD4")
+ {
+ return std::unique_ptr<HashFunction>(new MD4);
+ }
#endif
-#if defined(BOTAN_HAS_TIGER)
-BOTAN_REGISTER_NAMED_T_2LEN(HashFunction, Tiger, "Tiger", "base", 24, 3);
+#if defined(BOTAN_HAS_GOST_34_11)
+ if(req.algo_name() == "GOST-R-34.11-94")
+ {
+ return std::unique_ptr<HashFunction>(new GOST_34_11);
+ }
#endif
-#if defined(BOTAN_HAS_SKEIN_512)
-BOTAN_REGISTER_NAMED_T(HashFunction, "Skein-512", Skein_512, Skein_512::make);
+#if defined(BOTAN_HAS_ADLER32)
+ if(req.algo_name() == "Adler32")
+ {
+ return std::unique_ptr<HashFunction>(new Adler32);
+ }
#endif
-#if defined(BOTAN_HAS_WHIRLPOOL)
-BOTAN_REGISTER_HASH_NOARGS(Whirlpool);
+#if defined(BOTAN_HAS_CRC24)
+ if(req.algo_name() == "CRC24")
+ {
+ return std::unique_ptr<HashFunction>(new CRC24);
+ }
#endif
-#if defined(BOTAN_HAS_BLAKE2B)
-BOTAN_REGISTER_NAMED_T(HashFunction, "Blake2b", Blake2b, Blake2b::make);
+#if defined(BOTAN_HAS_CRC32)
+ if(req.algo_name() == "CRC32")
+ {
+ return std::unique_ptr<HashFunction>(new CRC32);
+ }
#endif
+ return nullptr;
+ }
+
+//static
+std::unique_ptr<HashFunction>
+HashFunction::create_or_throw(const std::string& algo,
+ const std::string& provider)
+ {
+ if(auto hash = HashFunction::create(algo, provider))
+ {
+ return hash;
+ }
+ throw Lookup_Error("Hash", algo, provider);
+ }
+
+std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
+ {
+ return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl"});
+ }
+
}
+
diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h
index 206333b9f..f6cf470cb 100644
--- a/src/lib/hash/hash.h
+++ b/src/lib/hash/hash.h
@@ -8,7 +8,6 @@
#ifndef BOTAN_HASH_FUNCTION_BASE_CLASS_H__
#define BOTAN_HASH_FUNCTION_BASE_CLASS_H__
-#include <botan/scan_name.h>
#include <botan/buf_comp.h>
#include <string>
@@ -20,17 +19,25 @@ namespace Botan {
class BOTAN_DLL HashFunction : public Buffered_Computation
{
public:
- typedef SCAN_Name Spec;
+ /**
+ * Create an instance based on a name, or return null if the
+ * algo/provider combination cannot be found. If provider is
+ * empty then best available is chosen.
+ */
+ static std::unique_ptr<HashFunction>
+ create(const std::string& algo_spec,
+ const std::string& provider = "");
/**
* Create an instance based on a name
* If provider is empty then best available is chosen.
* @param algo_spec algorithm name
* @param provider provider implementation to use
- * @return a null pointer if the algo/provider combination cannot be found
+ * Throws Lookup_Error if not not found.
*/
- static std::unique_ptr<HashFunction> create(const std::string& algo_spec,
- const std::string& provider = "");
+ static std::unique_ptr<HashFunction>
+ create_or_throw(const std::string& algo_spec,
+ const std::string& provider = "");
/**
* @return list of available providers for this algorithm, empty if not available
@@ -49,9 +56,7 @@ class BOTAN_DLL HashFunction : public Buffered_Computation
*/
virtual std::string provider() const { return "base"; }
- HashFunction();
-
- virtual ~HashFunction();
+ virtual ~HashFunction() {}
/**
* Reset the state.
diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp
index f6bed96ee..7320afee3 100644
--- a/src/lib/hash/par_hash/par_hash.cpp
+++ b/src/lib/hash/par_hash/par_hash.cpp
@@ -10,23 +10,6 @@
namespace Botan {
-Parallel* Parallel::make(const Spec& spec)
- {
- std::vector<std::unique_ptr<HashFunction>> m_hashes;
-
- for(size_t i = 0; i != spec.arg_count(); ++i)
- {
- auto h = HashFunction::create(spec.arg(i));
- if(!h)
- return nullptr;
- m_hashes.push_back(std::move(h));
- }
-
- Parallel* p = new Parallel;
- std::swap(p->m_hashes, m_hashes);
- return p;
- }
-
void Parallel::add_data(const byte input[], size_t length)
{
for(auto&& hash : m_hashes)
@@ -65,10 +48,10 @@ std::string Parallel::name() const
HashFunction* Parallel::clone() const
{
- std::vector<HashFunction*> hash_copies;
+ std::vector<std::unique_ptr<HashFunction>> hash_copies;
for(auto&& hash : m_hashes)
- hash_copies.push_back(hash.get());
+ hash_copies.push_back(std::unique_ptr<HashFunction>(hash->clone()));
return new Parallel(hash_copies);
}
@@ -79,12 +62,11 @@ void Parallel::clear()
hash->clear();
}
-Parallel::Parallel(const std::vector<HashFunction*>& in)
+Parallel::Parallel(std::vector<std::unique_ptr<HashFunction>>& h)
{
- for(size_t i = 0; i != in.size(); ++i)
+ for(size_t i = 0; i != h.size(); ++i)
{
- std::unique_ptr<HashFunction> h(in[i]->clone());
- m_hashes.push_back(std::move(h));
+ m_hashes.push_back(std::unique_ptr<HashFunction>(h[i].release()));
}
}
diff --git a/src/lib/hash/par_hash/par_hash.h b/src/lib/hash/par_hash/par_hash.h
index 3a93f4e8e..67d026c2f 100644
--- a/src/lib/hash/par_hash/par_hash.h
+++ b/src/lib/hash/par_hash/par_hash.h
@@ -27,13 +27,12 @@ class BOTAN_DLL Parallel final : public HashFunction
/**
* @param hashes a set of hashes to compute in parallel
+ * Takes ownership of all pointers
*/
- explicit Parallel(const std::vector<HashFunction*>& hashes);
+ explicit Parallel(std::vector<std::unique_ptr<HashFunction>>& hashes);
Parallel(const Parallel&) = delete;
Parallel& operator=(const Parallel&) = delete;
-
- static Parallel* make(const Spec& spec);
private:
Parallel() {}
diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp
index 86ea9e75a..21eeb1f27 100644
--- a/src/lib/hash/skein/skein_512.cpp
+++ b/src/lib/hash/skein/skein_512.cpp
@@ -12,11 +12,6 @@
namespace Botan {
-Skein_512* Skein_512::make(const Spec& spec)
- {
- return new Skein_512(spec.arg_as_integer(0, 512), spec.arg(1, ""));
- }
-
Skein_512::Skein_512(size_t arg_output_bits,
const std::string& arg_personalization) :
m_personalization(arg_personalization),
diff --git a/src/lib/hash/skein/skein_512.h b/src/lib/hash/skein/skein_512.h
index 001d9a991..1f34f1583 100644
--- a/src/lib/hash/skein/skein_512.h
+++ b/src/lib/hash/skein/skein_512.h
@@ -32,8 +32,6 @@ class BOTAN_DLL Skein_512 final : public HashFunction
size_t hash_block_size() const override { return 64; }
size_t output_length() const override { return m_output_bits / 8; }
- static Skein_512* make(const Spec& spec);
-
HashFunction* clone() const override;
std::string name() const override;
void clear() override;