aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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>