aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/block
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/block
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/block')
-rw-r--r--src/lib/block/block_cipher.cpp232
-rw-r--r--src/lib/block/block_cipher.h18
-rw-r--r--src/lib/block/cascade/cascade.cpp10
-rw-r--r--src/lib/block/cascade/cascade.h2
-rw-r--r--src/lib/block/lion/lion.cpp16
-rw-r--r--src/lib/block/lion/lion.h2
6 files changed, 184 insertions, 96 deletions
diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp
index 2388057c6..abfaf55ef 100644
--- a/src/lib/block/block_cipher.cpp
+++ b/src/lib/block/block_cipher.cpp
@@ -6,8 +6,7 @@
*/
#include <botan/block_cipher.h>
-#include <botan/cpuid.h>
-#include <botan/internal/algo_registry.h>
+#include <botan/scan_name.h>
#if defined(BOTAN_HAS_AES)
#include <botan/aes.h>
@@ -79,109 +78,220 @@
#include <botan/xtea.h>
#endif
-namespace Botan {
-
-BlockCipher::~BlockCipher() {}
+#if defined(BOTAN_HAS_OPENSSL)
+ #include <botan/internal/openssl.h>
+#endif
-std::unique_ptr<BlockCipher> BlockCipher::create(const std::string& algo_spec,
- const std::string& provider)
- {
- return std::unique_ptr<BlockCipher>(make_a<BlockCipher>(Botan::BlockCipher::Spec(algo_spec), provider));
- }
+namespace Botan {
-std::vector<std::string> BlockCipher::providers(const std::string& algo_spec)
+std::unique_ptr<BlockCipher>
+BlockCipher::create(const std::string& algo,
+ const std::string& provider)
{
- return providers_of<BlockCipher>(BlockCipher::Spec(algo_spec));
- }
+ const SCAN_Name req(algo);
-#define BOTAN_REGISTER_BLOCK_CIPHER(name, maker) BOTAN_REGISTER_T(BlockCipher, name, maker)
-#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(name) BOTAN_REGISTER_T_NOARGS(BlockCipher, name)
+#if defined(BOTAN_HAS_OPENSSL)
+ if(provider.empty() || provider == "openssl")
+ {
+ if(auto bc = make_openssl_block_cipher(algo))
+ return bc;
-#define BOTAN_REGISTER_BLOCK_CIPHER_1LEN(name, def) BOTAN_REGISTER_T_1LEN(BlockCipher, name, def)
+ if(!provider.empty())
+ return nullptr;
+ }
+#endif
-#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(type, name) \
- BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, make_new_T<type>)
-#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \
- BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len<type,def>))
-#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \
- BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str<type>, std::placeholders::_1, def))
+ // TODO: CommonCrypto
+ // TODO: CryptoAPI
+ // TODO: /dev/crypto
-#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(cond, type, name, provider, pref) \
- BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, BlockCipher, type, name, provider, pref)
+ // Only base providers from here on out
+ if(provider.empty() == false && provider != "base")
+ return nullptr;
#if defined(BOTAN_HAS_AES)
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_128, "AES-128");
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_192, "AES-192");
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_256, "AES-256");
+ if(req.algo_name() == "AES-128" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new AES_128);
+ }
+
+ if(req.algo_name() == "AES-192" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new AES_192);
+ }
+
+ if(req.algo_name() == "AES-256" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new AES_256);
+ }
#endif
-#if defined(BOTAN_HAS_BLOWFISH)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish);
+#if defined(BOTAN_HAS_SERPENT)
+ if(req.algo_name() == "Serpent" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Serpent);
+ }
#endif
-#if defined(BOTAN_HAS_CAMELLIA)
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_128, "Camellia-128");
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_192, "Camellia-192");
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Camellia_256, "Camellia-256");
+#if defined(BOTAN_HAS_TWOFISH)
+ if(req.algo_name() == "Twofish" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Twofish);
+ }
#endif
-#if defined(BOTAN_HAS_CAST)
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_128, "CAST-128");
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(CAST_256, "CAST-256");
+#if defined(BOTAN_HAS_THREEFISH_512)
+ if(req.algo_name() == "Threefish-512" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Threefish_512);
+ }
#endif
-#if defined(BOTAN_HAS_DES)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DES);
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TripleDES);
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DESX);
+#if defined(BOTAN_HAS_BLOWFISH)
+ if(req.algo_name() == "Blowfish" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Blowfish);
+ }
#endif
-#if defined(BOTAN_HAS_GOST_28147_89)
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(GOST_28147_89, "GOST-28147-89", "R3411_94_TestParam");
+#if defined(BOTAN_HAS_CAMELLIA)
+ if(req.algo_name() == "Camellia-128" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Camellia_128);
+ }
+
+ if(req.algo_name() == "Camellia-192" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Camellia_192);
+ }
+
+ if(req.algo_name() == "Camellia-256" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Camellia_256);
+ }
#endif
-#if defined(BOTAN_HAS_IDEA)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA);
+#if defined(BOTAN_HAS_DES)
+ if(req.algo_name() == "DES" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new DES);
+ }
+
+ if(req.algo_name() == "DESX" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new DESX);
+ }
+
+ if(req.algo_name() == "TripleDES" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new TripleDES);
+ }
#endif
-#if defined(BOTAN_HAS_KASUMI)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI);
+#if defined(BOTAN_HAS_NOEKEON)
+ if(req.algo_name() == "Noekeon" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new Noekeon);
+ }
#endif
-#if defined(BOTAN_HAS_MISTY1)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MISTY1);
+#if defined(BOTAN_HAS_CAST)
+ if(req.algo_name() == "CAST-128" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new CAST_128);
+ }
+
+ if(req.algo_name() == "CAST-256" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new CAST_256);
+ }
#endif
-#if defined(BOTAN_HAS_NOEKEON)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon);
+#if defined(BOTAN_HAS_GOST_28147_89)
+ if(req.algo_name() == "GOST-28147-89")
+ {
+ return std::unique_ptr<BlockCipher>(new GOST_28147_89(req.arg(0, "R3411_94_TestParam")));
+ }
#endif
-#if defined(BOTAN_HAS_SEED)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED);
+#if defined(BOTAN_HAS_IDEA)
+ if(req.algo_name() == "IDEA" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new IDEA);
+ }
#endif
-#if defined(BOTAN_HAS_SERPENT)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent);
+#if defined(BOTAN_HAS_KASUMI)
+ if(req.algo_name() == "KASUMI" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new KASUMI);
+ }
#endif
-#if defined(BOTAN_HAS_TWOFISH)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish);
+#if defined(BOTAN_HAS_MISTY1)
+ if(req.algo_name() == "MISTY1" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new MISTY1);
+ }
#endif
-#if defined(BOTAN_HAS_THREEFISH_512)
-BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Threefish_512, "Threefish-512");
+#if defined(BOTAN_HAS_SEED)
+ if(req.algo_name() == "SEED" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new SEED);
+ }
#endif
#if defined(BOTAN_HAS_XTEA)
-BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA);
+ if(req.algo_name() == "XTEA" && req.arg_count() == 0)
+ {
+ return std::unique_ptr<BlockCipher>(new XTEA);
+ }
#endif
#if defined(BOTAN_HAS_CASCADE)
-BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, Cascade_Cipher::make);
+ if(req.algo_name() == "Cascade" && req.arg_count() == 2)
+ {
+ std::unique_ptr<BlockCipher> c1(BlockCipher::create(req.arg(0)));
+ std::unique_ptr<BlockCipher> c2(BlockCipher::create(req.arg(1)));
+
+ if(c1 && c2)
+ return std::unique_ptr<BlockCipher>(new Cascade_Cipher(c1.release(), c2.release()));
+ }
#endif
#if defined(BOTAN_HAS_LION)
-BOTAN_REGISTER_NAMED_T(BlockCipher, "Lion", Lion, Lion::make);
+ if(req.algo_name() == "Lion" && req.arg_count_between(2, 3))
+ {
+ std::unique_ptr<HashFunction> hash(HashFunction::create(req.arg(0)));
+ std::unique_ptr<StreamCipher> stream(StreamCipher::create(req.arg(1)));
+
+ if(hash && stream)
+ {
+ const size_t block_size = req.arg_as_integer(2, 1024);
+ return std::unique_ptr<BlockCipher>(new Lion(hash.release(), stream.release(), block_size));
+ }
+ }
#endif
+ return nullptr;
+ }
+
+//static
+std::unique_ptr<BlockCipher>
+BlockCipher::create_or_throw(const std::string& algo,
+ const std::string& provider)
+ {
+ if(auto bc = BlockCipher::create(algo, provider))
+ {
+ return bc;
+ }
+ throw Lookup_Error("Block cipher", algo, provider);
+ }
+
+std::vector<std::string> BlockCipher::providers(const std::string& algo)
+ {
+ return probe_providers_of<BlockCipher>(algo, { "base", "openssl" });
+ }
+
}
diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h
index 7c7084155..2062160bc 100644
--- a/src/lib/block/block_cipher.h
+++ b/src/lib/block/block_cipher.h
@@ -8,7 +8,6 @@
#ifndef BOTAN_BLOCK_CIPHER_H__
#define BOTAN_BLOCK_CIPHER_H__
-#include <botan/scan_name.h>
#include <botan/sym_algo.h>
#include <string>
@@ -20,7 +19,6 @@ namespace Botan {
class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
{
public:
- typedef SCAN_Name Spec;
/**
* Create an instance based on a name
@@ -29,8 +27,18 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* @param provider provider implementation to choose
* @return a null pointer if the algo/provider combination cannot be found
*/
- static std::unique_ptr<BlockCipher> create(const std::string& algo_spec,
- const std::string& provider = "");
+ static std::unique_ptr<BlockCipher>
+ create(const std::string& algo_spec,
+ const std::string& provider = "");
+
+ /**
+ * Create an instance based on a name, or throw if the
+ * algo/provider combination cannot be found. If provider is
+ * empty then best available is chosen.
+ */
+ static std::unique_ptr<BlockCipher>
+ create_or_throw(const std::string& algo_spec,
+ const std::string& provider = "");
/**
* @return list of available providers for this algorithm, empty if not available
@@ -165,7 +173,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
*/
virtual BlockCipher* clone() const = 0;
- virtual ~BlockCipher();
+ virtual ~BlockCipher() {}
};
/**
diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp
index 100fb33ab..98e862de9 100644
--- a/src/lib/block/cascade/cascade.cpp
+++ b/src/lib/block/cascade/cascade.cpp
@@ -9,16 +9,6 @@
namespace Botan {
-Cascade_Cipher* Cascade_Cipher::make(const BlockCipher::Spec& spec)
- {
- std::unique_ptr<BlockCipher> c1(BlockCipher::create(spec.arg(0)));
- std::unique_ptr<BlockCipher> c2(BlockCipher::create(spec.arg(1)));
-
- if(c1 && c2)
- return new Cascade_Cipher(c1.release(), c2.release());
- return nullptr;
- }
-
void Cascade_Cipher::encrypt_n(const byte in[], byte out[],
size_t blocks) const
{
diff --git a/src/lib/block/cascade/cascade.h b/src/lib/block/cascade/cascade.h
index 21af5bea4..aa7bd0421 100644
--- a/src/lib/block/cascade/cascade.h
+++ b/src/lib/block/cascade/cascade.h
@@ -33,8 +33,6 @@ class BOTAN_DLL Cascade_Cipher final : public BlockCipher
std::string name() const override;
BlockCipher* clone() const override;
- static Cascade_Cipher* make(const Spec& spec);
-
/**
* Create a cascade of two block ciphers
* @param cipher1 the first cipher
diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp
index 7ae620504..56aa55c2f 100644
--- a/src/lib/block/lion/lion.cpp
+++ b/src/lib/block/lion/lion.cpp
@@ -10,22 +10,6 @@
namespace Botan {
-Lion* Lion::make(const BlockCipher::Spec& spec)
- {
- if(spec.arg_count_between(2, 3))
- {
- std::unique_ptr<HashFunction> hash(HashFunction::create(spec.arg(0)));
- std::unique_ptr<StreamCipher> stream(StreamCipher::create(spec.arg(1)));
-
- if(hash && stream)
- {
- const size_t block_size = spec.arg_as_integer(2, 1024);
- return new Lion(hash.release(), stream.release(), block_size);
- }
- }
- return nullptr;
- }
-
/*
* Lion Encryption
*/
diff --git a/src/lib/block/lion/lion.h b/src/lib/block/lion/lion.h
index f22f0f8a8..e6ecca64f 100644
--- a/src/lib/block/lion/lion.h
+++ b/src/lib/block/lion/lion.h
@@ -39,8 +39,6 @@ class BOTAN_DLL Lion final : public BlockCipher
std::string name() const override;
BlockCipher* clone() const override;
- static Lion* make(const Spec&);
-
/**
* @param hash the hash to use internally
* @param cipher the stream cipher to use internally