diff options
Diffstat (limited to 'src/lib/stream/stream_cipher.cpp')
-rw-r--r-- | src/lib/stream/stream_cipher.cpp | 100 |
1 files changed, 80 insertions, 20 deletions
diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 7c41722a0..4b27caafe 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -1,12 +1,12 @@ /* * Stream Ciphers -* (C) 2015 Jack Lloyd +* (C) 2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/stream_cipher.h> -#include <botan/internal/algo_registry.h> +#include <botan/scan_name.h> #if defined(BOTAN_HAS_CHACHA) #include <botan/chacha.h> @@ -32,44 +32,104 @@ #include <botan/rc4.h> #endif +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> +#endif + namespace Botan { std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec, const std::string& provider) { - return std::unique_ptr<StreamCipher>(make_a<StreamCipher>(Botan::StreamCipher::Spec(algo_spec), provider)); - } - -std::vector<std::string> StreamCipher::providers(const std::string& algo_spec) - { - return providers_of<StreamCipher>(StreamCipher::Spec(algo_spec)); - } + const SCAN_Name req(algo_spec); -StreamCipher::StreamCipher() {} -StreamCipher::~StreamCipher() {} +#if defined(BOTAN_HAS_CTR_BE) + if(req.algo_name() == "CTR-BE" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto c = BlockCipher::create(req.arg(0))) + return std::unique_ptr<StreamCipher>(new CTR_BE(c.release())); + } + } +#endif #if defined(BOTAN_HAS_CHACHA) -BOTAN_REGISTER_T_1LEN(StreamCipher, ChaCha, 20); + if(req.algo_name() == "ChaCha") + { + if(provider.empty() || provider == "base") + return std::unique_ptr<StreamCipher>(new ChaCha(req.arg_as_integer(0, 20))); + } #endif #if defined(BOTAN_HAS_SALSA20) -BOTAN_REGISTER_T_NOARGS(StreamCipher, Salsa20); + if(req.algo_name() == "Salsa20") + { + if(provider.empty() || provider == "base") + return std::unique_ptr<StreamCipher>(new Salsa20); + } #endif #if defined(BOTAN_HAS_SHAKE_CIPHER) -BOTAN_REGISTER_NAMED_T(StreamCipher, "SHAKE-128", SHAKE_128, make_new_T<SHAKE_128>); -#endif - -#if defined(BOTAN_HAS_CTR_BE) -BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make); + if(req.algo_name() == "SHAKE-128") + { + if(provider.empty() || provider == "base") + return std::unique_ptr<StreamCipher>(new SHAKE_128); + } #endif #if defined(BOTAN_HAS_OFB) -BOTAN_REGISTER_NAMED_T(StreamCipher, "OFB", OFB, OFB::make); + if(req.algo_name() == "OFB" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto c = BlockCipher::create(req.arg(0))) + return std::unique_ptr<StreamCipher>(new OFB(c.release())); + } + } #endif #if defined(BOTAN_HAS_RC4) -BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); + + if(req.algo_name() == "RC4" || + req.algo_name() == "ARC4" || + req.algo_name() == "MARK-4") + { + const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0); + +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip)); + } #endif + if(provider.empty() || provider == "base") + { + return std::unique_ptr<StreamCipher>(new RC4(skip)); + } + } + +#endif + + return nullptr; + } + +//static +std::unique_ptr<StreamCipher> +StreamCipher::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto sc = StreamCipher::create(algo, provider)) + { + return sc; + } + throw Lookup_Error("Stream cipher", algo, provider); + } + +std::vector<std::string> StreamCipher::providers(const std::string& algo_spec) + { + return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"}); + } + } |