diff options
37 files changed, 209 insertions, 202 deletions
diff --git a/doc/relnotes/1_11_15.rst b/doc/relnotes/1_11_15.rst index a0937deb2..3fbf0cd40 100644 --- a/doc/relnotes/1_11_15.rst +++ b/doc/relnotes/1_11_15.rst @@ -6,4 +6,6 @@ Version 1.11.15, Not Yet Released * When comparing two ASN.1 algorithm identifiers, consider empty and NULL parameters the same. +* Fixed memory leaks in TLS and cipher modes introduced in 1.11.14 + * Fix compilation problem on OS X diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h index e94c45541..63f376cc9 100644 --- a/src/lib/base/algo_registry.h +++ b/src/lib/base/algo_registry.h @@ -7,7 +7,7 @@ #ifndef BOTAN_ALGO_REGISTRY_H__ #define BOTAN_ALGO_REGISTRY_H__ -#include <botan/types.h> +#include <botan/lookup.h> #include <functional> #include <stdexcept> #include <mutex> diff --git a/src/lib/base/lookup.cpp b/src/lib/base/lookup.cpp index b6a49ec6b..6655a4fb4 100644 --- a/src/lib/base/lookup.cpp +++ b/src/lib/base/lookup.cpp @@ -44,6 +44,38 @@ MessageAuthenticationCode* get_mac(const std::string& algo_spec, const std::stri return make_a<MessageAuthenticationCode>(algo_spec, provider); } +std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec, + const std::string& provider) + { + if(auto x = get_block_cipher(algo_spec, provider)) + return std::unique_ptr<BlockCipher>(x); + throw Algorithm_Not_Found(algo_spec); + } + +std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec, + const std::string& provider) + { + if(auto x = get_stream_cipher(algo_spec, provider)) + return std::unique_ptr<StreamCipher>(x); + throw Algorithm_Not_Found(algo_spec); + } + +std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec, + const std::string& provider) + { + if(auto x = get_hash_function(algo_spec, provider)) + return std::unique_ptr<HashFunction>(x); + throw Algorithm_Not_Found(algo_spec); + } + +std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec, + const std::string& provider) + { + if(auto x = get_mac(algo_spec, provider)) + return std::unique_ptr<MessageAuthenticationCode>(x); + throw Algorithm_Not_Found(algo_spec); + } + std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec) { return providers_of<BlockCipher>(BlockCipher::Spec(algo_spec)); diff --git a/src/lib/base/lookup.h b/src/lib/base/lookup.h index c50186e35..d5b17237e 100644 --- a/src/lib/base/lookup.h +++ b/src/lib/base/lookup.h @@ -8,8 +8,10 @@ #ifndef BOTAN_LOOKUP_H__ #define BOTAN_LOOKUP_H__ -#include <botan/symkey.h> +#include <botan/types.h> #include <string> +#include <vector> +#include <memory> namespace Botan { @@ -31,7 +33,11 @@ class PBKDF; * @param algo_spec the name of the desired block cipher * @return pointer to the block cipher object */ -BOTAN_DLL BlockCipher* get_block_cipher(const std::string& algo_spec, const std::string& provider = ""); +BOTAN_DLL BlockCipher* get_block_cipher(const std::string& algo_spec, + const std::string& provider = ""); + +BOTAN_DLL std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec, + const std::string& provider = ""); BOTAN_DLL std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec); @@ -41,7 +47,11 @@ BOTAN_DLL std::vector<std::string> get_block_cipher_providers(const std::string& * @param algo_spec the name of the desired stream cipher * @return pointer to the stream cipher object */ -BOTAN_DLL StreamCipher* get_stream_cipher(const std::string& algo_spec, const std::string& provider = ""); +BOTAN_DLL StreamCipher* get_stream_cipher(const std::string& algo_spec, + const std::string& provider = ""); + +BOTAN_DLL std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec, + const std::string& provider = ""); BOTAN_DLL std::vector<std::string> get_stream_cipher_providers(const std::string& algo_spec); @@ -51,9 +61,14 @@ BOTAN_DLL std::vector<std::string> get_stream_cipher_providers(const std::string * @param algo_spec the name of the desired hash function * @return pointer to the hash function object */ -BOTAN_DLL HashFunction* get_hash_function(const std::string& algo_spec, const std::string& provider = ""); +BOTAN_DLL HashFunction* get_hash_function(const std::string& algo_spec, + const std::string& provider = ""); -inline HashFunction* get_hash(const std::string& algo_spec, const std::string& provider = "") +BOTAN_DLL std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec, + const std::string& provider = ""); + +inline HashFunction* get_hash(const std::string& algo_spec, + const std::string& provider = "") { return get_hash_function(algo_spec, provider); } @@ -66,7 +81,11 @@ BOTAN_DLL std::vector<std::string> get_hash_function_providers(const std::string * @param algo_spec the name of the desired MAC * @return pointer to the MAC object */ -BOTAN_DLL MessageAuthenticationCode* get_mac(const std::string& algo_spec, const std::string& provider = ""); +BOTAN_DLL MessageAuthenticationCode* get_mac(const std::string& algo_spec, + const std::string& provider = ""); + +BOTAN_DLL std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec, + const std::string& provider = ""); BOTAN_DLL std::vector<std::string> get_mac_providers(const std::string& algo_spec); @@ -75,7 +94,8 @@ BOTAN_DLL std::vector<std::string> get_mac_providers(const std::string& algo_spe * @param algo_spec the name of the desired PBKDF algorithm * @return pointer to newly allocated object of that type */ -BOTAN_DLL PBKDF* get_pbkdf(const std::string& algo_spec, const std::string& provider = ""); +BOTAN_DLL PBKDF* get_pbkdf(const std::string& algo_spec, + const std::string& provider = ""); } diff --git a/src/lib/base/symkey.h b/src/lib/base/symkey.h index f49bf226f..c837e8ca5 100644 --- a/src/lib/base/symkey.h +++ b/src/lib/base/symkey.h @@ -23,6 +23,7 @@ class BOTAN_DLL OctetString * @return size of this octet string in bytes */ size_t length() const { return bits.size(); } + size_t size() const { return bits.size(); } /** * @return this object as a secure_vector<byte> diff --git a/src/lib/block/cascade/cascade.cpp b/src/lib/block/cascade/cascade.cpp index c80bfbc68..3b59a4362 100644 --- a/src/lib/block/cascade/cascade.cpp +++ b/src/lib/block/cascade/cascade.cpp @@ -14,9 +14,8 @@ BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, Cascade_Cipher::m Cascade_Cipher* Cascade_Cipher::make(const BlockCipher::Spec& spec) { - auto& block_cipher = Algo_Registry<BlockCipher>::global_registry(); - std::unique_ptr<BlockCipher> c1(block_cipher.make(spec.arg(0))); - std::unique_ptr<BlockCipher> c2(block_cipher.make(spec.arg(1))); + std::unique_ptr<BlockCipher> c1(get_block_cipher(spec.arg(0))); + std::unique_ptr<BlockCipher> c2(get_block_cipher(spec.arg(1))); if(c1 && c2) return new Cascade_Cipher(c1.release(), c2.release()); diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index 44d4d0bed..a3f15fb51 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -17,8 +17,8 @@ Lion* make_lion(const BlockCipher::Spec& spec) { if(spec.arg_count_between(2, 3)) { - 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))); + std::unique_ptr<HashFunction> hash(get_hash_function(spec.arg(0))); + std::unique_ptr<StreamCipher> stream(get_stream_cipher(spec.arg(1))); if(hash && stream) { diff --git a/src/lib/filters/algo_filt.cpp b/src/lib/filters/algo_filt.cpp index c1f7b00e2..6c2176a85 100644 --- a/src/lib/filters/algo_filt.cpp +++ b/src/lib/filters/algo_filt.cpp @@ -1,127 +1,87 @@ /* * Filters -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/filters.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> #include <algorithm> namespace Botan { -/* -* StreamCipher_Filter Constructor -*/ StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher) : - buffer(DEFAULT_BUFFERSIZE), m_cipher(cipher) + m_buffer(DEFAULT_BUFFERSIZE), + m_cipher(cipher) { } -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, - const SymmetricKey& key) : - buffer(DEFAULT_BUFFERSIZE), +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key) : + m_buffer(DEFAULT_BUFFERSIZE), m_cipher(cipher) { m_cipher->set_key(key); } -/* -* StreamCipher_Filter Constructor -*/ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : - buffer(DEFAULT_BUFFERSIZE) + m_buffer(DEFAULT_BUFFERSIZE), + m_cipher(make_stream_cipher(sc_name)) { - m_cipher.reset(Algo_Registry<StreamCipher>::global_registry().make(sc_name)); } -/* -* StreamCipher_Filter Constructor -*/ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, - const SymmetricKey& key) : - buffer(DEFAULT_BUFFERSIZE) +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, const SymmetricKey& key) : + m_buffer(DEFAULT_BUFFERSIZE), + m_cipher(make_stream_cipher(sc_name)) { - m_cipher.reset(Algo_Registry<StreamCipher>::global_registry().make(sc_name)); m_cipher->set_key(key); } -/* -* Set the IV of a stream cipher -*/ -void StreamCipher_Filter::set_iv(const InitializationVector& iv) - { - m_cipher->set_iv(iv.begin(), iv.length()); - } - -/* -* Write data into a StreamCipher_Filter -*/ void StreamCipher_Filter::write(const byte input[], size_t length) { while(length) { - size_t copied = std::min<size_t>(length, buffer.size()); - m_cipher->cipher(input, &buffer[0], copied); - send(buffer, copied); + size_t copied = std::min<size_t>(length, m_buffer.size()); + m_cipher->cipher(input, &m_buffer[0], copied); + send(m_buffer, copied); input += copied; length -= copied; } } -/* -* Hash_Filter Constructor -*/ -Hash_Filter::Hash_Filter(const std::string& algo_spec, - size_t len) : - OUTPUT_LENGTH(len) +Hash_Filter::Hash_Filter(const std::string& hash_name, size_t len) : + m_hash(make_hash_function(hash_name)), + m_out_len(len) { - m_hash.reset(Algo_Registry<HashFunction>::global_registry().make(algo_spec)); } -/* -* Complete a calculation by a Hash_Filter -*/ void Hash_Filter::end_msg() { secure_vector<byte> output = m_hash->final(); - if(OUTPUT_LENGTH) - send(output, std::min<size_t>(OUTPUT_LENGTH, output.size())); + if(m_out_len) + send(output, std::min<size_t>(m_out_len, output.size())); else send(output); } -/* -* MAC_Filter Constructor -*/ MAC_Filter::MAC_Filter(const std::string& mac_name, size_t len) : - OUTPUT_LENGTH(len) + m_mac(make_message_auth(mac_name)), + m_out_len(len) { - m_mac.reset(Algo_Registry<MessageAuthenticationCode>::global_registry().make(mac_name)); } -/* -* MAC_Filter Constructor -*/ -MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, - size_t len) : OUTPUT_LENGTH(len) +MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, size_t len) : + m_mac(make_message_auth(mac_name)), + m_out_len(len) { - m_mac.reset(Algo_Registry<MessageAuthenticationCode>::global_registry().make(mac_name)); m_mac->set_key(key); } -/* -* Complete a calculation by a MAC_Filter -*/ void MAC_Filter::end_msg() { secure_vector<byte> output = m_mac->final(); - if(OUTPUT_LENGTH) - send(output, std::min<size_t>(OUTPUT_LENGTH, output.size())); + if(m_out_len) + send(output, std::min<size_t>(m_out_len, output.size())); else send(output); } diff --git a/src/lib/filters/filters.h b/src/lib/filters/filters.h index f0b3c110e..1a9597de3 100644 --- a/src/lib/filters/filters.h +++ b/src/lib/filters/filters.h @@ -1,6 +1,6 @@ /* * Filters -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -50,7 +50,10 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter * Set the initialization vector for this filter. * @param iv the initialization vector to set */ - void set_iv(const InitializationVector& iv); + void set_iv(const InitializationVector& iv) + { + m_cipher->set_iv(iv.begin(), iv.length()); + } /** * Set the key of this filter. @@ -86,7 +89,7 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key); private: - secure_vector<byte> buffer; + secure_vector<byte> m_buffer; std::unique_ptr<StreamCipher> m_cipher; }; @@ -110,7 +113,7 @@ class BOTAN_DLL Hash_Filter : public Filter * output of the hash algorithm will be cut off. */ Hash_Filter(HashFunction* hash, size_t len = 0) : - OUTPUT_LENGTH(len), m_hash(hash) {} + m_hash(hash), m_out_len(len) {} /** * Construct a hash filter. @@ -123,8 +126,8 @@ class BOTAN_DLL Hash_Filter : public Filter Hash_Filter(const std::string& request, size_t len = 0); private: - const size_t OUTPUT_LENGTH; std::unique_ptr<HashFunction> m_hash; + const size_t m_out_len; }; /** @@ -156,8 +159,8 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter */ MAC_Filter(MessageAuthenticationCode* mac, size_t out_len = 0) : - OUTPUT_LENGTH(out_len), - m_mac(mac) + m_mac(mac), + m_out_len(out_len) { } @@ -173,8 +176,8 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter MAC_Filter(MessageAuthenticationCode* mac, const SymmetricKey& key, size_t out_len = 0) : - OUTPUT_LENGTH(out_len), - m_mac(mac) + m_mac(mac), + m_out_len(out_len) { m_mac->set_key(key); } @@ -201,8 +204,8 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter MAC_Filter(const std::string& mac, const SymmetricKey& key, size_t len = 0); private: - const size_t OUTPUT_LENGTH; std::unique_ptr<MessageAuthenticationCode> m_mac; + const size_t m_out_len; }; } diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp index 4cb08eb0b..4797e2483 100644 --- a/src/lib/hash/comb4p/comb4p.cpp +++ b/src/lib/hash/comb4p/comb4p.cpp @@ -41,9 +41,8 @@ Comb4P* Comb4P::make(const Spec& spec) { if(spec.arg_count() == 2) { - auto& hashes = Algo_Registry<HashFunction>::global_registry(); - std::unique_ptr<HashFunction> h1(hashes.make(spec.arg(0))); - std::unique_ptr<HashFunction> h2(hashes.make(spec.arg(1))); + std::unique_ptr<HashFunction> h1(make_hash_function(spec.arg(0))); + std::unique_ptr<HashFunction> h2(make_hash_function(spec.arg(1))); if(h1 && h2) return new Comb4P(h1.release(), h2.release()); diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp index d3c641a95..b6133929c 100644 --- a/src/lib/hash/par_hash/par_hash.cpp +++ b/src/lib/hash/par_hash/par_hash.cpp @@ -8,7 +8,6 @@ #include <botan/internal/hash_utils.h> #include <botan/par_hash.h> #include <botan/parsing.h> -#include <botan/internal/algo_registry.h> namespace Botan { @@ -16,14 +15,11 @@ BOTAN_REGISTER_NAMED_T(HashFunction, "Parallel", Parallel, Parallel::make); Parallel* Parallel::make(const Spec& spec) { - auto& hash_fns = Algo_Registry<HashFunction>::global_registry(); - std::vector<std::unique_ptr<HashFunction>> hashes; for(size_t i = 0; i != spec.arg_count(); ++i) { - std::unique_ptr<HashFunction> h(hash_fns.make(spec.arg(i))); - + std::unique_ptr<HashFunction> h(get_hash_function(spec.arg(i))); if(!h) return nullptr; hashes.push_back(std::move(h)); diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index 8c92c779b..e725c3a4a 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -14,10 +14,10 @@ BOTAN_REGISTER_NAMED_T(KDF, "HKDF", HKDF, HKDF::make); HKDF* HKDF::make(const Spec& spec) { - if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) + if(auto mac = get_mac(spec.arg(0))) return new HKDF(mac); - if(auto mac = make_a<MessageAuthenticationCode>("HMAC(" + spec.arg(0) + ")")) + if(auto mac = get_mac("HMAC(" + spec.arg(0) + ")")) return new HKDF(mac); return nullptr; diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 9161dc71e..2deb133e9 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -13,9 +13,9 @@ namespace Botan { TLS_12_PRF* TLS_12_PRF::make(const Spec& spec) { - if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) + if(auto mac = get_mac(spec.arg(0))) return new TLS_12_PRF(mac); - if(auto hash = make_a<HashFunction>(spec.arg(0))) + if(auto hash = get_hash_function(spec.arg(0))) return new TLS_12_PRF(new HMAC(hash)); return nullptr; } @@ -23,10 +23,10 @@ TLS_12_PRF* TLS_12_PRF::make(const Spec& spec) BOTAN_REGISTER_NAMED_T(KDF, "TLS-12-PRF", TLS_12_PRF, TLS_12_PRF::make); BOTAN_REGISTER_KDF_NOARGS(TLS_PRF, "TLS-PRF"); -TLS_PRF::TLS_PRF() +TLS_PRF::TLS_PRF() : + m_hmac_md5(make_message_auth("HMAC(MD5)")), + m_hmac_sha1(make_message_auth("HMAC(SHA-1)")) { - m_hmac_md5.reset(make_a<MessageAuthenticationCode>("HMAC(MD5)")); - m_hmac_sha1.reset(make_a<MessageAuthenticationCode>("HMAC(SHA-1)")); } namespace { diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp index 5ca0f01ff..47e869bd5 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -35,7 +35,7 @@ size_t X942_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len) const { - std::unique_ptr<HashFunction> hash(make_a<HashFunction>("SHA-160")); + std::unique_ptr<HashFunction> hash(make_hash_function("SHA-160")); const OID kek_algo(m_key_wrap_oid); secure_vector<byte> h; diff --git a/src/lib/mac/cbc_mac/cbc_mac.cpp b/src/lib/mac/cbc_mac/cbc_mac.cpp index d893b922f..f07c7fe37 100644 --- a/src/lib/mac/cbc_mac/cbc_mac.cpp +++ b/src/lib/mac/cbc_mac/cbc_mac.cpp @@ -13,7 +13,10 @@ 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))); + { + if(auto bc = make_block_cipher(spec.arg(0))) + return new CBC_MAC(bc.release()); + } return nullptr; } diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index a77673138..0b867af8f 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -13,7 +13,10 @@ 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))); + { + if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + return new CMAC(bc); + } return nullptr; } diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 12525f088..1c6821a54 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -14,7 +14,10 @@ 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))); + { + if(HashFunction* h = get_hash_function(spec.arg(0))) + return new HMAC(h); + } return nullptr; } diff --git a/src/lib/mac/x919_mac/x919_mac.cpp b/src/lib/mac/x919_mac/x919_mac.cpp index 31fda319b..2e0fb2817 100644 --- a/src/lib/mac/x919_mac/x919_mac.cpp +++ b/src/lib/mac/x919_mac/x919_mac.cpp @@ -90,8 +90,7 @@ MessageAuthenticationCode* ANSI_X919_MAC::clone() const */ ANSI_X919_MAC::ANSI_X919_MAC() : m_state(8), m_position(0) { - auto& ciphers = Algo_Registry<BlockCipher>::global_registry(); - m_des1.reset(ciphers.make(BlockCipher::Spec("DES"), "")); + m_des1.reset(get_block_cipher("DES")); m_des2.reset(m_des1->clone()); } diff --git a/src/lib/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp index 3e8a29349..c30b20698 100644 --- a/src/lib/misc/benchmark/benchmark.cpp +++ b/src/lib/misc/benchmark/benchmark.cpp @@ -6,7 +6,7 @@ */ #include <botan/benchmark.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> #include <botan/buf_comp.h> #include <botan/cipher_mode.h> #include <botan/block_cipher.h> @@ -55,7 +55,7 @@ time_algorithm_ops(const std::string& name, const double mb_mult = buffer.size() / static_cast<double>(Mebibyte); - if(BlockCipher* p = make_a<BlockCipher>(name, provider)) + if(BlockCipher* p = get_block_cipher(name, provider)) { std::unique_ptr<BlockCipher> bc(p); @@ -67,7 +67,7 @@ time_algorithm_ops(const std::string& name, { "decrypt", mb_mult * time_op(runtime / 2, [&]() { bc->decrypt(buffer); }) }, }); } - else if(StreamCipher* p = make_a<StreamCipher>(name, provider)) + else if(StreamCipher* p = get_stream_cipher(name, provider)) { std::unique_ptr<StreamCipher> sc(p); @@ -78,7 +78,7 @@ time_algorithm_ops(const std::string& name, { "", mb_mult * time_op(runtime, [&]() { sc->encipher(buffer); }) }, }); } - else if(HashFunction* p = make_a<HashFunction>(name, provider)) + else if(HashFunction* p = get_hash_function(name, provider)) { std::unique_ptr<HashFunction> h(p); @@ -86,7 +86,7 @@ time_algorithm_ops(const std::string& name, { "", mb_mult * time_op(runtime, [&]() { h->update(buffer); }) }, }); } - else if(MessageAuthenticationCode* p = make_a<MessageAuthenticationCode>(name, provider)) + else if(MessageAuthenticationCode* p = get_mac(name, provider)) { std::unique_ptr<MessageAuthenticationCode> mac(p); @@ -136,10 +136,10 @@ std::set<std::string> get_all_providers_of(const std::string& algo) auto add_to_set = [&provs](const std::vector<std::string>& str) { for(auto&& s : str) { provs.insert(s); } }; - add_to_set(Algo_Registry<BlockCipher>::global_registry().providers_of(algo)); - add_to_set(Algo_Registry<StreamCipher>::global_registry().providers_of(algo)); - add_to_set(Algo_Registry<HashFunction>::global_registry().providers_of(algo)); - add_to_set(Algo_Registry<MessageAuthenticationCode>::global_registry().providers_of(algo)); + add_to_set(get_block_cipher_providers(algo)); + add_to_set(get_stream_cipher_providers(algo)); + add_to_set(get_hash_function_providers(algo)); + add_to_set(get_mac_providers(algo)); return provs; } diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index e46286906..435caaab1 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -6,9 +6,9 @@ */ #include <botan/pbes2.h> -#include <botan/internal/algo_registry.h> #include <botan/cipher_mode.h> -#include <botan/pbkdf2.h> +#include <botan/lookup.h> +#include <botan/pbkdf.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/parsing.h> @@ -82,15 +82,15 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, std::unique_ptr<Cipher_Mode> enc(get_cipher_mode(cipher, ENCRYPTION)); - PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); const size_t key_length = enc->key_spec().maximum_keylength(); size_t iterations = 0; secure_vector<byte> iv = rng.random_vec(enc->default_nonce_length()); - enc->set_key(pbkdf.derive_key(key_length, passphrase, &salt[0], salt.size(), - msec, iterations).bits_of()); + enc->set_key(pbkdf->derive_key(key_length, passphrase, &salt[0], salt.size(), + msec, iterations).bits_of()); enc->start(iv); secure_vector<byte> buf = key_bits; @@ -151,15 +151,15 @@ pbes2_decrypt(const secure_vector<byte>& key_bits, BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end(); const std::string prf = OIDS::lookup(prf_algo.oid); - PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); + + std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION)); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); - dec->set_key(pbkdf.derive_key(key_length, passphrase, &salt[0], salt.size(), - iterations).bits_of()); + dec->set_key(pbkdf->pbkdf_iterations(key_length, passphrase, &salt[0], salt.size(), iterations)); dec->start(iv); diff --git a/src/lib/misc/rfc3394/rfc3394.cpp b/src/lib/misc/rfc3394/rfc3394.cpp index 422f2a2dd..11791418b 100644 --- a/src/lib/misc/rfc3394/rfc3394.cpp +++ b/src/lib/misc/rfc3394/rfc3394.cpp @@ -6,7 +6,7 @@ */ #include <botan/rfc3394.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> #include <botan/block_cipher.h> #include <botan/loadstor.h> #include <botan/exceptn.h> @@ -14,30 +14,16 @@ namespace Botan { -namespace { - -BlockCipher* make_aes(size_t keylength) - { - auto& block_ciphers = Algo_Registry<BlockCipher>::global_registry(); - if(keylength == 16) - return block_ciphers.make("AES-128"); - else if(keylength == 24) - return block_ciphers.make("AES-192"); - else if(keylength == 32) - return block_ciphers.make("AES-256"); - else - throw std::invalid_argument("Bad KEK length for NIST keywrap"); - } - -} - secure_vector<byte> rfc3394_keywrap(const secure_vector<byte>& key, 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())); + if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) + throw std::invalid_argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key wrap"); + + std::unique_ptr<BlockCipher> aes(make_block_cipher("AES-" + std::to_string(8*kek.size()))); aes->set_key(kek); const size_t n = key.size() / 8; @@ -78,7 +64,10 @@ secure_vector<byte> rfc3394_keyunwrap(const secure_vector<byte>& key, 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())); + if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) + throw std::invalid_argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key unwrap"); + + std::unique_ptr<BlockCipher> aes(make_block_cipher("AES-" + std::to_string(8*kek.size()))); aes->set_key(kek); const size_t n = (key.size() - 8) / 8; diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp index 15fd8f959..37e0ef96b 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -13,6 +13,11 @@ namespace Botan { BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Encryption); BOTAN_REGISTER_TRANSFORM_NOARGS(ChaCha20Poly1305_Decryption); +ChaCha20Poly1305_Mode::ChaCha20Poly1305_Mode() : + m_chacha(make_stream_cipher("ChaCha")), + m_poly1305(make_message_auth("Poly1305")) + {} + bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const { return (n == 8 || n == 12); @@ -20,16 +25,14 @@ bool ChaCha20Poly1305_Mode::valid_nonce_length(size_t n) const void ChaCha20Poly1305_Mode::clear() { - m_chacha.reset(); - m_poly1305.reset(); + m_chacha->clear(); + m_poly1305->clear(); m_ad.clear(); m_ctext_len = 0; } void ChaCha20Poly1305_Mode::key_schedule(const byte key[], size_t length) { - if(!m_chacha.get()) - m_chacha.reset(make_a<StreamCipher>("ChaCha")); m_chacha->set_key(key, length); } @@ -60,8 +63,6 @@ secure_vector<byte> ChaCha20Poly1305_Mode::start_raw(const byte nonce[], size_t secure_vector<byte> zeros(64); m_chacha->encrypt(zeros); - if(!m_poly1305.get()) - m_poly1305.reset(make_a<MessageAuthenticationCode>("Poly1305")); m_poly1305->set_key(&zeros[0], 32); // Remainder of output is discard diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h index a3b83dc63..f496590af 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h @@ -41,6 +41,8 @@ class BOTAN_DLL ChaCha20Poly1305_Mode : public AEAD_Mode std::unique_ptr<StreamCipher> m_chacha; std::unique_ptr<MessageAuthenticationCode> m_poly1305; + ChaCha20Poly1305_Mode(); + secure_vector<byte> m_ad; size_t m_nonce_len = 0; size_t m_ctext_len = 0; diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp index 1fb27f2e0..7cee72081 100644 --- a/src/lib/modes/cbc/cbc.cpp +++ b/src/lib/modes/cbc/cbc.cpp @@ -14,7 +14,7 @@ namespace Botan { template<typename CBC_T, typename CTS_T> Transform* make_cbc_mode(const Transform::Spec& spec) { - std::unique_ptr<BlockCipher> bc(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); + std::unique_ptr<BlockCipher> bc(get_block_cipher(spec.arg(0))); if(bc) { diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp index 6318671ca..eaab1810d 100644 --- a/src/lib/modes/ecb/ecb.cpp +++ b/src/lib/modes/ecb/ecb.cpp @@ -13,7 +13,7 @@ namespace Botan { template<typename T> Transform* make_ecb_mode(const Transform::Spec& spec) { - std::unique_ptr<BlockCipher> bc(Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))); + std::unique_ptr<BlockCipher> bc(get_block_cipher(spec.arg(0))); std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(spec.arg(1, "NoPadding"))); if(bc && pad) return new T(bc.release(), pad.release()); diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h index ef2840000..e2e2af83e 100644 --- a/src/lib/modes/mode_utils.h +++ b/src/lib/modes/mode_utils.h @@ -22,18 +22,18 @@ namespace Botan { template<typename T> T* make_block_cipher_mode(const Transform::Spec& spec) { - if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) - return new T(bc->clone()); + if(BlockCipher* bc = get_block_cipher(spec.arg(0))) + return new T(bc); return nullptr; } template<typename T, size_t LEN1> T* make_block_cipher_mode_len(const Transform::Spec& spec) { - if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) + if(BlockCipher* bc = get_block_cipher(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); - return new T(bc->clone(), len1); + return new T(bc, len1); } return nullptr; @@ -42,11 +42,11 @@ 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) { - if(BlockCipher* bc = Algo_Registry<BlockCipher>::global_registry().make(spec.arg(0))) + if(BlockCipher* bc = get_block_cipher(spec.arg(0))) { const size_t len1 = spec.arg_as_integer(1, LEN1); const size_t len2 = spec.arg_as_integer(2, LEN2); - return new T(bc->clone(), len1, len2); + return new T(bc, len1, len2); } return nullptr; diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index 88360e6a2..ab3735bac 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -17,10 +17,10 @@ BOTAN_REGISTER_NAMED_T(PBKDF, "PBKDF2", PKCS5_PBKDF2, PKCS5_PBKDF2::make); PKCS5_PBKDF2* PKCS5_PBKDF2::make(const Spec& spec) { - if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) + if(auto mac = get_mac(spec.arg(0))) return new PKCS5_PBKDF2(mac); - if(auto mac = make_a<MessageAuthenticationCode>("HMAC(" + spec.arg(0) + ")")) + if(auto mac = get_mac("HMAC(" + spec.arg(0) + ")")) return new PKCS5_PBKDF2(mac); return nullptr; diff --git a/src/lib/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp index dc9266ee7..46bcc04ee 100644 --- a/src/lib/pk_pad/eme_oaep/oaep.cpp +++ b/src/lib/pk_pad/eme_oaep/oaep.cpp @@ -17,12 +17,10 @@ OAEP* OAEP::make(const Spec& request) { 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")) { - if(HashFunction* hash = hashes.make(request.arg(0))) + if(HashFunction* hash = get_hash_function(request.arg(0))) return new OAEP(hash); } } diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index 8f6255b23..f73c8b7d9 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -17,7 +17,11 @@ EMSA* make_pkcs1v15(const EMSA::Spec& spec) if(spec.arg(0) == "Raw") return new EMSA_PKCS1v15_Raw; else - return new EMSA_PKCS1v15(make_a<HashFunction>(spec.arg(0))); + { + if(HashFunction* h = get_hash_function(spec.arg(0))) + return new EMSA_PKCS1v15(h); + } + return nullptr; } } diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp index 3f93ca79d..691d15964 100644 --- a/src/lib/pk_pad/emsa_pssr/pssr.cpp +++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp @@ -17,14 +17,13 @@ PSSR* PSSR::make(const Spec& request) if(request.arg(1, "MGF1") != "MGF1") return nullptr; - auto hash = make_a<HashFunction>(request.arg(0)); - - if(!hash) - return nullptr; - - const size_t salt_size = request.arg_as_integer(2, hash->output_length()); + if(HashFunction* hash = get_hash_function(request.arg(0))) + { + const size_t salt_size = request.arg_as_integer(2, hash->output_length()); + return new PSSR(hash, salt_size); + } - return new PSSR(hash, salt_size); + return nullptr; } BOTAN_REGISTER_NAMED_T(EMSA, "PSSR", PSSR, PSSR::make); diff --git a/src/lib/pubkey/rfc6979/rfc6979.cpp b/src/lib/pubkey/rfc6979/rfc6979.cpp index 9f9bbc9c0..3bd723d6d 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.cpp +++ b/src/lib/pubkey/rfc6979/rfc6979.cpp @@ -8,7 +8,7 @@ #include <botan/rfc6979.h> #include <botan/hmac_drbg.h> #include <botan/scan_name.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> namespace Botan { @@ -30,8 +30,7 @@ BigInt generate_rfc6979_nonce(const BigInt& x, const BigInt& h, const std::string& hash) { - auto& macs = Algo_Registry<MessageAuthenticationCode>::global_registry(); - HMAC_DRBG rng(macs.make("HMAC(" + hash + ")"), nullptr); + HMAC_DRBG rng(make_message_auth("HMAC(" + hash + ")").release(), nullptr); const size_t qlen = q.bits(); const size_t rlen = qlen / 8 + (qlen % 8 ? 1 : 0); diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp index a5222c51d..462d8afa1 100644 --- a/src/lib/rng/rng.cpp +++ b/src/lib/rng/rng.cpp @@ -7,16 +7,15 @@ #include <botan/rng.h> #include <botan/hmac_rng.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> namespace Botan { RandomNumberGenerator* RandomNumberGenerator::make_rng() { - std::unique_ptr<RandomNumberGenerator> rng( - new HMAC_RNG(make_a<MessageAuthenticationCode>("HMAC(SHA-512)"), - make_a<MessageAuthenticationCode>("HMAC(SHA-256)")) - ); + std::unique_ptr<MessageAuthenticationCode> h1(make_message_auth("HMAC(SHA-512")); + std::unique_ptr<MessageAuthenticationCode> h2(h1->clone()); + std::unique_ptr<RandomNumberGenerator> rng(new HMAC_RNG(h1.release(), h2.release())); rng->reseed(256); diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index 943bb75f7..3b2e75f72 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -16,7 +16,7 @@ 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))) + if(BlockCipher* c = get_block_cipher(spec.arg(0))) return new CTR_BE(c); } return nullptr; diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 37429cd38..b98f81be3 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -16,7 +16,7 @@ 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))) + if(BlockCipher* c = get_block_cipher(spec.arg(0))) return new OFB(c); } return nullptr; diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index 31c688c51..c0f9dbf76 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -7,7 +7,7 @@ #include <botan/tls_ciphersuite.h> #include <botan/parsing.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> #include <botan/block_cipher.h> #include <botan/stream_cipher.h> #include <botan/hash.h> @@ -104,16 +104,14 @@ namespace { bool have_hash(const std::string& prf) { - if(Algo_Registry<HashFunction>::global_registry().providers_of(prf).size() > 0) - return true; - return false; + return (!get_hash_function_providers(prf).empty()); } bool have_cipher(const std::string& cipher) { - if(Algo_Registry<BlockCipher>::global_registry().providers_of(cipher).size() > 0) + if(!get_block_cipher_providers(cipher).empty()) return true; - if(Algo_Registry<StreamCipher>::global_registry().providers_of(cipher).size() > 0) + if(!get_stream_cipher_providers(cipher).empty()) return true; return false; } diff --git a/src/lib/tls/tls_handshake_hash.cpp b/src/lib/tls/tls_handshake_hash.cpp index 76766c5fc..94c2774c5 100644 --- a/src/lib/tls/tls_handshake_hash.cpp +++ b/src/lib/tls/tls_handshake_hash.cpp @@ -7,7 +7,7 @@ #include <botan/internal/tls_handshake_hash.h> #include <botan/tls_exceptn.h> -#include <botan/internal/algo_registry.h> +#include <botan/lookup.h> #include <botan/hash.h> namespace Botan { @@ -20,18 +20,16 @@ namespace TLS { secure_vector<byte> Handshake_Hash::final(Protocol_Version version, const std::string& mac_algo) const { - std::unique_ptr<HashFunction> hash; + auto choose_hash = [=]() { + if(!version.supports_ciphersuite_specific_prf()) + return "Parallel(MD5,SHA-160)";; - if(version.supports_ciphersuite_specific_prf()) - { if(mac_algo == "MD5" || mac_algo == "SHA-1") - hash.reset(make_a<HashFunction>("SHA-256")); - else - hash.reset(make_a<HashFunction>(mac_algo)); - } - else - hash.reset(make_a<HashFunction>("Parallel(MD5,SHA-160)")); + return "SHA-256"; + return mac_algo.c_str(); + }; + std::unique_ptr<HashFunction> hash(make_hash_function(choose_hash())); hash->update(data); return hash->final(); } diff --git a/src/lib/tls/tls_record.cpp b/src/lib/tls/tls_record.cpp index 521e7e4c1..6ccb31165 100644 --- a/src/lib/tls/tls_record.cpp +++ b/src/lib/tls/tls_record.cpp @@ -65,7 +65,7 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, if(BlockCipher* bc = get_block_cipher(cipher_algo)) { - m_block_cipher.reset(bc->clone()); + m_block_cipher.reset(bc); m_block_cipher->set_key(cipher_key); m_block_cipher_cbc_state = iv.bits_of(); m_block_size = bc->block_size(); @@ -75,7 +75,7 @@ Connection_Cipher_State::Connection_Cipher_State(Protocol_Version version, } else if(StreamCipher* sc = get_stream_cipher(cipher_algo)) { - m_stream_cipher.reset(sc->clone()); + m_stream_cipher.reset(sc); m_stream_cipher->set_key(cipher_key); } else |