diff options
Diffstat (limited to 'src/lib/modes')
-rw-r--r-- | src/lib/modes/aead/aead.cpp | 52 | ||||
-rw-r--r-- | src/lib/modes/aead/aead.h | 27 | ||||
-rw-r--r-- | src/lib/modes/cipher_mode.cpp | 55 | ||||
-rw-r--r-- | src/lib/modes/cipher_mode.h | 44 |
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(); + } } |