diff options
author | Alexander Bluhm <[email protected]> | 2017-04-03 18:00:54 +0200 |
---|---|---|
committer | Alexander Bluhm <[email protected]> | 2017-04-25 15:50:33 +0200 |
commit | a9b91783b734d0cb1b3515f091564d126218275f (patch) | |
tree | 6ea2804824dc3286865cdd368952c3922171a3eb /src/lib/modes | |
parent | 3a560e25b2ab197e54935eb047090446be6c10f5 (diff) |
Implement cipher modes with OpenSSL.
Use the OpenSSL provider to implement AES CBC mode. Also pass down
the provider to the encryption layer if there is no matching OpenSSL
mode. Add a test with empty nonce.
Diffstat (limited to 'src/lib/modes')
-rw-r--r-- | src/lib/modes/cipher_mode.cpp | 38 | ||||
-rw-r--r-- | src/lib/modes/cipher_mode.h | 13 |
2 files changed, 46 insertions, 5 deletions
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index 843e49581..74d565f33 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -34,10 +34,26 @@ #include <botan/xts.h> #endif +#if defined(BOTAN_HAS_OPENSSL) + #include <botan/internal/openssl.h> +#endif + namespace Botan { -Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) +Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction, + const std::string& provider) { +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + if(Cipher_Mode* bc = make_openssl_cipher_mode(algo, direction)) + return bc; + + if(!provider.empty()) + return nullptr; + } +#endif + if(auto sc = StreamCipher::create(algo)) { return new Stream_Cipher_Mode(sc.release()); @@ -69,7 +85,7 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) alg_args << ')'; const std::string mode_name = mode_info[0] + alg_args.str(); - return get_cipher_mode(mode_name, direction); + return get_cipher_mode(mode_name, direction, provider); } #if defined(BOTAN_HAS_BLOCK_CIPHER) @@ -81,7 +97,7 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) return nullptr; } - std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0))); + std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0), provider)); if(!bc) { @@ -141,4 +157,20 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) return nullptr; } +//static +std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec) + { + const std::vector<std::string>& possible = { "base", "openssl" }; + std::vector<std::string> providers; + for(auto&& prov : possible) + { + std::unique_ptr<Cipher_Mode> mode(get_cipher_mode(algo_spec, ENCRYPTION, prov)); + if(mode) + { + providers.push_back(prov); // available + } + } + return providers; + } + } diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h index 411a1b3e5..bf1821256 100644 --- a/src/lib/modes/cipher_mode.h +++ b/src/lib/modes/cipher_mode.h @@ -25,6 +25,12 @@ class BOTAN_DLL Cipher_Mode public: virtual ~Cipher_Mode() = default; + /** + * @return list of available providers for this algorithm, empty if not available + * @param algo_spec algorithm name + */ + static std::vector<std::string> providers(const std::string& algo_spec); + /* * Prepare for processing a message under the specified nonce */ @@ -209,14 +215,17 @@ class BOTAN_DLL Cipher_Mode * The two possible directions for cipher filters, determining whether they * actually perform encryption or decryption. */ -enum Cipher_Dir { ENCRYPTION, DECRYPTION }; +enum Cipher_Dir : int { ENCRYPTION, DECRYPTION }; /** * Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS") * @param algo_spec cipher name * @param direction ENCRYPTION or DECRYPTION +* @param provider provider implementation to choose */ -BOTAN_DLL Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction); +BOTAN_DLL Cipher_Mode* get_cipher_mode(const std::string& algo_spec, + Cipher_Dir direction, + const std::string& provider = ""); } |