aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/hash/hash.cpp
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/hash.cpp
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/hash.cpp')
-rw-r--r--src/lib/hash/hash.cpp219
1 files changed, 161 insertions, 58 deletions
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"});
+ }
+
}
+