From 558808900bffc3c48da5e6d79ba602e88e619154 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 11 Oct 2016 13:00:57 -0400 Subject: Remove Algo_Registry I repent my use of global constructors. I repent my use of global locks. Hopefully I will never touch this code again. :) --- src/lib/stream/ctr/ctr.cpp | 10 ----- src/lib/stream/ctr/ctr.h | 2 - src/lib/stream/ofb/ofb.cpp | 10 ----- src/lib/stream/ofb/ofb.h | 2 - src/lib/stream/rc4/rc4.cpp | 9 ---- src/lib/stream/rc4/rc4.h | 2 - src/lib/stream/stream_cipher.cpp | 97 +++++++++++++++++++++++++++++++--------- src/lib/stream/stream_cipher.h | 23 +++++++--- 8 files changed, 93 insertions(+), 62 deletions(-) (limited to 'src/lib/stream') diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index 43609ba2d..c4552d459 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -9,16 +9,6 @@ namespace Botan { -CTR_BE* CTR_BE::make(const Spec& spec) - { - if(spec.algo_name() == "CTR-BE" && spec.arg_count() == 1) - { - if(auto c = BlockCipher::create(spec.arg(0))) - return new CTR_BE(c.release()); - } - return nullptr; - } - CTR_BE::CTR_BE(BlockCipher* ciph) : m_cipher(ciph), m_counter(m_cipher->parallel_bytes()), diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h index 385edac54..c4a28bd2b 100644 --- a/src/lib/stream/ctr/ctr.h +++ b/src/lib/stream/ctr/ctr.h @@ -38,8 +38,6 @@ class BOTAN_DLL CTR_BE final : public StreamCipher void clear() override; - static CTR_BE* make(const Spec& spec); - /** * @param cipher the block cipher to use */ diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 3337a0c14..0c23188d5 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -9,16 +9,6 @@ namespace Botan { -OFB* OFB::make(const Spec& spec) - { - if(spec.algo_name() == "OFB" && spec.arg_count() == 1) - { - if(auto c = BlockCipher::create(spec.arg(0))) - return new OFB(c.release()); - } - return nullptr; - } - OFB::OFB(BlockCipher* cipher) : m_cipher(cipher), m_buffer(m_cipher->block_size()), diff --git a/src/lib/stream/ofb/ofb.h b/src/lib/stream/ofb/ofb.h index 7d77bae7a..f8beb4956 100644 --- a/src/lib/stream/ofb/ofb.h +++ b/src/lib/stream/ofb/ofb.h @@ -38,8 +38,6 @@ class BOTAN_DLL OFB final : public StreamCipher void clear() override; - static OFB* make(const Spec& spec); - /** * @param cipher the block cipher to use */ diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index e5ea2e2b8..7200288b6 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -10,15 +10,6 @@ namespace Botan { -RC4* RC4::make(const Spec& spec) - { - if(spec.algo_name() == "RC4") - return new RC4(spec.arg_as_integer(0, 0)); - if(spec.algo_name() == "RC4_drop") - return new RC4(768); - return nullptr; - } - /* * Combine cipher stream with message */ diff --git a/src/lib/stream/rc4/rc4.h b/src/lib/stream/rc4/rc4.h index 82dd6097b..46715f7d2 100644 --- a/src/lib/stream/rc4/rc4.h +++ b/src/lib/stream/rc4/rc4.h @@ -33,8 +33,6 @@ class BOTAN_DLL RC4 final : public StreamCipher return Key_Length_Specification(1, 256); } - static RC4* make(const Spec& spec); - /** * @param skip skip this many initial bytes in the keystream */ diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 7c41722a0..74b9db9e7 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -1,12 +1,12 @@ /* * Stream Ciphers -* (C) 2015 Jack Lloyd +* (C) 2015,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include -#include +#include #if defined(BOTAN_HAS_CHACHA) #include @@ -32,44 +32,101 @@ #include #endif +#if defined(BOTAN_HAS_OPENSSL) + #include +#endif + namespace Botan { std::unique_ptr StreamCipher::create(const std::string& algo_spec, const std::string& provider) { - return std::unique_ptr(make_a(Botan::StreamCipher::Spec(algo_spec), provider)); - } - -std::vector StreamCipher::providers(const std::string& algo_spec) - { - return providers_of(StreamCipher::Spec(algo_spec)); - } + const SCAN_Name req(algo_spec); -StreamCipher::StreamCipher() {} -StreamCipher::~StreamCipher() {} +#if defined(BOTAN_HAS_CTR_BE) + if(req.algo_name() == "CTR-BE" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto c = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new CTR_BE(c.release())); + } + } +#endif #if defined(BOTAN_HAS_CHACHA) -BOTAN_REGISTER_T_1LEN(StreamCipher, ChaCha, 20); + if(req.algo_name() == "ChaCha") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new ChaCha(req.arg_as_integer(0, 20))); + } #endif #if defined(BOTAN_HAS_SALSA20) -BOTAN_REGISTER_T_NOARGS(StreamCipher, Salsa20); + if(req.algo_name() == "Salsa20") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new Salsa20); + } #endif #if defined(BOTAN_HAS_SHAKE_CIPHER) -BOTAN_REGISTER_NAMED_T(StreamCipher, "SHAKE-128", SHAKE_128, make_new_T); -#endif - -#if defined(BOTAN_HAS_CTR_BE) -BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make); + if(req.algo_name() == "SHAKE-128") + { + if(provider.empty() || provider == "base") + return std::unique_ptr(new SHAKE_128); + } #endif #if defined(BOTAN_HAS_OFB) -BOTAN_REGISTER_NAMED_T(StreamCipher, "OFB", OFB, OFB::make); + if(req.algo_name() == "OFB" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto c = BlockCipher::create(req.arg(0))) + return std::unique_ptr(new OFB(c.release())); + } + } #endif #if defined(BOTAN_HAS_RC4) -BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); + + if(req.algo_name() == "RC4") + { + const size_t skip = req.arg_as_integer(0, 0); +#if defined(BOTAN_HAS_OPENSSL) + if(provider.empty() || provider == "openssl") + { + return std::unique_ptr(make_openssl_rc4(skip)); + } #endif + if(provider.empty() || provider == "base") + { + return std::unique_ptr(new RC4(skip)); + } + } + +#endif + + return nullptr; + } + +//static +std::unique_ptr +StreamCipher::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto sc = StreamCipher::create(algo, provider)) + { + return sc; + } + throw Lookup_Error("Stream cipher", algo, provider); + } + +std::vector StreamCipher::providers(const std::string& algo_spec) + { + return probe_providers_of(algo_spec, {"base", "openssl"}); + } + } diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index 0cbdf3c65..7654bf427 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -9,7 +9,7 @@ #define BOTAN_STREAM_CIPHER_H__ #include -#include +#include namespace Botan { @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: - typedef SCAN_Name Spec; + virtual ~StreamCipher() {} /** * Create an instance based on a name @@ -28,8 +28,20 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * @param provider provider implementation to use * @return a null pointer if the algo/provider combination cannot be found */ - static std::unique_ptr create(const std::string& algo_spec, - const std::string& provider = ""); + static std::unique_ptr + create(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * Create an instance based on a name + * If provider is empty then best available is chosen. + * @param algo_spec algorithm name + * @param provider provider implementation to use + * Throws a Lookup_Error if the algo/provider combination cannot be found + */ + static std::unique_ptr + create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); /** * @return list of available providers for this algorithm, empty if not available @@ -109,9 +121,6 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * might also return "sse2", "avx2", "openssl", or some other arbitrary string. */ virtual std::string provider() const { return "base"; } - - StreamCipher(); - virtual ~StreamCipher(); }; } -- cgit v1.2.3 From df64fb318acbfee7911bee4fd021100f1d6532ed Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 17 Oct 2016 06:05:37 -0400 Subject: Remove alias logic from SCAN_Name This required taking a global lock and doing a map lookup each time an algorithm was requested (and so many times during a TLS handshake). --- src/lib/base/scan_name.cpp | 56 +----------------- src/lib/base/scan_name.h | 9 --- src/lib/block/block_cipher.cpp | 60 +++++++++---------- src/lib/hash/hash.cpp | 112 +++++++++++++++++++---------------- src/lib/mac/mac.cpp | 6 +- src/lib/modes/aead/aead.cpp | 6 ++ src/lib/modes/cipher_mode.cpp | 6 ++ src/lib/pk_pad/eme.cpp | 26 ++++---- src/lib/pk_pad/emsa.cpp | 52 ++++++++++------ src/lib/prov/openssl/openssl_rc4.cpp | 5 +- src/lib/stream/rc4/rc4.cpp | 5 +- src/lib/stream/stream_cipher.cpp | 7 ++- 12 files changed, 168 insertions(+), 182 deletions(-) (limited to 'src/lib/stream') diff --git a/src/lib/base/scan_name.cpp b/src/lib/base/scan_name.cpp index 76d9b1a17..d18296a78 100644 --- a/src/lib/base/scan_name.cpp +++ b/src/lib/base/scan_name.cpp @@ -52,13 +52,6 @@ std::string make_arg( return output; } -std::pair -deref_aliases(const std::pair& in) - { - return std::make_pair(in.first, - SCAN_Name::deref_alias(in.second)); - } - } SCAN_Name::SCAN_Name(std::string algo_spec, const std::string& extra) : SCAN_Name(algo_spec) @@ -78,8 +71,6 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; - algo_spec = SCAN_Name::deref_alias(algo_spec); - for(size_t i = 0; i != algo_spec.size(); ++i) { char c = algo_spec[i]; @@ -100,7 +91,7 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg else { if(accum.second != "") - name.push_back(deref_aliases(accum)); + name.push_back(accum); accum = std::make_pair(level, ""); } } @@ -109,7 +100,7 @@ SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg } if(accum.second != "") - name.push_back(deref_aliases(accum)); + name.push_back(accum); if(level != 0) throw Decoding_Error(decoding_error + "Missing close paren"); @@ -172,47 +163,4 @@ size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const return to_u32bit(m_args[i]); } -mutex_type SCAN_Name::g_alias_map_mutex; -std::map SCAN_Name::g_alias_map = { - { "3DES", "TripleDES" }, - { "ARC4", "RC4" }, - { "CAST5", "CAST-128" }, - { "DES-EDE", "TripleDES" }, - { "EME-OAEP", "OAEP" }, - { "EME-PKCS1-v1_5", "PKCS1v15" }, - { "EME1", "OAEP" }, - { "EMSA-PKCS1-v1_5", "EMSA_PKCS1" }, - { "EMSA-PSS", "PSSR" }, - { "EMSA2", "EMSA_X931" }, - { "EMSA3", "EMSA_PKCS1" }, - { "EMSA4", "PSSR" }, - { "GOST-34.11", "GOST-R-34.11-94" }, - { "MARK-4", "RC4(256)" }, - { "OMAC", "CMAC" }, - { "PSS-MGF1", "PSSR" }, - { "SHA-1", "SHA-160" }, - { "SHA1", "SHA-160" }, - { "X9.31", "EMSA2" } -}; - -void SCAN_Name::add_alias(const std::string& alias, const std::string& basename) - { - lock_guard_type lock(g_alias_map_mutex); - - if(g_alias_map.find(alias) == g_alias_map.end()) - g_alias_map[alias] = basename; - } - -std::string SCAN_Name::deref_alias(const std::string& alias) - { - lock_guard_type lock(g_alias_map_mutex); - - std::string name = alias; - - for(auto i = g_alias_map.find(name); i != g_alias_map.end(); i = g_alias_map.find(name)) - name = i->second; - - return name; - } - } diff --git a/src/lib/base/scan_name.h b/src/lib/base/scan_name.h index 981d54765..2587fb875 100644 --- a/src/lib/base/scan_name.h +++ b/src/lib/base/scan_name.h @@ -107,15 +107,6 @@ class BOTAN_DLL SCAN_Name std::string cipher_mode_pad() const { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; } - /* - * FIXME add doc - */ - static void add_alias(const std::string& alias, const std::string& basename); - - /* - * FIXME add doc - */ - static std::string deref_alias(const std::string& alias); private: static mutex_type g_alias_map_mutex; static std::map g_alias_map; diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index abfaf55ef..750d01821 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -88,8 +88,6 @@ std::unique_ptr BlockCipher::create(const std::string& algo, const std::string& provider) { - const SCAN_Name req(algo); - #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -110,145 +108,147 @@ BlockCipher::create(const std::string& algo, return nullptr; #if defined(BOTAN_HAS_AES) - if(req.algo_name() == "AES-128" && req.arg_count() == 0) + if(algo == "AES-128") { return std::unique_ptr(new AES_128); } - if(req.algo_name() == "AES-192" && req.arg_count() == 0) + if(algo == "AES-192") { return std::unique_ptr(new AES_192); } - if(req.algo_name() == "AES-256" && req.arg_count() == 0) + if(algo == "AES-256") { return std::unique_ptr(new AES_256); } #endif #if defined(BOTAN_HAS_SERPENT) - if(req.algo_name() == "Serpent" && req.arg_count() == 0) + if(algo == "Serpent") { return std::unique_ptr(new Serpent); } #endif #if defined(BOTAN_HAS_TWOFISH) - if(req.algo_name() == "Twofish" && req.arg_count() == 0) + if(algo == "Twofish") { return std::unique_ptr(new Twofish); } #endif #if defined(BOTAN_HAS_THREEFISH_512) - if(req.algo_name() == "Threefish-512" && req.arg_count() == 0) + if(algo == "Threefish-512") { return std::unique_ptr(new Threefish_512); } #endif #if defined(BOTAN_HAS_BLOWFISH) - if(req.algo_name() == "Blowfish" && req.arg_count() == 0) + if(algo == "Blowfish") { return std::unique_ptr(new Blowfish); } #endif #if defined(BOTAN_HAS_CAMELLIA) - if(req.algo_name() == "Camellia-128" && req.arg_count() == 0) + if(algo == "Camellia-128") { return std::unique_ptr(new Camellia_128); } - if(req.algo_name() == "Camellia-192" && req.arg_count() == 0) + if(algo == "Camellia-192") { return std::unique_ptr(new Camellia_192); } - if(req.algo_name() == "Camellia-256" && req.arg_count() == 0) + if(algo == "Camellia-256") { return std::unique_ptr(new Camellia_256); } #endif #if defined(BOTAN_HAS_DES) - if(req.algo_name() == "DES" && req.arg_count() == 0) + if(algo == "DES") { return std::unique_ptr(new DES); } - if(req.algo_name() == "DESX" && req.arg_count() == 0) + if(algo == "DESX") { return std::unique_ptr(new DESX); } - if(req.algo_name() == "TripleDES" && req.arg_count() == 0) + if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE") { return std::unique_ptr(new TripleDES); } #endif #if defined(BOTAN_HAS_NOEKEON) - if(req.algo_name() == "Noekeon" && req.arg_count() == 0) + if(algo == "Noekeon") { return std::unique_ptr(new Noekeon); } #endif #if defined(BOTAN_HAS_CAST) - if(req.algo_name() == "CAST-128" && req.arg_count() == 0) + if(algo == "CAST-128" || algo == "CAST5") { return std::unique_ptr(new CAST_128); } - if(req.algo_name() == "CAST-256" && req.arg_count() == 0) + if(algo == "CAST-256") { return std::unique_ptr(new CAST_256); } #endif -#if defined(BOTAN_HAS_GOST_28147_89) - if(req.algo_name() == "GOST-28147-89") - { - return std::unique_ptr(new GOST_28147_89(req.arg(0, "R3411_94_TestParam"))); - } -#endif - #if defined(BOTAN_HAS_IDEA) - if(req.algo_name() == "IDEA" && req.arg_count() == 0) + if(algo == "IDEA") { return std::unique_ptr(new IDEA); } #endif #if defined(BOTAN_HAS_KASUMI) - if(req.algo_name() == "KASUMI" && req.arg_count() == 0) + if(algo == "KASUMI") { return std::unique_ptr(new KASUMI); } #endif #if defined(BOTAN_HAS_MISTY1) - if(req.algo_name() == "MISTY1" && req.arg_count() == 0) + if(algo == "MISTY1") { return std::unique_ptr(new MISTY1); } #endif #if defined(BOTAN_HAS_SEED) - if(req.algo_name() == "SEED" && req.arg_count() == 0) + if(algo == "SEED") { return std::unique_ptr(new SEED); } #endif #if defined(BOTAN_HAS_XTEA) - if(req.algo_name() == "XTEA" && req.arg_count() == 0) + if(algo == "XTEA") { return std::unique_ptr(new XTEA); } #endif + const SCAN_Name req(algo); + +#if defined(BOTAN_HAS_GOST_28147_89) + if(req.algo_name() == "GOST-28147-89") + { + return std::unique_ptr(new GOST_28147_89(req.arg(0, "R3411_94_TestParam"))); + } +#endif + #if defined(BOTAN_HAS_CASCADE) if(req.algo_name() == "Cascade" && req.arg_count() == 2) { diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index dc95099b8..7a32ccede 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -89,8 +89,6 @@ namespace Botan { std::unique_ptr HashFunction::create(const std::string& algo_spec, const std::string& provider) { - const SCAN_Name req(algo_spec); - #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -102,52 +100,107 @@ std::unique_ptr HashFunction::create(const std::string& algo_spec, } #endif + // TODO: CommonCrypto hashes + if(provider.empty() == false && provider != "base") return nullptr; // unknown provider #if defined(BOTAN_HAS_SHA1) - if(req.algo_name() == "SHA-160") + if(algo_spec == "SHA-160" || + algo_spec == "SHA-1" || + algo_spec == "SHA1") { return std::unique_ptr(new SHA_160); } #endif #if defined(BOTAN_HAS_SHA2_32) - if(req.algo_name() == "SHA-224") + if(algo_spec == "SHA-224") { return std::unique_ptr(new SHA_224); } - if(req.algo_name() == "SHA-256") + if(algo_spec == "SHA-256") { return std::unique_ptr(new SHA_256); } #endif #if defined(BOTAN_HAS_SHA2_64) - if(req.algo_name() == "SHA-384") + if(algo_spec == "SHA-384") { return std::unique_ptr(new SHA_384); } - if(req.algo_name() == "SHA-512") + if(algo_spec == "SHA-512") { return std::unique_ptr(new SHA_512); } - if(req.algo_name() == "SHA-512-256") + if(algo_spec == "SHA-512-256") { return std::unique_ptr(new SHA_512_256); } #endif #if defined(BOTAN_HAS_RIPEMD_160) - if(req.algo_name() == "RIPEMD-160") + if(algo_spec == "RIPEMD-160") { return std::unique_ptr(new RIPEMD_160); } #endif +#if defined(BOTAN_HAS_WHIRLPOOL) + if(algo_spec == "Whirlpool") + { + return std::unique_ptr(new Whirlpool); + } +#endif + +#if defined(BOTAN_HAS_MD5) + if(algo_spec == "MD5") + { + return std::unique_ptr(new MD5); + } +#endif + +#if defined(BOTAN_HAS_MD4) + if(algo_spec == "MD4") + { + return std::unique_ptr(new MD4); + } +#endif + +#if defined(BOTAN_HAS_GOST_34_11) + if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") + { + return std::unique_ptr(new GOST_34_11); + } +#endif + +#if defined(BOTAN_HAS_ADLER32) + if(algo_spec == "Adler32") + { + return std::unique_ptr(new Adler32); + } +#endif + +#if defined(BOTAN_HAS_CRC24) + if(algo_spec == "CRC24") + { + return std::unique_ptr(new CRC24); + } +#endif + +#if defined(BOTAN_HAS_CRC32) + if(algo_spec == "CRC32") + { + return std::unique_ptr(new CRC32); + } +#endif + + const SCAN_Name req(algo_spec); + #if defined(BOTAN_HAS_TIGER) if(req.algo_name() == "Tiger") { @@ -226,47 +279,6 @@ std::unique_ptr HashFunction::create(const std::string& algo_spec, } #endif -#if defined(BOTAN_HAS_MD5) - if(req.algo_name() == "MD5") - { - return std::unique_ptr(new MD5); - } -#endif - -#if defined(BOTAN_HAS_MD4) - if(req.algo_name() == "MD4") - { - return std::unique_ptr(new MD4); - } -#endif - -#if defined(BOTAN_HAS_GOST_34_11) - if(req.algo_name() == "GOST-R-34.11-94") - { - return std::unique_ptr(new GOST_34_11); - } -#endif - -#if defined(BOTAN_HAS_ADLER32) - if(req.algo_name() == "Adler32") - { - return std::unique_ptr(new Adler32); - } -#endif - -#if defined(BOTAN_HAS_CRC24) - if(req.algo_name() == "CRC24") - { - return std::unique_ptr(new CRC24); - } -#endif - -#if defined(BOTAN_HAS_CRC32) - if(req.algo_name() == "CRC32") - { - return std::unique_ptr(new CRC32); - } -#endif return nullptr; } diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index 919ce959d..70807b39f 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -67,15 +67,15 @@ MessageAuthenticationCode::create(const std::string& algo_spec, if(provider.empty() || provider == "base") { return std::unique_ptr( - new SipHash(req.arg_as_integer(0, 2), - req.arg_as_integer(1, 4))); + new SipHash(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4))); } } #endif #if defined(BOTAN_HAS_CMAC) - if(req.algo_name() == "CMAC" && req.arg_count() == 1) + if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) { + // TODO: OpenSSL CMAC if(provider.empty() || provider == "base") { if(auto bc = BlockCipher::create(req.arg(0))) diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp index 033dad94e..1b7b78be7 100644 --- a/src/lib/modes/aead/aead.cpp +++ b/src/lib/modes/aead/aead.cpp @@ -76,6 +76,12 @@ AEAD_Mode* get_aead(const std::string& algo, Cipher_Dir dir) #if defined(BOTAN_HAS_BLOCK_CIPHER) SCAN_Name req(algo); + + if(req.arg_count() == 0) + { + return nullptr; + } + std::unique_ptr bc(BlockCipher::create(req.arg(0))); if(!bc) diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp index df2944323..d622e7754 100644 --- a/src/lib/modes/cipher_mode.cpp +++ b/src/lib/modes/cipher_mode.cpp @@ -79,6 +79,12 @@ Cipher_Mode* get_cipher_mode(const std::string& algo, Cipher_Dir direction) #if defined(BOTAN_HAS_BLOCK_CIPHER) SCAN_Name spec(algo); + + if(spec.arg_count() == 0) + { + return nullptr; + } + std::unique_ptr bc(BlockCipher::create(spec.arg(0))); if(!bc) diff --git a/src/lib/pk_pad/eme.cpp b/src/lib/pk_pad/eme.cpp index fa569d8e4..eab9862af 100644 --- a/src/lib/pk_pad/eme.cpp +++ b/src/lib/pk_pad/eme.cpp @@ -24,10 +24,22 @@ namespace Botan { EME* get_eme(const std::string& algo_spec) { - SCAN_Name req(algo_spec); +#if defined(BOTAN_HAS_EME_RAW) + if(algo_spec == "Raw") + return new EME_Raw; +#endif + +#if defined(BOTAN_HAS_EME_PKCS1v15) + if(algo_spec == "PKCS1v15" || algo_spec == "EME-PKCS1-v1_5") + return new EME_PKCS1v15; +#endif #if defined(BOTAN_HAS_EME_OAEP) - if(req.algo_name() == "OAEP" && req.arg_count_between(1, 2)) + SCAN_Name req(algo_spec); + + if(req.algo_name() == "OAEP" || + req.algo_name() == "EME-OAEP" || + req.algo_name() == "EME1") { if(req.arg_count() == 1 || (req.arg_count() == 2 && req.arg(1) == "MGF1")) @@ -38,16 +50,6 @@ EME* get_eme(const std::string& algo_spec) } #endif -#if defined(BOTAN_HAS_EME_PKCS1v15) - if(req.algo_name() == "PKCS1v15" && req.arg_count() == 0) - return new EME_PKCS1v15; -#endif - -#if defined(BOTAN_HAS_EME_RAW) - if(req.algo_name() == "Raw" && req.arg_count() == 0) - return new EME_Raw; -#endif - throw Algorithm_Not_Found(algo_spec); } diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp index c091319e2..719863557 100644 --- a/src/lib/pk_pad/emsa.cpp +++ b/src/lib/pk_pad/emsa.cpp @@ -44,42 +44,58 @@ EMSA* get_emsa(const std::string& algo_spec) #endif #if defined(BOTAN_HAS_EMSA_PKCS1) - if(req.algo_name() == "EMSA_PKCS1" && req.arg_count() == 1) + if(req.algo_name() == "EMSA_PKCS1" || + req.algo_name() == "EMSA-PKCS1-v1_5" || + req.algo_name() == "EMSA3") { - if(req.arg(0) == "Raw") + if(req.arg_count() == 1) { - return new EMSA_PKCS1v15_Raw; - } - else - { - if(auto hash = HashFunction::create(req.arg(0))) + if(req.arg(0) == "Raw") { - return new EMSA_PKCS1v15(hash.release()); + return new EMSA_PKCS1v15_Raw; + } + else + { + if(auto hash = HashFunction::create(req.arg(0))) + { + return new EMSA_PKCS1v15(hash.release()); + } } } } #endif #if defined(BOTAN_HAS_EMSA_PSSR) - if(req.algo_name() == "PSSR") + if(req.algo_name() == "PSSR" || + req.algo_name() == "EMSA-PSS" || + req.algo_name() == "PSS-MGF1" || + req.algo_name() == "EMSA4") { - if(req.arg(1, "MGF1") != "MGF1") - return nullptr; // not supported - - if(auto h = HashFunction::create(req.arg(0))) + if(req.arg_count_between(2, 3)) { - const size_t salt_size = req.arg_as_integer(2, h->output_length()); - return new PSSR(h.release(), salt_size); + if(req.arg(1, "MGF1") != "MGF1") + return nullptr; // not supported + + if(auto h = HashFunction::create(req.arg(0))) + { + const size_t salt_size = req.arg_as_integer(2, h->output_length()); + return new PSSR(h.release(), salt_size); + } } } #endif #if defined(BOTAN_HAS_EMSA_X931) - if(req.algo_name() == "EMSA_X931" && req.arg_count() == 1) + if(req.algo_name() == "EMSA_X931" || + req.algo_name() == "EMSA2" || + req.algo_name() == "X9.31") { - if(auto hash = HashFunction::create(req.arg(0))) + if(req.arg_count() == 1) { - return new EMSA_X931(hash.release()); + if(auto hash = HashFunction::create(req.arg(0))) + { + return new EMSA_X931(hash.release()); + } } } #endif diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp index a9b793678..b43d801ed 100644 --- a/src/lib/prov/openssl/openssl_rc4.cpp +++ b/src/lib/prov/openssl/openssl_rc4.cpp @@ -48,9 +48,10 @@ class OpenSSL_RC4 : public StreamCipher explicit OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); } ~OpenSSL_RC4() { clear(); } - void set_iv(const byte*, size_t) override + void set_iv(const byte*, size_t len) override { - throw Exception("RC4 does not support an IV"); + if(len > 0) + throw Exception("RC4 does not support an IV"); } void seek(u64bit) override diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 7200288b6..47dc1ce29 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -27,9 +27,10 @@ void RC4::cipher(const byte in[], byte out[], size_t length) m_position += length; } -void RC4::set_iv(const byte*, size_t) +void RC4::set_iv(const byte*, size_t length) { - throw Exception("RC4 does not support an IV"); + if(length > 0) + throw Exception("RC4 does not support an IV"); } /* diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 74b9db9e7..4b27caafe 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -91,9 +91,12 @@ std::unique_ptr StreamCipher::create(const std::string& algo_spec, #if defined(BOTAN_HAS_RC4) - if(req.algo_name() == "RC4") + if(req.algo_name() == "RC4" || + req.algo_name() == "ARC4" || + req.algo_name() == "MARK-4") { - const size_t skip = req.arg_as_integer(0, 0); + const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0); + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { -- cgit v1.2.3