aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Wildt <[email protected]>2017-06-28 16:33:55 +0200
committerPatrick Wildt <[email protected]>2017-07-05 11:05:49 +0200
commit783798ca424fe44b36bdec386da91da75e856cdd (patch)
tree5e4604dc849622960a561ab0cee99b646cc577dd
parent38fe6d3ab3e8a4be2becd5fd0b8c7bb4a8f1e192 (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-xconfigure.py2
-rw-r--r--src/lib/hash/hash.cpp17
-rw-r--r--src/lib/prov/bearssl/bearssl.h35
-rw-r--r--src/lib/prov/bearssl/bearssl_hash.cpp116
-rw-r--r--src/lib/prov/bearssl/info.txt13
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(&copy->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>