diff options
Diffstat (limited to 'src/lib/libstate')
-rw-r--r-- | src/lib/libstate/lookup.cpp | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/src/lib/libstate/lookup.cpp b/src/lib/libstate/lookup.cpp index 290c266a3..08f0ac866 100644 --- a/src/lib/libstate/lookup.cpp +++ b/src/lib/libstate/lookup.cpp @@ -6,8 +6,19 @@ */ #include <botan/lookup.h> +#include <botan/cipher_mode.h> +#include <botan/filters.h> #include <botan/libstate.h> -#include <botan/engine.h> +#include <botan/parsing.h> +#include <botan/transform_filter.h> + +#if defined(BOTAN_HAS_OFB) + #include <botan/ofb.h> +#endif + +#if defined(BOTAN_HAS_CTR_BE) + #include <botan/ctr.h> +#endif namespace Botan { @@ -82,13 +93,44 @@ Keyed_Filter* get_cipher(const std::string& algo_spec, { Algorithm_Factory& af = global_state().algorithm_factory(); - Algorithm_Factory::Engine_Iterator i(af); + std::unique_ptr<Cipher_Mode> c(get_cipher_mode(algo_spec, direction)); + if(c) + return new Transform_Filter(c.release()); + + std::vector<std::string> algo_parts = split_on(algo_spec, '/'); + if(algo_parts.empty()) + throw Invalid_Algorithm_Name(algo_spec); + + const std::string cipher_name = algo_parts[0]; + + // check if it is a stream cipher first (easy case) + const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); + if(stream_cipher) + return new StreamCipher_Filter(stream_cipher->clone()); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); + if(!block_cipher) + return nullptr; + + if(algo_parts.size() >= 4) + return nullptr; // 4 part mode, not something we know about + + if(algo_parts.size() < 2) + throw Lookup_Error("Cipher specification '" + algo_spec + + "' is missing mode identifier"); + + const std::string mode = algo_parts[1]; + + +#if defined(BOTAN_HAS_OFB) + if(mode == "OFB") + return new StreamCipher_Filter(new OFB(block_cipher->clone())); +#endif - while(Engine* engine = i.next()) - { - if(Keyed_Filter* algo = engine->get_cipher(algo_spec, direction, af)) - return algo; - } +#if defined(BOTAN_HAS_CTR_BE) + if(mode == "CTR-BE") + return new StreamCipher_Filter(new CTR_BE(block_cipher->clone())); +#endif throw Algorithm_Not_Found(algo_spec); } |