diff options
-rwxr-xr-x | configure.py | 2 | ||||
-rw-r--r-- | src/lib/hash/hash.cpp | 17 | ||||
-rw-r--r-- | src/lib/prov/bearssl/bearssl.h | 35 | ||||
-rw-r--r-- | src/lib/prov/bearssl/bearssl_hash.cpp | 116 | ||||
-rw-r--r-- | src/lib/prov/bearssl/info.txt | 13 |
5 files changed, 181 insertions, 2 deletions
diff --git a/configure.py b/configure.py index 184e64b3d..978744979 100755 --- a/configure.py +++ b/configure.py @@ -432,7 +432,7 @@ def process_command_line(args): # pylint: disable=too-many-locals help='minimize build') # Should be derived from info.txt but this runs too early - third_party = ['boost', 'bzip2', 'lzma', 'openssl', 'sqlite3', 'zlib', 'tpm'] + third_party = ['bearssl', 'boost', 'bzip2', 'lzma', 'openssl', 'sqlite3', 'zlib', 'tpm'] for mod in third_party: mods_group.add_option('--with-%s' % (mod), diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index c8dd58a66..cd2b5ad7a 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -88,6 +88,10 @@ #include <botan/blake2b.h> #endif +#if defined(BOTAN_HAS_BEARSSL) + #include <botan/internal/bearssl.h> +#endif + #if defined(BOTAN_HAS_OPENSSL) #include <botan/internal/openssl.h> #endif @@ -97,6 +101,17 @@ namespace Botan { std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec, const std::string& provider) { +#if defined(BOTAN_HAS_BEARSSL) + if(provider.empty() || provider == "bearssl") + { + if(auto hash = make_bearssl_hash(algo_spec)) + return hash; + + if(!provider.empty()) + return nullptr; + } +#endif + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -323,7 +338,7 @@ HashFunction::create_or_throw(const std::string& algo, std::vector<std::string> HashFunction::providers(const std::string& algo_spec) { - return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl"}); + return probe_providers_of<HashFunction>(algo_spec, {"base", "bearssl", "openssl"}); } } diff --git a/src/lib/prov/bearssl/bearssl.h b/src/lib/prov/bearssl/bearssl.h new file mode 100644 index 000000000..d438c47c7 --- /dev/null +++ b/src/lib/prov/bearssl/bearssl.h @@ -0,0 +1,35 @@ +/* +* Utils for calling BearSSL +* (C) 2015,2016 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_INTERNAL_BEARSSL_H__ +#define BOTAN_INTERNAL_BEARSSL_H__ + +#include <botan/pk_ops_fwd.h> +#include <botan/secmem.h> +#include <botan/exceptn.h> +#include <memory> +#include <string> + +namespace Botan { + +class HashFunction; + +class BearSSL_Error : public Exception + { + public: + BearSSL_Error(const std::string& what) : + Exception(what + " failed") {} + }; + +/* Hash */ + +std::unique_ptr<HashFunction> +make_bearssl_hash(const std::string& name); + +} + +#endif diff --git a/src/lib/prov/bearssl/bearssl_hash.cpp b/src/lib/prov/bearssl/bearssl_hash.cpp new file mode 100644 index 000000000..74b6a9ae7 --- /dev/null +++ b/src/lib/prov/bearssl/bearssl_hash.cpp @@ -0,0 +1,116 @@ +/* +* BearSSL Hash Functions +* (C) 1999-2007,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/hash.h> +#include <botan/internal/bearssl.h> +#include <bearssl_hash.h> +#include <unordered_map> + +namespace Botan { + +namespace { + +class BearSSL_HashFunction : public HashFunction + { + public: + void clear() override + { + m_ctx.vtable->init(&m_ctx.vtable); + } + + std::string provider() const override { return "bearssl"; } + std::string name() const override { return m_name; } + + HashFunction* clone() const override + { + return new BearSSL_HashFunction(m_ctx.vtable, m_name); + } + + std::unique_ptr<HashFunction> copy_state() const override + { + std::unique_ptr<BearSSL_HashFunction> copy(new BearSSL_HashFunction(m_ctx.vtable, m_name)); + memcpy(©->m_ctx, &m_ctx, sizeof(m_ctx)); + return std::move(copy); + } + + size_t output_length() const override + { + return (m_ctx.vtable->desc >> BR_HASHDESC_OUT_OFF) & BR_HASHDESC_OUT_MASK; + } + + size_t hash_block_size() const override + { + return 1 << ((m_ctx.vtable->desc >> BR_HASHDESC_LBLEN_OFF) & BR_HASHDESC_LBLEN_MASK); + } + + BearSSL_HashFunction(const br_hash_class *hash, const std::string name) + { + m_name = name; + hash->init(&m_ctx.vtable); + } + + ~BearSSL_HashFunction() + { + } + + private: + void add_data(const uint8_t input[], size_t length) override + { + m_ctx.vtable->update(&m_ctx.vtable, input, length); + } + + void final_result(uint8_t output[]) override + { + m_ctx.vtable->out(&m_ctx.vtable, output); + m_ctx.vtable->init(&m_ctx.vtable); + } + + std::string m_name; + br_hash_compat_context m_ctx; + }; + +} + +std::unique_ptr<HashFunction> +make_bearssl_hash(const std::string& name) + { +#define MAKE_BEARSSL_HASH(vtable) \ + std::unique_ptr<HashFunction>(new BearSSL_HashFunction(vtable, name)) + +#if defined(BOTAN_HAS_SHA2_32) + if(name == "SHA-224") + return MAKE_BEARSSL_HASH(&br_sha224_vtable); + if(name == "SHA-256") + return MAKE_BEARSSL_HASH(&br_sha256_vtable); +#endif + +#if defined(BOTAN_HAS_SHA2_64) + if(name == "SHA-384") + return MAKE_BEARSSL_HASH(&br_sha384_vtable); + if(name == "SHA-512") + return MAKE_BEARSSL_HASH(&br_sha512_vtable); +#endif + +#if defined(BOTAN_HAS_SHA1) + if(name == "SHA-160" || name == "SHA-1") + return MAKE_BEARSSL_HASH(&br_sha1_vtable); +#endif + +#if defined(BOTAN_HAS_MD5) + if(name == "MD5") + return MAKE_BEARSSL_HASH(&br_md5_vtable); +#endif + +#if defined(BOTAN_HAS_PARALLEL_HASH) + if(name == "Parallel(MD5,SHA-160)") + return MAKE_BEARSSL_HASH(&br_md5sha1_vtable); +#endif + + return nullptr; + } + +} diff --git a/src/lib/prov/bearssl/info.txt b/src/lib/prov/bearssl/info.txt new file mode 100644 index 000000000..cf38a1fe7 --- /dev/null +++ b/src/lib/prov/bearssl/info.txt @@ -0,0 +1,13 @@ +<defines> +BEARSSL -> 20170628 +</defines> + +load_on vendor + +<header:internal> +bearssl.h +</header:internal> + +<libs> +all!windows -> bearssl +</libs> |