diff options
Diffstat (limited to 'src')
38 files changed, 193 insertions, 253 deletions
diff --git a/src/lib/algo_base/algo_registry.h b/src/lib/algo_base/algo_registry.h index 8f3bebec7..80eff47be 100644 --- a/src/lib/algo_base/algo_registry.h +++ b/src/lib/algo_base/algo_registry.h @@ -34,8 +34,8 @@ class Algo_Registry void add(const std::string& name, const std::string& provider, maker_fn fn) { std::unique_lock<std::mutex> lock(m_mutex); - // TODO: check for duplicated registrations - m_maker_fns[name][provider] = fn; + if(!m_maker_fns[name][provider]) + m_maker_fns[name][provider] = fn; } T* make(const Spec& spec, const std::string& provider = "") diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index 420b92cdb..44d4d0bed 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -8,7 +8,6 @@ #include <botan/internal/block_utils.h> #include <botan/lion.h> #include <botan/parsing.h> -#include <botan/libstate.h> namespace Botan { @@ -18,14 +17,13 @@ Lion* make_lion(const BlockCipher::Spec& spec) { if(spec.arg_count_between(2, 3)) { - Algorithm_Factory& af = global_state().algorithm_factory(); - const HashFunction* hash = af.prototype_hash_function(spec.arg(0)); - const StreamCipher* stream_cipher = af.prototype_stream_cipher(spec.arg(1)); + std::unique_ptr<HashFunction> hash(Algo_Registry<HashFunction>::global_registry().make(spec.arg(0))); + std::unique_ptr<StreamCipher> stream(Algo_Registry<StreamCipher>::global_registry().make(spec.arg(1))); - if(hash && stream_cipher) + if(hash && stream) { const size_t block_size = spec.arg_as_integer(2, 1024); - return new Lion(hash->clone(), stream_cipher->clone(), block_size); + return new Lion(hash.release(), stream.release(), block_size); } } return nullptr; diff --git a/src/lib/constructs/pbes2/pbes2.cpp b/src/lib/constructs/pbes2/pbes2.cpp index 8c2348408..811806891 100644 --- a/src/lib/constructs/pbes2/pbes2.cpp +++ b/src/lib/constructs/pbes2/pbes2.cpp @@ -6,6 +6,8 @@ */ #include <botan/pbes2.h> +#include <botan/algo_registry.h> +#include <botan/cipher_mode.h> #include <botan/pbkdf2.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> @@ -13,13 +15,8 @@ #include <botan/alg_id.h> #include <botan/oids.h> #include <botan/rng.h> -#include <botan/cbc.h> #include <algorithm> -#if defined(BOTAN_HAS_AEAD_GCM) - #include <botan/gcm.h> -#endif - namespace Botan { namespace { @@ -70,8 +67,7 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, std::chrono::milliseconds msec, const std::string& cipher, const std::string& digest, - RandomNumberGenerator& rng, - Algorithm_Factory& af) + RandomNumberGenerator& rng) { const std::string prf = "HMAC(" + digest + ")"; @@ -81,18 +77,12 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, const secure_vector<byte> salt = rng.random_vec(12); - std::unique_ptr<Keyed_Transform> enc; - - if(cipher_spec[1] == "CBC") - enc.reset(new CBC_Encryption(af.make_block_cipher(cipher_spec[0]), new PKCS7_Padding)); -#if defined(BOTAN_HAS_AEAD_GCM) - else if(cipher_spec[1] == "GCM") - enc.reset(new GCM_Encryption(af.make_block_cipher(cipher_spec[0]))); -#endif - else + if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); - PKCS5_PBKDF2 pbkdf(af.make_mac(prf)); + std::unique_ptr<Keyed_Transform> enc(get_cipher_mode(cipher, ENCRYPTION)); + + PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); const size_t key_length = enc->key_spec().maximum_keylength(); size_t iterations = 0; @@ -116,8 +106,7 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, secure_vector<byte> pbes2_decrypt(const secure_vector<byte>& key_bits, const std::string& passphrase, - const std::vector<byte>& params, - Algorithm_Factory& af) + const std::vector<byte>& params) { AlgorithmIdentifier kdf_algo, enc_algo; @@ -152,6 +141,8 @@ pbes2_decrypt(const secure_vector<byte>& key_bits, const std::vector<std::string> cipher_spec = split_on(cipher, '/'); if(cipher_spec.size() != 2) throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); + if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") + throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); if(salt.size() < 8) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); @@ -159,18 +150,10 @@ pbes2_decrypt(const secure_vector<byte>& key_bits, secure_vector<byte> iv; BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end(); - PKCS5_PBKDF2 pbkdf(af.make_mac(OIDS::lookup(prf_algo.oid))); - - std::unique_ptr<Keyed_Transform> dec; + const std::string prf = OIDS::lookup(prf_algo.oid); + PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); - if(cipher_spec[1] == "CBC") - dec.reset(new CBC_Decryption(af.make_block_cipher(cipher_spec[0]), new PKCS7_Padding)); -#if defined(BOTAN_HAS_AEAD_GCM) - else if(cipher_spec[1] == "GCM") - dec.reset(new GCM_Decryption(af.make_block_cipher(cipher_spec[0]))); -#endif - else - throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); + std::unique_ptr<Keyed_Transform> dec(get_cipher_mode(cipher, DECRYPTION)); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); diff --git a/src/lib/constructs/pbes2/pbes2.h b/src/lib/constructs/pbes2/pbes2.h index 7d73795dc..3aa7d1159 100644 --- a/src/lib/constructs/pbes2/pbes2.h +++ b/src/lib/constructs/pbes2/pbes2.h @@ -30,8 +30,7 @@ BOTAN_DLL pbes2_encrypt(const secure_vector<byte>& key_bits, std::chrono::milliseconds msec, const std::string& cipher, const std::string& digest, - RandomNumberGenerator& rng, - Algorithm_Factory& af); + RandomNumberGenerator& rng); /** * Decrypt a PKCS #5 v2.0 encrypted stream @@ -42,8 +41,7 @@ BOTAN_DLL pbes2_encrypt(const secure_vector<byte>& key_bits, secure_vector<byte> BOTAN_DLL pbes2_decrypt(const secure_vector<byte>& key_bits, const std::string& passphrase, - const std::vector<byte>& params, - Algorithm_Factory& af); + const std::vector<byte>& params); } diff --git a/src/lib/constructs/rfc3394/rfc3394.cpp b/src/lib/constructs/rfc3394/rfc3394.cpp index ee1cc1dd8..6c8b62219 100644 --- a/src/lib/constructs/rfc3394/rfc3394.cpp +++ b/src/lib/constructs/rfc3394/rfc3394.cpp @@ -6,7 +6,7 @@ */ #include <botan/rfc3394.h> -#include <botan/algo_factory.h> +#include <botan/algo_registry.h> #include <botan/block_cipher.h> #include <botan/loadstor.h> #include <botan/exceptn.h> @@ -16,15 +16,15 @@ namespace Botan { namespace { -BlockCipher* make_aes(size_t keylength, - Algorithm_Factory& af) +BlockCipher* make_aes(size_t keylength) { + auto& block_ciphers = Algo_Registry<BlockCipher>::global_registry(); if(keylength == 16) - return af.make_block_cipher("AES-128"); + return block_ciphers.make("AES-128"); else if(keylength == 24) - return af.make_block_cipher("AES-192"); + return block_ciphers.make("AES-192"); else if(keylength == 32) - return af.make_block_cipher("AES-256"); + return block_ciphers.make("AES-256"); else throw std::invalid_argument("Bad KEK length for NIST keywrap"); } @@ -32,13 +32,12 @@ BlockCipher* make_aes(size_t keylength, } secure_vector<byte> rfc3394_keywrap(const secure_vector<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af) + const SymmetricKey& kek) { if(key.size() % 8 != 0) throw std::invalid_argument("Bad input key size for NIST key wrap"); - std::unique_ptr<BlockCipher> aes(make_aes(kek.length(), af)); + std::unique_ptr<BlockCipher> aes(make_aes(kek.length())); aes->set_key(kek); const size_t n = key.size() / 8; @@ -74,13 +73,12 @@ secure_vector<byte> rfc3394_keywrap(const secure_vector<byte>& key, } secure_vector<byte> rfc3394_keyunwrap(const secure_vector<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af) + const SymmetricKey& kek) { if(key.size() < 16 || key.size() % 8 != 0) throw std::invalid_argument("Bad input key size for NIST key unwrap"); - std::unique_ptr<BlockCipher> aes(make_aes(kek.length(), af)); + std::unique_ptr<BlockCipher> aes(make_aes(kek.length())); aes->set_key(kek); const size_t n = (key.size() - 8) / 8; diff --git a/src/lib/constructs/rfc3394/rfc3394.h b/src/lib/constructs/rfc3394/rfc3394.h index 9800bbab1..fab6bc3cb 100644 --- a/src/lib/constructs/rfc3394/rfc3394.h +++ b/src/lib/constructs/rfc3394/rfc3394.h @@ -12,20 +12,16 @@ namespace Botan { -class Algorithm_Factory; - /** * Encrypt a key under a key encryption key using the algorithm * described in RFC 3394 * * @param key the plaintext key to encrypt * @param kek the key encryption key -* @param af an algorithm factory * @return key encrypted under kek */ secure_vector<byte> BOTAN_DLL rfc3394_keywrap(const secure_vector<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af); + const SymmetricKey& kek); /** * Decrypt a key under a key encryption key using the algorithm @@ -37,8 +33,7 @@ secure_vector<byte> BOTAN_DLL rfc3394_keywrap(const secure_vector<byte>& key, * @return key decrypted under kek */ secure_vector<byte> BOTAN_DLL rfc3394_keyunwrap(const secure_vector<byte>& key, - const SymmetricKey& kek, - Algorithm_Factory& af); + const SymmetricKey& kek); } diff --git a/src/lib/engine/core_engine/lookup_mac.cpp b/src/lib/engine/core_engine/lookup_mac.cpp index d5e16cf44..1336cee5f 100644 --- a/src/lib/engine/core_engine/lookup_mac.cpp +++ b/src/lib/engine/core_engine/lookup_mac.cpp @@ -7,31 +7,7 @@ #include <botan/internal/core_engine.h> #include <botan/scan_name.h> -#include <botan/algo_factory.h> - -#if defined(BOTAN_HAS_CBC_MAC) - #include <botan/cbc_mac.h> -#endif - -#if defined(BOTAN_HAS_CMAC) - #include <botan/cmac.h> -#endif - -#if defined(BOTAN_HAS_HMAC) - #include <botan/hmac.h> -#endif - -#if defined(BOTAN_HAS_POLY1305) - #include <botan/poly1305.h> -#endif - -#if defined(BOTAN_HAS_SIPHASH) - #include <botan/siphash.h> -#endif - -#if defined(BOTAN_HAS_ANSI_X919_MAC) - #include <botan/x919_mac.h> -#endif +#include <botan/algo_registry.h> namespace Botan { @@ -40,38 +16,10 @@ namespace Botan { */ MessageAuthenticationCode* Core_Engine::find_mac(const SCAN_Name& request, - Algorithm_Factory& af) const + Algorithm_Factory&) const { -#if defined(BOTAN_HAS_HMAC) - if(request.algo_name() == "HMAC" && request.arg_count() == 1) - return new HMAC(af.make_hash_function(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_CMAC) - if(request.algo_name() == "CMAC" && request.arg_count() == 1) - return new CMAC(af.make_block_cipher(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_POLY1305) - if(request.algo_name() == "Poly1305") - return new Poly1305; -#endif - -#if defined(BOTAN_HAS_SIPHASH) - if(request.algo_name() == "SipHash") - return new SipHash(request.arg_as_integer(0, 2), - request.arg_as_integer(1, 4)); -#endif - -#if defined(BOTAN_HAS_CBC_MAC) - if(request.algo_name() == "CBC-MAC" && request.arg_count() == 1) - return new CBC_MAC(af.make_block_cipher(request.arg(0))); -#endif - -#if defined(BOTAN_HAS_ANSI_X919_MAC) - if(request.algo_name() == "X9.19-MAC" && request.arg_count() == 0) - return new ANSI_X919_MAC(af.make_block_cipher("DES")); -#endif + if(MessageAuthenticationCode* m = Algo_Registry<MessageAuthenticationCode>::global_registry().make(request, "builtin")) + return m; return nullptr; } diff --git a/src/lib/engine/core_engine/lookup_stream.cpp b/src/lib/engine/core_engine/lookup_stream.cpp index a0fee6978..068db7def 100644 --- a/src/lib/engine/core_engine/lookup_stream.cpp +++ b/src/lib/engine/core_engine/lookup_stream.cpp @@ -7,27 +7,7 @@ #include <botan/internal/core_engine.h> #include <botan/scan_name.h> -#include <botan/algo_factory.h> - -#if defined(BOTAN_HAS_OFB) - #include <botan/ofb.h> -#endif - -#if defined(BOTAN_HAS_CTR_BE) - #include <botan/ctr.h> -#endif - -#if defined(BOTAN_HAS_RC4) - #include <botan/rc4.h> -#endif - -#if defined(BOTAN_HAS_CHACHA) - #include <botan/chacha.h> -#endif - -#if defined(BOTAN_HAS_SALSA20) - #include <botan/salsa20.h> -#endif +#include <botan/algo_registry.h> namespace Botan { @@ -36,40 +16,10 @@ namespace Botan { */ StreamCipher* Core_Engine::find_stream_cipher(const SCAN_Name& request, - Algorithm_Factory& af) const + Algorithm_Factory&) const { -#if defined(BOTAN_HAS_OFB) - if(request.algo_name() == "OFB" && request.arg_count() == 1) - { - if(auto proto = af.prototype_block_cipher(request.arg(0))) - return new OFB(proto->clone()); - } -#endif - -#if defined(BOTAN_HAS_CTR_BE) - if(request.algo_name() == "CTR-BE" && request.arg_count() == 1) - { - if(auto proto = af.prototype_block_cipher(request.arg(0))) - return new CTR_BE(proto->clone()); - } -#endif - -#if defined(BOTAN_HAS_RC4) - if(request.algo_name() == "RC4") - return new RC4(request.arg_as_integer(0, 0)); - if(request.algo_name() == "RC4_drop") - return new RC4(768); -#endif - -#if defined(BOTAN_HAS_CHACHA) - if(request.algo_name() == "ChaCha") - return new ChaCha; -#endif - -#if defined(BOTAN_HAS_SALSA20) - if(request.algo_name() == "Salsa20") - return new Salsa20; -#endif + if(StreamCipher* c = Algo_Registry<StreamCipher>::global_registry().make(request, "builtin")) + return c; return nullptr; } diff --git a/src/lib/filters/algo_filt.cpp b/src/lib/filters/algo_filt.cpp index 924977715..2cbb3acff 100644 --- a/src/lib/filters/algo_filt.cpp +++ b/src/lib/filters/algo_filt.cpp @@ -6,7 +6,7 @@ */ #include <botan/filters.h> -#include <botan/libstate.h> +#include <botan/algo_registry.h> #include <algorithm> namespace Botan { @@ -36,8 +36,7 @@ StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : buffer(DEFAULT_BUFFERSIZE) { - Algorithm_Factory& af = global_state().algorithm_factory(); - m_cipher.reset(af.make_stream_cipher(sc_name)); + m_cipher.reset(Algo_Registry<StreamCipher>::global_registry().make(sc_name)); } /* @@ -47,8 +46,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) : buffer(DEFAULT_BUFFERSIZE) { - Algorithm_Factory& af = global_state().algorithm_factory(); - m_cipher.reset(af.make_stream_cipher(sc_name)); + m_cipher.reset(Algo_Registry<StreamCipher>::global_registry().make(sc_name)); m_cipher->set_key(key); } @@ -82,8 +80,7 @@ Hash_Filter::Hash_Filter(const std::string& algo_spec, size_t len) : OUTPUT_LENGTH(len) { - Algorithm_Factory& af = global_state().algorithm_factory(); - m_hash.reset(af.make_hash_function(algo_spec)); + m_hash.reset(Algo_Registry<HashFunction>::global_registry().make(sc_name)); } /* @@ -104,8 +101,7 @@ void Hash_Filter::end_msg() MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : OUTPUT_LENGTH(len) { - Algorithm_Factory& af = global_state().algorithm_factory(); - m_mac.reset(af.make_mac(mac_name)); + m_mac.reset(Algo_Registry<MessageAuthenticationCode>::global_registry().make(mac_name)); } /* @@ -114,8 +110,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) : OUTPUT_LENGTH(len) { - Algorithm_Factory& af = global_state().algorithm_factory(); - m_mac.reset(af.make_mac(mac_name)); + m_mac.reset(Algo_Registry<MessageAuthenticationCode>::global_registry().make(mac_name)); m_mac->set_key(key); } diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp index 820e5234c..a0ee580ab 100644 --- a/src/lib/kdf/kdf.cpp +++ b/src/lib/kdf/kdf.cpp @@ -56,11 +56,6 @@ KDF* get_kdf(const std::string& algo_spec) return new TLS_PRF; #endif -#if defined(BOTAN_HAS_TLS_V10_PRF) - if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) - return new TLS_PRF; -#endif - #if defined(BOTAN_HAS_TLS_V12_PRF) if(request.algo_name() == "TLS-12-PRF" && request.arg_count() == 1) return new TLS_12_PRF(af.make_mac("HMAC(" + request.arg(0) + ")")); diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index e8fc394fa..d893b922f 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -5,12 +5,20 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/cbc_mac.h> -#include <botan/internal/xor_buf.h> -#include <algorithm> namespace Botan { +CBC_MAC* CBC_MAC::make(const Spec& spec) + { + if(spec.arg_count() == 1) + return new CBC_MAC(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); + return nullptr; + } + +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CBC-MAC", CBC_MAC, CBC_MAC::make); + /* * Update an CBC-MAC Calculation */ diff --git a/src/lib/mac/cbc_mac/cbc_mac.h b/src/lib/mac/cbc_mac/cbc_mac.h index 10c8a0da4..722658174 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.h +++ b/src/lib/mac/cbc_mac/cbc_mac.h @@ -34,6 +34,7 @@ class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode */ CBC_MAC(BlockCipher* cipher); + static CBC_MAC* make(const Spec& spec); private: void add_data(const byte[], size_t); void final_result(byte[]); diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index 2e90e9002..a77673138 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -5,12 +5,20 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/cmac.h> -#include <botan/loadstor.h> -#include <botan/internal/xor_buf.h> namespace Botan { +CMAC* CMAC::make(const Spec& spec) + { + if(spec.arg_count() == 1) + return new CMAC(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); + return nullptr; + } + +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "CMAC", CMAC, CMAC::make); + /* * Perform CMAC's multiplication in GF(2^n) */ diff --git a/src/lib/mac/cmac/cmac.h b/src/lib/mac/cmac/cmac.h index 491a081a4..f90e5d40c 100644 --- a/src/lib/mac/cmac/cmac.h +++ b/src/lib/mac/cmac/cmac.h @@ -42,6 +42,8 @@ class BOTAN_DLL CMAC : public MessageAuthenticationCode */ CMAC(BlockCipher* cipher); + static CMAC* make(const Spec& spec); + CMAC(const CMAC&) = delete; CMAC& operator=(const CMAC&) = delete; private: diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 625fd122e..12525f088 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -6,11 +6,20 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/hmac.h> -#include <botan/internal/xor_buf.h> namespace Botan { +HMAC* HMAC::make(const Spec& spec) + { + if(spec.arg_count() == 1) + return new HMAC(Algo_Registry<HashFunction>::global_registry().make(spec.arg(0))); + return nullptr; + } + +BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make); + /* * Update a HMAC Calculation */ diff --git a/src/lib/mac/hmac/hmac.h b/src/lib/mac/hmac/hmac.h index b6311d741..6b01eb365 100644 --- a/src/lib/mac/hmac/hmac.h +++ b/src/lib/mac/hmac/hmac.h @@ -36,6 +36,8 @@ class BOTAN_DLL HMAC : public MessageAuthenticationCode */ HMAC(HashFunction* hash); + static HMAC* make(const Spec& spec); + HMAC(const HMAC&) = delete; HMAC& operator=(const HMAC&) = delete; private: diff --git a/src/lib/mac/info.txt b/src/lib/mac/info.txt index d991577f7..871e415ee 100644 --- a/src/lib/mac/info.txt +++ b/src/lib/mac/info.txt @@ -1,3 +1,11 @@ <requires> algo_base </requires> + +<header:public> +mac.h +</header:public> + +<header:internal> +mac_utils.h +</header:internal> diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index e472e4d0b..2ee971b90 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -10,6 +10,7 @@ #include <botan/buf_comp.h> #include <botan/sym_algo.h> +#include <botan/scan_name.h> #include <string> namespace Botan { @@ -39,6 +40,8 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, * @return name of this algorithm */ virtual std::string name() const = 0; + + typedef SCAN_Name Spec; }; } diff --git a/src/lib/mac/poly1305/poly1305.cpp b/src/lib/mac/poly1305/poly1305.cpp index 8000ebbd8..8cf42abbb 100644 --- a/src/lib/mac/poly1305/poly1305.cpp +++ b/src/lib/mac/poly1305/poly1305.cpp @@ -5,11 +5,14 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/poly1305.h> #include <botan/internal/poly1305_donna.h> namespace Botan { +BOTAN_REGISTER_MAC_NOARGS(Poly1305); + void Poly1305::clear() { zap(m_poly); @@ -17,7 +20,7 @@ void Poly1305::clear() m_buf_pos = 0; } -void Poly1305::key_schedule(const byte key[], size_t key_len) +void Poly1305::key_schedule(const byte key[], size_t) { m_buf_pos = 0; m_buf.resize(16); diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp index bc242d4ac..3fafb35a9 100644 --- a/src/lib/mac/siphash/siphash.cpp +++ b/src/lib/mac/siphash/siphash.cpp @@ -5,13 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/siphash.h> -#include <botan/rotate.h> -#include <botan/loadstor.h> -#include <botan/internal/xor_buf.h> namespace Botan { +BOTAN_REGISTER_NAMED_T_2LEN(MessageAuthenticationCode, SipHash, "SipHash", "builtin", 2, 4); + namespace { void SipRounds(u64bit M, secure_vector<u64bit>& V, size_t r) diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index 4378a432f..31fda319b 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -5,12 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/mac_utils.h> #include <botan/x919_mac.h> -#include <botan/internal/xor_buf.h> -#include <algorithm> namespace Botan { +BOTAN_REGISTER_MAC_NAMED_NOARGS(ANSI_X919_MAC, "X9.19-MAC"); + /* * Update an ANSI X9.19 MAC Calculation */ @@ -81,17 +82,17 @@ std::string ANSI_X919_MAC::name() const MessageAuthenticationCode* ANSI_X919_MAC::clone() const { - return new ANSI_X919_MAC(m_des1->clone()); + return new ANSI_X919_MAC; } /* * ANSI X9.19 MAC Constructor */ -ANSI_X919_MAC::ANSI_X919_MAC(BlockCipher* cipher) : - m_des1(cipher), m_des2(m_des1->clone()), m_state(8), m_position(0) +ANSI_X919_MAC::ANSI_X919_MAC() : m_state(8), m_position(0) { - if(cipher->name() != "DES") - throw Invalid_Argument("ANSI X9.19 MAC only supports DES"); + auto& ciphers = Algo_Registry<BlockCipher>::global_registry(); + m_des1.reset(ciphers.make(BlockCipher::Spec("DES"), "")); + m_des2.reset(m_des1->clone()); } } diff --git a/src/lib/mac/x919_mac/x919_mac.h b/src/lib/mac/x919_mac/x919_mac.h index 35553c544..7b7d7d88b 100644 --- a/src/lib/mac/x919_mac/x919_mac.h +++ b/src/lib/mac/x919_mac/x919_mac.h @@ -30,10 +30,7 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode return Key_Length_Specification(8, 16, 8); } - /** - * @param cipher the underlying block cipher to use - */ - ANSI_X919_MAC(BlockCipher* cipher); + ANSI_X919_MAC(); ANSI_X919_MAC(const ANSI_X919_MAC&) = delete; ANSI_X919_MAC& operator=(const ANSI_X919_MAC&) = delete; diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp index e54553d16..1fb27f2e0 100644 --- a/src/lib/modes/cbc/cbc.cpp +++ b/src/lib/modes/cbc/cbc.cpp @@ -14,17 +14,16 @@ namespace Botan { template<typename CBC_T, typename CTS_T> Transform* make_cbc_mode(const Transform::Spec& spec) { - Algorithm_Factory& af = global_state().algorithm_factory(); - const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0)); + std::unique_ptr<BlockCipher> bc(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); if(bc) { const std::string padding = spec.arg(1, "PKCS7"); if(padding == "CTS") - return new CTS_T(bc->clone()); + return new CTS_T(bc.release()); else - return new CBC_T(bc->clone(), get_bc_pad(padding)); + return new CBC_T(bc.release(), get_bc_pad(padding)); } return nullptr; diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp index 1db272d12..6318671ca 100644 --- a/src/lib/modes/ecb/ecb.cpp +++ b/src/lib/modes/ecb/ecb.cpp @@ -13,11 +13,10 @@ namespace Botan { template<typename T> Transform* make_ecb_mode(const Transform::Spec& spec) { - Algorithm_Factory& af = global_state().algorithm_factory(); - const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0)); - BlockCipherModePaddingMethod* pad = get_bc_pad(spec.arg(1, "NoPadding")); + std::unique_ptr<BlockCipher> bc(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); + std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(spec.arg(1, "NoPadding"))); if(bc && pad) - return new T(bc->clone(), pad); + return new T(bc.release(), pad.release()); return nullptr; } diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index 0333403a3..70c996428 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -11,7 +11,6 @@ #include <botan/cipher_mode.h> #include <botan/algo_registry.h> #include <botan/block_cipher.h> -#include <botan/libstate.h> #include <botan/loadstor.h> #include <botan/internal/xor_buf.h> #include <botan/internal/rounding.h> @@ -23,9 +22,7 @@ namespace Botan { template<typename T> T* make_block_cipher_mode(const Transform::Spec& spec) { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0))) + if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) return new T(bc->clone()); return nullptr; } @@ -33,9 +30,7 @@ T* make_block_cipher_mode(const Transform::Spec& spec) template<typename T, size_t LEN1> T* make_block_cipher_mode_len(const Transform::Spec& spec) { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0))) + if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); return new T(bc->clone(), len1); @@ -47,9 +42,7 @@ T* make_block_cipher_mode_len(const Transform::Spec& spec) template<typename T, size_t LEN1, size_t LEN2> T* make_block_cipher_mode_len2(const Transform::Spec& spec) { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(const BlockCipher* bc = af.prototype_block_cipher(spec.arg(0))) + if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); const size_t len2 = spec.arg_as_integer(2, LEN2); diff --git a/src/lib/pk_pad/get_pk_pad.cpp b/src/lib/pk_pad/get_pk_pad.cpp index 0cb533084..b7df17158 100644 --- a/src/lib/pk_pad/get_pk_pad.cpp +++ b/src/lib/pk_pad/get_pk_pad.cpp @@ -7,7 +7,6 @@ #include <botan/emsa.h> #include <botan/eme.h> -#include <botan/libstate.h> #include <botan/scan_name.h> #if defined(BOTAN_HAS_EMSA1) @@ -51,7 +50,7 @@ EMSA* get_emsa(const std::string& algo_spec) { SCAN_Name request(algo_spec); - Algorithm_Factory& af = global_state().algorithm_factory(); + auto& hashes = Algo_Registry<HashFunction>::global_registry(); #if defined(BOTAN_HAS_EMSA_RAW) if(request.algo_name() == "Raw" && request.arg_count() == 0) @@ -66,18 +65,18 @@ EMSA* get_emsa(const std::string& algo_spec) #endif #if defined(BOTAN_HAS_EMSA1) - return new EMSA1(af.make_hash_function(request.arg(0))); + return new EMSA1(hashes.make(request.arg(0))); #endif } #if defined(BOTAN_HAS_EMSA1_BSI) if(request.algo_name() == "EMSA1_BSI" && request.arg_count() == 1) - return new EMSA1_BSI(af.make_hash_function(request.arg(0))); + return new EMSA1_BSI(hashes.make(request.arg(0))); #endif #if defined(BOTAN_HAS_EMSA_X931) if(request.algo_name() == "EMSA_X931" && request.arg_count() == 1) - return new EMSA_X931(af.make_hash_function(request.arg(0))); + return new EMSA_X931(hashes.make(request.arg(0))); #endif #if defined(BOTAN_HAS_EMSA_PKCS1) @@ -85,7 +84,7 @@ EMSA* get_emsa(const std::string& algo_spec) { if(request.arg(0) == "Raw") return new EMSA_PKCS1v15_Raw; - return new EMSA_PKCS1v15(af.make_hash_function(request.arg(0))); + return new EMSA_PKCS1v15(hashes.make(request.arg(0))); } #endif @@ -94,13 +93,13 @@ EMSA* get_emsa(const std::string& algo_spec) { // 3 args: Hash, MGF, salt size (MGF is hardcoded MGF1 in Botan) if(request.arg_count() == 1) - return new PSSR(af.make_hash_function(request.arg(0))); + return new PSSR(hashes.make(request.arg(0))); if(request.arg_count() == 2 && request.arg(1) != "MGF1") - return new PSSR(af.make_hash_function(request.arg(0))); + return new PSSR(hashes.make(request.arg(0))); if(request.arg_count() == 3) - return new PSSR(af.make_hash_function(request.arg(0)), + return new PSSR(hashes.make(request.arg(0)), request.arg_as_integer(2, 0)); } #endif @@ -124,14 +123,14 @@ EME* get_eme(const std::string& algo_spec) #endif #if defined(BOTAN_HAS_EME_OAEP) - Algorithm_Factory& af = global_state().algorithm_factory(); - if(request.algo_name() == "OAEP" && request.arg_count_between(1, 2)) { + auto& hashes = Algo_Registry<HashFunction>::global_registry(); + if(request.arg_count() == 1 || (request.arg_count() == 2 && request.arg(1) == "MGF1")) { - return new OAEP(af.make_hash_function(request.arg(0))); + return new OAEP(hashes.make(request.arg(0))); } } #endif diff --git a/src/lib/pubkey/pkcs8.cpp b/src/lib/pubkey/pkcs8.cpp index 3cfb48c3a..a1731c8ef 100644 --- a/src/lib/pubkey/pkcs8.cpp +++ b/src/lib/pubkey/pkcs8.cpp @@ -99,8 +99,7 @@ secure_vector<byte> PKCS8_decode( if(OIDS::lookup(pbe_alg_id.oid) != "PBE-PKCS5v20") throw std::runtime_error("Unknown PBE type " + pbe_alg_id.oid.as_string()); - key = pbes2_decrypt(key_data, pass.second, pbe_alg_id.parameters, - global_state().algorithm_factory()); + key = pbes2_decrypt(key_data, pass.second, pbe_alg_id.parameters); } BER_Decoder(key) @@ -185,8 +184,7 @@ std::vector<byte> BER_encode(const Private_Key& key, const std::pair<AlgorithmIdentifier, std::vector<byte>> pbe_info = pbes2_encrypt(PKCS8::BER_encode(key), pass, msec, - pbe_params.first, pbe_params.second, - rng, global_state().algorithm_factory()); + pbe_params.first, pbe_params.second, rng); return DER_Encoder() .start_cons(SEQUENCE) diff --git a/src/lib/pubkey/rfc6979/rfc6979.cpp b/src/lib/pubkey/rfc6979/rfc6979.cpp index a691e6e8c..1b22fae54 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.cpp +++ b/src/lib/pubkey/rfc6979/rfc6979.cpp @@ -7,7 +7,6 @@ #include <botan/rfc6979.h> #include <botan/hmac_drbg.h> -#include <botan/libstate.h> #include <botan/scan_name.h> namespace Botan { @@ -19,8 +18,7 @@ std::string hash_for_deterministic_signature(const std::string& emsa) if(emsa_name.arg_count() > 0) { const std::string pos_hash = emsa_name.arg(0); - if(global_state().algorithm_factory().prototype_hash_function(pos_hash)) - return pos_hash; + return pos_hash; } return "SHA-512"; // safe default if nothing we understand diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index 7aac66b3d..d0c534083 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -5,13 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/stream_utils.h> #include <botan/chacha.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> -#include <botan/internal/xor_buf.h> namespace Botan { +BOTAN_REGISTER_STREAM_CIPHER_NOARGS(ChaCha); + void ChaCha::chacha(byte output[64], const u32bit input[16]) { u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3], diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index 27118ee64..b6057a2a8 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -5,11 +5,23 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/stream_utils.h> #include <botan/ctr.h> -#include <botan/internal/xor_buf.h> namespace Botan { +BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make); + +CTR_BE* CTR_BE::make(const Spec& spec) + { + if(spec.algo_name() == "CTR-BE" && spec.arg_count() == 1) + { + if(BlockCipher* c = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) + return new CTR_BE(c); + } + return nullptr; + } + CTR_BE::CTR_BE(BlockCipher* ciph) : m_cipher(ciph), m_counter(256 * m_cipher->block_size()), diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h index 52b6b66fa..1515b0e82 100644 --- a/src/lib/stream/ctr/ctr.h +++ b/src/lib/stream/ctr/ctr.h @@ -38,6 +38,8 @@ class BOTAN_DLL CTR_BE : public StreamCipher void clear(); + static CTR_BE* make(const Spec& spec); + /** * @param cipher the underlying block cipher to use */ diff --git a/src/lib/stream/info.txt b/src/lib/stream/info.txt index faa2db215..15f0e91e5 100644 --- a/src/lib/stream/info.txt +++ b/src/lib/stream/info.txt @@ -3,3 +3,11 @@ define STREAM_CIPHER 20131128 <requires> algo_base </requires> + +<header:public> +stream_cipher.h +</header:public> + +<header:internal> +stream_utils.h +</header:internal> diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 986e6bf71..37429cd38 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -5,11 +5,23 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/stream_utils.h> #include <botan/ofb.h> -#include <botan/internal/xor_buf.h> namespace Botan { +BOTAN_REGISTER_NAMED_T(StreamCipher, "OFB", OFB, OFB::make); + +OFB* OFB::make(const Spec& spec) + { + if(spec.algo_name() == "OFB" && spec.arg_count() == 1) + { + if(BlockCipher* c = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) + return new OFB(c); + } + 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 925e7a773..09e11644a 100644 --- a/src/lib/stream/ofb/ofb.h +++ b/src/lib/stream/ofb/ofb.h @@ -38,6 +38,8 @@ class BOTAN_DLL OFB : public StreamCipher void clear(); + static OFB* make(const Spec& spec); + /** * @param cipher the underlying block cipher to use */ diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp index 1a5ad80e9..dcf4af241 100644 --- a/src/lib/stream/rc4/rc4.cpp +++ b/src/lib/stream/rc4/rc4.cpp @@ -5,12 +5,23 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/stream_utils.h> #include <botan/rc4.h> -#include <botan/internal/xor_buf.h> #include <botan/internal/rounding.h> namespace Botan { +BOTAN_REGISTER_NAMED_T(StreamCipher, "RC4", RC4, RC4::make); + +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 f72e2e75d..b2006fec5 100644 --- a/src/lib/stream/rc4/rc4.h +++ b/src/lib/stream/rc4/rc4.h @@ -31,6 +31,8 @@ class BOTAN_DLL RC4 : 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/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index a307110b3..7ab7b4f76 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -5,13 +5,13 @@ * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/stream_utils.h> #include <botan/salsa20.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> -#include <botan/internal/xor_buf.h> namespace Botan { +BOTAN_REGISTER_STREAM_CIPHER_NOARGS(Salsa20); + namespace { #define SALSA20_QUARTER_ROUND(x1, x2, x3, x4) \ diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h index 5708c2ab6..2ca92e467 100644 --- a/src/lib/stream/stream_cipher.h +++ b/src/lib/stream/stream_cipher.h @@ -9,6 +9,7 @@ #define BOTAN_STREAM_CIPHER_H__ #include <botan/sym_algo.h> +#include <botan/scan_name.h> namespace Botan { @@ -63,6 +64,8 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * Get a new object representing the same algorithm as *this */ virtual StreamCipher* clone() const = 0; + + typedef SCAN_Name Spec; }; } |