diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/lib/modes/aead/aead.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/lib/modes/aead/aead.cpp')
-rw-r--r-- | comm/third_party/botan/src/lib/modes/aead/aead.cpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/modes/aead/aead.cpp b/comm/third_party/botan/src/lib/modes/aead/aead.cpp new file mode 100644 index 0000000000..9ad550ffd7 --- /dev/null +++ b/comm/third_party/botan/src/lib/modes/aead/aead.cpp @@ -0,0 +1,176 @@ +/* +* (C) 2013,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/aead.h> +#include <botan/scan_name.h> +#include <botan/parsing.h> +#include <sstream> + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + #include <botan/block_cipher.h> +#endif + +#if defined(BOTAN_HAS_AEAD_CCM) + #include <botan/ccm.h> +#endif + +#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) + #include <botan/chacha20poly1305.h> +#endif + +#if defined(BOTAN_HAS_AEAD_EAX) + #include <botan/eax.h> +#endif + +#if defined(BOTAN_HAS_AEAD_GCM) + #include <botan/gcm.h> +#endif + +#if defined(BOTAN_HAS_AEAD_OCB) + #include <botan/ocb.h> +#endif + +#if defined(BOTAN_HAS_AEAD_SIV) + #include <botan/siv.h> +#endif + +namespace Botan { + +void AEAD_Mode::set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len) + { + if(i == 0) + this->set_associated_data(ad, ad_len); + else + throw Invalid_Argument("AEAD '" + name() + "' does not support multiple associated data"); + } + +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) + { + BOTAN_UNUSED(provider); +#if defined(BOTAN_HAS_AEAD_CHACHA20_POLY1305) + if(algo == "ChaCha20Poly1305") + { + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Encryption); + else + return std::unique_ptr<AEAD_Mode>(new ChaCha20Poly1305_Decryption); + + } +#endif + + if(algo.find('/') != std::string::npos) + { + const std::vector<std::string> algo_parts = split_on(algo, '/'); + const std::string cipher_name = algo_parts[0]; + const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]); + + if(mode_info.empty()) + return std::unique_ptr<AEAD_Mode>(); + + std::ostringstream alg_args; + + alg_args << '(' << cipher_name; + for(size_t i = 1; i < mode_info.size(); ++i) + alg_args << ',' << mode_info[i]; + for(size_t i = 2; i < algo_parts.size(); ++i) + alg_args << ',' << algo_parts[i]; + alg_args << ')'; + + const std::string mode_name = mode_info[0] + alg_args.str(); + return AEAD_Mode::create(mode_name, dir); + } + +#if defined(BOTAN_HAS_BLOCK_CIPHER) + + SCAN_Name req(algo); + + if(req.arg_count() == 0) + { + return std::unique_ptr<AEAD_Mode>(); + } + + std::unique_ptr<BlockCipher> bc(BlockCipher::create(req.arg(0), provider)); + + if(!bc) + { + return std::unique_ptr<AEAD_Mode>(); + } + +#if defined(BOTAN_HAS_AEAD_CCM) + if(req.algo_name() == "CCM") + { + size_t tag_len = req.arg_as_integer(1, 16); + size_t L_len = req.arg_as_integer(2, 3); + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new CCM_Encryption(bc.release(), tag_len, L_len)); + else + return std::unique_ptr<AEAD_Mode>(new CCM_Decryption(bc.release(), tag_len, L_len)); + } +#endif + +#if defined(BOTAN_HAS_AEAD_GCM) + if(req.algo_name() == "GCM") + { + size_t tag_len = req.arg_as_integer(1, 16); + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new GCM_Encryption(bc.release(), tag_len)); + else + return std::unique_ptr<AEAD_Mode>(new GCM_Decryption(bc.release(), tag_len)); + } +#endif + +#if defined(BOTAN_HAS_AEAD_OCB) + if(req.algo_name() == "OCB") + { + size_t tag_len = req.arg_as_integer(1, 16); + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new OCB_Encryption(bc.release(), tag_len)); + else + return std::unique_ptr<AEAD_Mode>(new OCB_Decryption(bc.release(), tag_len)); + } +#endif + +#if defined(BOTAN_HAS_AEAD_EAX) + if(req.algo_name() == "EAX") + { + size_t tag_len = req.arg_as_integer(1, bc->block_size()); + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new EAX_Encryption(bc.release(), tag_len)); + else + return std::unique_ptr<AEAD_Mode>(new EAX_Decryption(bc.release(), tag_len)); + } +#endif + +#if defined(BOTAN_HAS_AEAD_SIV) + if(req.algo_name() == "SIV") + { + if(dir == ENCRYPTION) + return std::unique_ptr<AEAD_Mode>(new SIV_Encryption(bc.release())); + else + return std::unique_ptr<AEAD_Mode>(new SIV_Decryption(bc.release())); + } +#endif + +#endif + + return std::unique_ptr<AEAD_Mode>(); + } + + + +} |