diff options
author | Patrick Wildt <[email protected]> | 2017-06-28 16:33:55 +0200 |
---|---|---|
committer | Patrick Wildt <[email protected]> | 2017-07-05 11:05:49 +0200 |
commit | 783798ca424fe44b36bdec386da91da75e856cdd (patch) | |
tree | 5e4604dc849622960a561ab0cee99b646cc577dd | |
parent | 38fe6d3ab3e8a4be2becd5fd0b8c7bb4a8f1e192 (diff) |
BearSSL: Initial support and hash tests
BearSSL is an implementation of the SSL/TLS protocol in C aiming
to be correct and secure, small and highly portable. Thus making
it nicer to be included in a rather sparse bootloader. This commit
adds support for BearSSL's hash routines only, with more stuff
coming up in following commits. The goal is to be able to test
BearSSL using Botan's extensive testsuite.
-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> |