aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/modes
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/modes')
-rw-r--r--src/lib/modes/aead/aead.cpp52
-rw-r--r--src/lib/modes/aead/aead.h27
-rw-r--r--src/lib/modes/cipher_mode.cpp55
-rw-r--r--src/lib/modes/cipher_mode.h44
4 files changed, 127 insertions, 51 deletions
diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp
index e8885dc0e..cd1db761d 100644
--- a/src/lib/modes/aead/aead.cpp
+++ b/src/lib/modes/aead/aead.cpp
@@ -39,15 +39,27 @@
namespace Botan {
-AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
+std::unique_ptr<AEAD_Mode> AEAD_Mode::create_or_throw(const std::string& algo,
+ Cipher_Dir dir,
+ const std::string& provider)
+ {
+ if(auto aead = AEAD_Mode::create(algo, dir, provider))
+ return aead;
+
+ throw Lookup_Error("AEAD", algo, provider);
+ }
+
+std::unique_ptr<AEAD_Mode> AEAD_Mode::create(const std::string& algo,
+ Cipher_Dir dir,
+ const std::string& provider)
{
#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305)
if(algo == "ChaCha20Poly1305")
{
if(dir == ENCRYPTION)
- return new ChaCha20Poly1305_Encryption;
+ return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Encryption);
else
- return new ChaCha20Poly1305_Decryption;
+ return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Decryption);
}
#endif
@@ -59,7 +71,7 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
if(mode_info.empty())
- return nullptr;
+ return std::unique_ptr<AEAD_Mode>();
std::ostringstream alg_args;
@@ -71,7 +83,7 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
alg_args << ')';
const std::string mode_name = mode_info[0] + alg_args.str();
- return get_aead(mode_name, dir);
+ return AEAD_Mode::create(mode_name, dir);
}
#if defined(BOTAN_HAS_BLOCK_CIPHER)
@@ -80,14 +92,14 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
if(req.arg_count() == 0)
{
- return nullptr;
+ return std::unique_ptr<AEAD_Mode>();
}
- std::unique_ptr<BlockCipher> bc(BlockCipher::create(req.arg(0)));
+ std::unique_ptr<BlockCipher> bc(BlockCipher::create(req.arg(0), provider));
if(!bc)
{
- return nullptr;
+ return std::unique_ptr<AEAD_Mode>();
}
#if defined(BOTAN_HAS_AEAD_CCM)
@@ -96,9 +108,9 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
size_t tag_len = req.arg_as_integer(1, 16);
size_t L_len = req.arg_as_integer(2, 3);
if(dir == ENCRYPTION)
- return new CCM_Encryption(bc.release(), tag_len, L_len);
+ return std::unique_ptr<AEAD_Mode>(new CCM_Encryption(bc.release(), tag_len, L_len));
else
- return new CCM_Decryption(bc.release(), tag_len, L_len);
+ return std::unique_ptr<AEAD_Mode>(new CCM_Decryption(bc.release(), tag_len, L_len));
}
#endif
@@ -107,9 +119,9 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
{
size_t tag_len = req.arg_as_integer(1, 16);
if(dir == ENCRYPTION)
- return new GCM_Encryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new GCM_Encryption(bc.release(), tag_len));
else
- return new GCM_Decryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new GCM_Decryption(bc.release(), tag_len));
}
#endif
@@ -118,9 +130,9 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
{
size_t tag_len = req.arg_as_integer(1, 16);
if(dir == ENCRYPTION)
- return new OCB_Encryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new OCB_Encryption(bc.release(), tag_len));
else
- return new OCB_Decryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new OCB_Decryption(bc.release(), tag_len));
}
#endif
@@ -129,9 +141,9 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
{
size_t tag_len = req.arg_as_integer(1, bc->block_size());
if(dir == ENCRYPTION)
- return new EAX_Encryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new EAX_Encryption(bc.release(), tag_len));
else
- return new EAX_Decryption(bc.release(), tag_len);
+ return std::unique_ptr<AEAD_Mode>(new EAX_Decryption(bc.release(), tag_len));
}
#endif
@@ -139,15 +151,17 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir)
if(req.algo_name() == "SIV")
{
if(dir == ENCRYPTION)
- return new SIV_Encryption(bc.release());
+ return std::unique_ptr<AEAD_Mode>(new SIV_Encryption(bc.release()));
else
- return new SIV_Decryption(bc.release());
+ return std::unique_ptr<AEAD_Mode>(new SIV_Decryption(bc.release()));
}
#endif
#endif
- return nullptr;
+ return std::unique_ptr<AEAD_Mode>();
}
+
+
}
diff --git a/src/lib/modes/aead/aead.h b/src/lib/modes/aead/aead.h
index 18bc339f1..4d4b60ce1 100644
--- a/src/lib/modes/aead/aead.h
+++ b/src/lib/modes/aead/aead.h
@@ -22,6 +22,28 @@ namespace Botan {
class BOTAN_PUBLIC_API(2,0) AEAD_Mode : public Cipher_Mode
{
public:
+ /**
+ * Create an AEAD mode
+ * @param algo the algorithm to create
+ * @param direction specify if this should be an encryption or decryption AEAD
+ * @param provider optional specification for provider to use
+ * @return an AEAD mode or a null pointer if not available
+ */
+ static std::unique_ptr<AEAD_Mode> create(const std::string& algo,
+ Cipher_Dir direction,
+ const std::string& provider = "");
+
+ /**
+ * Create an AEAD mode, or throw
+ * @param algo the algorithm to create
+ * @param direction specify if this should be an encryption or decryption AEAD
+ * @param provider optional specification for provider to use
+ * @return an AEAD mode, or throw an exception
+ */
+ static std::unique_ptr<AEAD_Mode> create_or_throw(const std::string& algo,
+ Cipher_Dir direction,
+ const std::string& provider = "");
+
bool authenticated() const override { return true; }
/**
@@ -82,7 +104,10 @@ class BOTAN_PUBLIC_API(2,0) AEAD_Mode : public Cipher_Mode
* @param name AEAD name
* @param direction ENCRYPTION or DECRYPTION
*/
-BOTAN_PUBLIC_API(2,0) AEAD_Mode* get_aead(const std::string& name, Cipher_Dir direction);
+inline AEAD_Mode* get_aead(const std::string& name, Cipher_Dir direction)
+ {
+ return AEAD_Mode::create(name, direction, "").release();
+ }
}
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp
index 804713be7..6d04d93b4 100644
--- a/src/lib/modes/cipher_mode.cpp
+++ b/src/lib/modes/cipher_mode.cpp
@@ -37,29 +37,42 @@
namespace Botan {
-Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
- const std::string& provider)
+std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo,
+ Cipher_Dir direction,
+ const std::string& provider)
+ {
+ if(auto mode = Cipher_Mode::create(algo, direction, provider))
+ return mode;
+
+ throw Lookup_Error("Cipher mode", algo, provider);
+ }
+
+std::unique_ptr<Cipher_Mode> Cipher_Mode::create(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;
+ std::unique_ptr<Cipher_Mode> openssl_cipher(make_openssl_cipher_mode(algo, direction));
+
+ if(openssl_cipher)
+ return openssl_cipher;
if(!provider.empty())
- return nullptr;
+ return std::unique_ptr<Cipher_Mode>();
}
#endif
#if defined(BOTAN_HAS_STREAM_CIPHER)
if(auto sc = StreamCipher::create(algo))
{
- return new Stream_Cipher_Mode(sc.release());
+ return std::unique_ptr<Cipher_Mode>(new Stream_Cipher_Mode(sc.release()));
}
#endif
#if defined(BOTAN_HAS_AEAD_MODES)
- if(auto aead = get_aead(algo, direction))
+ if(auto aead = AEAD_Mode::create(algo, direction))
{
return aead;
}
@@ -72,7 +85,7 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
if(mode_info.empty())
- return nullptr;
+ return std::unique_ptr<Cipher_Mode>();
std::ostringstream alg_args;
@@ -84,7 +97,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, provider);
+ return Cipher_Mode::create(mode_name, direction, provider);
}
#if defined(BOTAN_HAS_BLOCK_CIPHER)
@@ -93,14 +106,14 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
if(spec.arg_count() == 0)
{
- return nullptr;
+ return std::unique_ptr<Cipher_Mode>();
}
std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0), provider));
if(!bc)
{
- return nullptr;
+ return std::unique_ptr<Cipher_Mode>();
}
#if defined(BOTAN_HAS_MODE_CBC)
@@ -111,9 +124,9 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
if(padding == "CTS")
{
if(direction == ENCRYPTION)
- return new CTS_Encryption(bc.release());
+ return std::unique_ptr<Cipher_Mode>(new CTS_Encryption(bc.release()));
else
- return new CTS_Decryption(bc.release());
+ return std::unique_ptr<Cipher_Mode>(new CTS_Decryption(bc.release()));
}
else
{
@@ -122,9 +135,9 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
if(pad)
{
if(direction == ENCRYPTION)
- return new CBC_Encryption(bc.release(), pad.release());
+ return std::unique_ptr<Cipher_Mode>(new CBC_Encryption(bc.release(), pad.release()));
else
- return new CBC_Decryption(bc.release(), pad.release());
+ return std::unique_ptr<Cipher_Mode>(new CBC_Decryption(bc.release(), pad.release()));
}
}
}
@@ -134,9 +147,9 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
if(spec.algo_name() == "XTS")
{
if(direction == ENCRYPTION)
- return new XTS_Encryption(bc.release());
+ return std::unique_ptr<Cipher_Mode>(new XTS_Encryption(bc.release()));
else
- return new XTS_Decryption(bc.release());
+ return std::unique_ptr<Cipher_Mode>(new XTS_Decryption(bc.release()));
}
#endif
@@ -145,15 +158,15 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction,
{
const size_t feedback_bits = spec.arg_as_integer(1, 8*bc->block_size());
if(direction == ENCRYPTION)
- return new CFB_Encryption(bc.release(), feedback_bits);
+ return std::unique_ptr<Cipher_Mode>(new CFB_Encryption(bc.release(), feedback_bits));
else
- return new CFB_Decryption(bc.release(), feedback_bits);
+ return std::unique_ptr<Cipher_Mode>(new CFB_Decryption(bc.release(), feedback_bits));
}
#endif
#endif
- return nullptr;
+ return std::unique_ptr<Cipher_Mode>();
}
//static
@@ -163,7 +176,7 @@ std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec)
std::vector<std::string> providers;
for(auto&& prov : possible)
{
- std::unique_ptr<Cipher_Mode> mode(get_cipher_mode(algo_spec, ENCRYPTION, prov));
+ std::unique_ptr<Cipher_Mode> mode = Cipher_Mode::create(algo_spec, ENCRYPTION, prov);
if(mode)
{
providers.push_back(prov); // available
diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h
index 7abfdac97..f67e737a4 100644
--- a/src/lib/modes/cipher_mode.h
+++ b/src/lib/modes/cipher_mode.h
@@ -18,6 +18,12 @@
namespace Botan {
/**
+* The two possible directions for cipher filters, determining whether they
+* actually perform encryption or decryption.
+*/
+enum Cipher_Dir : int { ENCRYPTION, DECRYPTION };
+
+/**
* Interface for cipher modes
*/
class BOTAN_PUBLIC_API(2,0) Cipher_Mode
@@ -31,6 +37,28 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode
*/
static std::vector<std::string> providers(const std::string& algo_spec);
+ /**
+ * Create an AEAD mode
+ * @param algo the algorithm to create
+ * @param direction specify if this should be an encryption or decryption AEAD
+ * @param provider optional specification for provider to use
+ * @return an AEAD mode or a null pointer if not available
+ */
+ static std::unique_ptr<Cipher_Mode> create(const std::string& algo,
+ Cipher_Dir direction,
+ const std::string& provider = "");
+
+ /**
+ * Create an AEAD mode, or throw
+ * @param algo the algorithm to create
+ * @param direction specify if this should be an encryption or decryption AEAD
+ * @param provider optional specification for provider to use
+ * @return an AEAD mode, or throw an exception
+ */
+ static std::unique_ptr<Cipher_Mode> create_or_throw(const std::string& algo,
+ Cipher_Dir direction,
+ const std::string& provider = "");
+
/*
* Prepare for processing a message under the specified nonce
*/
@@ -212,21 +240,17 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode
};
/**
-* The two possible directions for cipher filters, determining whether they
-* actually perform encryption or 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_PUBLIC_API(2,2)
-Cipher_Mode* get_cipher_mode(const std::string& algo_spec,
- Cipher_Dir direction,
- const std::string& provider = "");
+inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec,
+ Cipher_Dir direction,
+ const std::string& provider = "")
+ {
+ return Cipher_Mode::create(algo_spec, direction, provider).release();
+ }
}