diff options
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/mac')
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp | 107 | ||||
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h | 48 | ||||
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt | 7 | ||||
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/info.txt | 7 | ||||
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/mac.cpp | 171 | ||||
-rw-r--r-- | src/libs/3rdparty/botan/src/lib/mac/mac.h | 143 |
6 files changed, 483 insertions, 0 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp new file mode 100644 index 0000000000..72c617c5b4 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.cpp @@ -0,0 +1,107 @@ +/* +* HMAC +* (C) 1999-2007,2014 Jack Lloyd +* 2007 Yves Jerschow +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/hmac.h> + +namespace Botan { + +/* +* Update a HMAC Calculation +*/ +void HMAC::add_data(const uint8_t input[], size_t length) + { + verify_key_set(m_ikey.empty() == false); + m_hash->update(input, length); + } + +/* +* Finalize a HMAC Calculation +*/ +void HMAC::final_result(uint8_t mac[]) + { + verify_key_set(m_okey.empty() == false); + m_hash->final(mac); + m_hash->update(m_okey); + m_hash->update(mac, output_length()); + m_hash->final(mac); + m_hash->update(m_ikey); + } + +Key_Length_Specification HMAC::key_spec() const + { + // Support very long lengths for things like PBKDF2 and the TLS PRF + return Key_Length_Specification(0, 4096); + } + +/* +* HMAC Key Schedule +*/ +void HMAC::key_schedule(const uint8_t key[], size_t length) + { + m_hash->clear(); + + m_ikey.resize(m_hash->hash_block_size()); + m_okey.resize(m_hash->hash_block_size()); + + const uint8_t ipad = 0x36; + const uint8_t opad = 0x5C; + + std::fill(m_ikey.begin(), m_ikey.end(), ipad); + std::fill(m_okey.begin(), m_okey.end(), opad); + + if(length > m_hash->hash_block_size()) + { + secure_vector<uint8_t> hmac_key = m_hash->process(key, length); + xor_buf(m_ikey, hmac_key, hmac_key.size()); + xor_buf(m_okey, hmac_key, hmac_key.size()); + } + else + { + xor_buf(m_ikey, key, length); + xor_buf(m_okey, key, length); + } + + m_hash->update(m_ikey); + } + +/* +* Clear memory of sensitive data +*/ +void HMAC::clear() + { + m_hash->clear(); + zap(m_ikey); + zap(m_okey); + } + +/* +* Return the name of this type +*/ +std::string HMAC::name() const + { + return "HMAC(" + m_hash->name() + ")"; + } + +/* +* Return a clone of this object +*/ +MessageAuthenticationCode* HMAC::clone() const + { + return new HMAC(m_hash->clone()); + } + +/* +* HMAC Constructor +*/ +HMAC::HMAC(HashFunction* hash) : m_hash(hash) + { + BOTAN_ARG_CHECK(m_hash->hash_block_size() > 0, + "HMAC is not compatible with this hash function"); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h new file mode 100644 index 0000000000..8001594324 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/hmac.h @@ -0,0 +1,48 @@ +/* +* HMAC +* (C) 1999-2007,2014 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_HMAC_H_ +#define BOTAN_HMAC_H_ + +#include <botan/mac.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* HMAC +*/ +class BOTAN_PUBLIC_API(2,0) HMAC final : public MessageAuthenticationCode + { + public: + void clear() override; + std::string name() const override; + MessageAuthenticationCode* clone() const override; + + size_t output_length() const override { return m_hash->output_length(); } + + Key_Length_Specification key_spec() const override; + + /** + * @param hash the hash to use for HMACing + */ + explicit HMAC(HashFunction* hash); + + HMAC(const HMAC&) = delete; + HMAC& operator=(const HMAC&) = delete; + private: + void add_data(const uint8_t[], size_t) override; + void final_result(uint8_t[]) override; + void key_schedule(const uint8_t[], size_t) override; + + std::unique_ptr<HashFunction> m_hash; + secure_vector<uint8_t> m_ikey, m_okey; + }; + +} + +#endif diff --git a/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt b/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt new file mode 100644 index 0000000000..50dc665dc9 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/hmac/info.txt @@ -0,0 +1,7 @@ +<defines> +HMAC -> 20131128 +</defines> + +<requires> +hash +</requires> diff --git a/src/libs/3rdparty/botan/src/lib/mac/info.txt b/src/libs/3rdparty/botan/src/lib/mac/info.txt new file mode 100644 index 0000000000..7aef92b879 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/info.txt @@ -0,0 +1,7 @@ +<defines> +MAC -> 20150626 +</defines> + +<header:public> +mac.h +</header:public> diff --git a/src/libs/3rdparty/botan/src/lib/mac/mac.cpp b/src/libs/3rdparty/botan/src/lib/mac/mac.cpp new file mode 100644 index 0000000000..4c3fc5230e --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/mac.cpp @@ -0,0 +1,171 @@ +/* +* Message Authentication Code base class +* (C) 1999-2008 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/mac.h> +#include <botan/exceptn.h> +#include <botan/scan_name.h> +#include <botan/mem_ops.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_GMAC) + #include <botan/gmac.h> + #include <botan/block_cipher.h> +#endif + +#if defined(BOTAN_HAS_HMAC) + #include <botan/hmac.h> + #include <botan/hash.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 + +namespace Botan { + +std::unique_ptr<MessageAuthenticationCode> +MessageAuthenticationCode::create(const std::string& algo_spec, + const std::string& provider) + { + const SCAN_Name req(algo_spec); + +#if defined(BOTAN_HAS_GMAC) + if(req.algo_name() == "GMAC" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr<MessageAuthenticationCode>(new GMAC(bc.release())); + } + } +#endif + +#if defined(BOTAN_HAS_HMAC) + if(req.algo_name() == "HMAC" && req.arg_count() == 1) + { + // TODO OpenSSL + if(provider.empty() || provider == "base") + { + if(auto h = HashFunction::create(req.arg(0))) + return std::unique_ptr<MessageAuthenticationCode>(new HMAC(h.release())); + } + } +#endif + +#if defined(BOTAN_HAS_POLY1305) + if(req.algo_name() == "Poly1305" && req.arg_count() == 0) + { + if(provider.empty() || provider == "base") + return std::unique_ptr<MessageAuthenticationCode>(new Poly1305); + } +#endif + +#if defined(BOTAN_HAS_SIPHASH) + if(req.algo_name() == "SipHash") + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr<MessageAuthenticationCode>( + 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.algo_name() == "OMAC") && req.arg_count() == 1) + { + // TODO: OpenSSL CMAC + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr<MessageAuthenticationCode>(new CMAC(bc.release())); + } + } +#endif + + +#if defined(BOTAN_HAS_CBC_MAC) + if(req.algo_name() == "CBC-MAC" && req.arg_count() == 1) + { + if(provider.empty() || provider == "base") + { + if(auto bc = BlockCipher::create(req.arg(0))) + return std::unique_ptr<MessageAuthenticationCode>(new CBC_MAC(bc.release())); + } + } +#endif + +#if defined(BOTAN_HAS_ANSI_X919_MAC) + if(req.algo_name() == "X9.19-MAC") + { + if(provider.empty() || provider == "base") + { + return std::unique_ptr<MessageAuthenticationCode>(new ANSI_X919_MAC); + } + } +#endif + + BOTAN_UNUSED(req); + BOTAN_UNUSED(provider); + + return nullptr; + } + +std::vector<std::string> +MessageAuthenticationCode::providers(const std::string& algo_spec) + { + return probe_providers_of<MessageAuthenticationCode>(algo_spec, {"base", "openssl"}); + } + +//static +std::unique_ptr<MessageAuthenticationCode> +MessageAuthenticationCode::create_or_throw(const std::string& algo, + const std::string& provider) + { + if(auto mac = MessageAuthenticationCode::create(algo, provider)) + { + return mac; + } + throw Lookup_Error("MAC", algo, provider); + } + +void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len) + { + BOTAN_UNUSED(nonce); + if(nonce_len > 0) + throw Invalid_IV_Length(name(), nonce_len); + } + +/* +* Default (deterministic) MAC verification operation +*/ +bool MessageAuthenticationCode::verify_mac(const uint8_t mac[], size_t length) + { + secure_vector<uint8_t> our_mac = final(); + + if(our_mac.size() != length) + return false; + + return constant_time_compare(our_mac.data(), mac, length); + } + +} diff --git a/src/libs/3rdparty/botan/src/lib/mac/mac.h b/src/libs/3rdparty/botan/src/lib/mac/mac.h new file mode 100644 index 0000000000..de30b7dbb2 --- /dev/null +++ b/src/libs/3rdparty/botan/src/lib/mac/mac.h @@ -0,0 +1,143 @@ +/* +* Base class for message authentiction codes +* (C) 1999-2007 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_MESSAGE_AUTH_CODE_BASE_H_ +#define BOTAN_MESSAGE_AUTH_CODE_BASE_H_ + +#include <botan/buf_comp.h> +#include <botan/sym_algo.h> +#include <string> +#include <memory> + +namespace Botan { + +/** +* This class represents Message Authentication Code (MAC) objects. +*/ +class BOTAN_PUBLIC_API(2,0) MessageAuthenticationCode : public Buffered_Computation, + public SymmetricAlgorithm + { + public: + /** + * 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 + * @return a null pointer if the algo/provider combination cannot be found + */ + static std::unique_ptr<MessageAuthenticationCode> + 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 algo/provider combination cannot be found + */ + static std::unique_ptr<MessageAuthenticationCode> + create_or_throw(const std::string& algo_spec, + const std::string& provider = ""); + + /** + * @return list of available providers for this algorithm, empty if not available + */ + static std::vector<std::string> providers(const std::string& algo_spec); + + virtual ~MessageAuthenticationCode() = default; + + /** + * Prepare for processing a message under the specified nonce + * + * Most MACs neither require nor support a nonce; for these algorithms + * calling `start_msg` is optional and calling it with anything other than + * an empty string is an error. One MAC which *requires* a per-message + * nonce be specified is GMAC. + * + * @param nonce the message nonce bytes + * @param nonce_len the size of len in bytes + * Default implementation simply rejects all non-empty nonces + * since most hash/MAC algorithms do not support randomization + */ + virtual void start_msg(const uint8_t nonce[], size_t nonce_len); + + /** + * Begin processing a message with a nonce + * + * @param nonce the per message nonce + */ + template<typename Alloc> + void start(const std::vector<uint8_t, Alloc>& nonce) + { + start_msg(nonce.data(), nonce.size()); + } + + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const uint8_t nonce[], size_t nonce_len) + { + start_msg(nonce, nonce_len); + } + + /** + * Begin processing a message. + */ + void start() + { + return start_msg(nullptr, 0); + } + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @param length the length of param in + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const uint8_t in[], size_t length); + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const std::vector<uint8_t>& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const secure_vector<uint8_t>& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Get a new object representing the same algorithm as *this + */ + virtual MessageAuthenticationCode* clone() const = 0; + + /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } + + }; + +typedef MessageAuthenticationCode MAC; + +} + +#endif |