aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/modes
diff options
context:
space:
mode:
authorAlexander Bluhm <[email protected]>2017-04-03 18:00:54 +0200
committerAlexander Bluhm <[email protected]>2017-04-25 15:50:33 +0200
commita9b91783b734d0cb1b3515f091564d126218275f (patch)
tree6ea2804824dc3286865cdd368952c3922171a3eb /src/lib/modes
parent3a560e25b2ab197e54935eb047090446be6c10f5 (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.cpp38
-rw-r--r--src/lib/modes/cipher_mode.h13
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 = "");
}