aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/block/block_cipher.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/block/block_cipher.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/block/block_cipher.cpp')
-rw-r--r--src/lib/block/block_cipher.cpp232
1 files changed, 171 insertions, 61 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" });
+ }
+
}