logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git
commit: 01f543064ebecd8f70ce0437df48debad2dbd354
parent 3fe24c73976047fe76b74b32fca2e6c1d35eac4c
Author: Michael Forney <mforney@mforney.org>
Date:   Tue, 14 Apr 2020 20:16:00 -0700

libfido2: Port to BearSSL

Diffstat:

Mpkg/libfido2/gen.lua5+++--
Apkg/libfido2/patch/0008-port-to-BearSSL.patch1796+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/libfido2/ver2+-
3 files changed, 1800 insertions(+), 3 deletions(-)

diff --git a/pkg/libfido2/gen.lua b/pkg/libfido2/gen.lua @@ -3,8 +3,8 @@ cflags{ '-include $outdir/config.h', '-D _DEFAULT_SOURCE', '-D _FIDO_INTERNAL', + '-I $builddir/pkg/bearssl/include', '-I $builddir/pkg/libcbor/include', - '-I $builddir/pkg/libressl/include', '-I $builddir/pkg/linux-headers/include', '-I $srcdir/src', '-I $basedir/pkg/openbsd/include', @@ -18,8 +18,8 @@ pkg.hdrs = copy('$outdir/include', '$srcdir/src', { }) pkg.deps = { '$outdir/config.h', + 'pkg/bearssl/headers', 'pkg/libcbor/headers', - 'pkg/libressl/headers', 'pkg/linux-headers/headers', } @@ -56,6 +56,7 @@ lib('libfido2.a', [[ hid_linux.c ) + $builddir/pkg/bearssl/libbearssl.a $builddir/pkg/libcbor/libcbor.a ]]) diff --git a/pkg/libfido2/patch/0008-port-to-BearSSL.patch b/pkg/libfido2/patch/0008-port-to-BearSSL.patch @@ -0,0 +1,1796 @@ +From 4f9ada2c0e453adf51c66afe11ce29cf5e41000f Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Mon, 18 Nov 2019 23:46:22 -0800 +Subject: [PATCH] port to BearSSL + +--- + CMakeLists.txt | 32 +++--- + src/CMakeLists.txt | 4 +- + src/aes256.c | 61 +++++------ + src/assert.c | 135 +++++++++---------------- + src/cbor.c | 98 +++++++----------- + src/cred.c | 94 ++++++++--------- + src/credman.c | 16 +-- + src/ecdh.c | 55 ++++------ + src/eddsa.c | 84 --------------- + src/es256.c | 247 +++++++-------------------------------------- + src/fido.h | 3 - + src/fido/eddsa.h | 22 ---- + src/fido/es256.h | 5 - + src/fido/rs256.h | 4 - + src/rs256.c | 117 +-------------------- + src/u2f.c | 109 ++++++++++---------- + 16 files changed, 286 insertions(+), 800 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 402220e..bdabd3a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -52,13 +52,13 @@ endif() + + if(MSVC) + if((NOT CBOR_INCLUDE_DIRS) OR (NOT CBOR_LIBRARY_DIRS) OR +- (NOT CRYPTO_INCLUDE_DIRS) OR (NOT CRYPTO_LIBRARY_DIRS)) ++ (NOT BEARSSL_INCLUDE_DIRS) OR (NOT BEARSSL_LIBRARY_DIRS)) + message(FATAL_ERROR "please provide definitions for " +- "{CBOR,CRYPTO}_{INCLUDE,LIBRARY}_DIRS when building " ++ "{CBOR,BEARSSL}_{INCLUDE,LIBRARY}_DIRS when building " + "under msvc") + endif() + set(CBOR_LIBRARIES cbor) +- set(CRYPTO_LIBRARIES crypto-45) ++ set(BEARSSL_LIBRARIES bearssl) + set(MSVC_DISABLED_WARNINGS_LIST + "C4200" # nonstandard extension used: zero-sized array in + # struct/union; +@@ -79,15 +79,19 @@ if(MSVC) + else() + include(FindPkgConfig) + pkg_search_module(CBOR libcbor) +- pkg_search_module(CRYPTO libcrypto REQUIRED) ++ find_library(BEARSSL_LIBRARIES bearssl) ++ find_path(BEARSSL_INCLUDE_DIRS bearssl.h) ++ if(NOT BEARSSL_LIBRARIES OR NOT BEARSSL_INCLUDE_DIRS) ++ message(FATAL_ERROR "could not find BearSSL") ++ endif() + + # XXX workaround libcbor's missing .pc file + if(NOT CBOR_FOUND) +- check_include_files(cbor.h HAVE_CBOR_H) +- if(NOT HAVE_CBOR_H) +- message(FATAL_ERROR "could not find cbor header files") ++ find_library(CBOR_LIBRARIES cbor) ++ find_path(CBOR_INCLUDE_DIRS cbor.h) ++ if(NOT CBOR_LIBRARIES OR NOT CBOR_INCLUDE_DIRS) ++ message(FATAL_ERROR "could not find libcbor") + endif() +- set(CBOR_LIBRARIES "cbor") + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") +@@ -325,10 +329,9 @@ endif() + + include_directories(${CMAKE_SOURCE_DIR}/src) + include_directories(${CBOR_INCLUDE_DIRS}) +-include_directories(${CRYPTO_INCLUDE_DIRS}) ++include_directories(${BEARSSL_INCLUDE_DIRS}) + + link_directories(${CBOR_LIBRARY_DIRS}) +-link_directories(${CRYPTO_LIBRARY_DIRS}) + + message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") + message(STATUS "CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}") +@@ -338,9 +341,8 @@ message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + message(STATUS "CBOR_INCLUDE_DIRS: ${CBOR_INCLUDE_DIRS}") + message(STATUS "CBOR_LIBRARY_DIRS: ${CBOR_LIBRARY_DIRS}") + message(STATUS "CBOR_LIBRARIES: ${CBOR_LIBRARIES}") +-message(STATUS "CRYPTO_INCLUDE_DIRS: ${CRYPTO_INCLUDE_DIRS}") +-message(STATUS "CRYPTO_LIBRARY_DIRS: ${CRYPTO_LIBRARY_DIRS}") +-message(STATUS "CRYPTO_LIBRARIES: ${CRYPTO_LIBRARIES}") ++message(STATUS "BEARSSL_INCLUDE_DIRS: ${BEARSSL_INCLUDE_DIRS}") ++message(STATUS "BEARSSL_LIBRARIES: ${BEARSSL_LIBRARIES}") + message(STATUS "BASE_LIBRARIES: ${BASE_LIBRARIES}") + message(STATUS "VERSION: ${FIDO_VERSION}") + message(STATUS "LIB_VERSION: ${LIB_VERSION}") +@@ -361,8 +363,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + endif() + + subdirs(src) +-subdirs(examples) +-subdirs(tools) ++#subdirs(examples) ++#subdirs(tools) + subdirs(man) + + if(NOT WIN32) +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 926e7f2..69ab5e0 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -55,7 +55,7 @@ list(APPEND COMPAT_SOURCES + + # static library + add_library(fido2 STATIC ${FIDO_SOURCES} ${COMPAT_SOURCES}) +-target_link_libraries(fido2 ${CBOR_LIBRARIES} ${CRYPTO_LIBRARIES} ++target_link_libraries(fido2 ${CBOR_LIBRARIES} ${BEARSSL_LIBRARIES} + ${UDEV_LIBRARIES} ${BASE_LIBRARIES}) + if(WIN32) + if (MINGW) +@@ -73,7 +73,7 @@ install(TARGETS fido2 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + + # dynamic library + add_library(fido2_shared SHARED ${FIDO_SOURCES} ${COMPAT_SOURCES}) +-target_link_libraries(fido2_shared ${CBOR_LIBRARIES} ${CRYPTO_LIBRARIES} ++target_link_libraries(fido2_shared ${CBOR_LIBRARIES} ${BEARSSL_LIBRARIES} + ${UDEV_LIBRARIES} ${BASE_LIBRARIES}) + if(WIN32) + if (MINGW) +diff --git a/src/aes256.c b/src/aes256.c +index 767cdb2..baacc0a 100644 +--- a/src/aes256.c ++++ b/src/aes256.c +@@ -4,7 +4,8 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/evp.h> ++#include <bearssl.h> ++ + #include <string.h> + + #include "fido.h" +@@ -12,38 +13,33 @@ + int + aes256_cbc_enc(const fido_blob_t *key, const fido_blob_t *in, fido_blob_t *out) + { +- EVP_CIPHER_CTX *ctx = NULL; +- unsigned char iv[32]; +- int len; +- int ok = -1; ++ br_aes_ct64_cbcenc_keys ctx; ++ unsigned char iv[32]; ++ int ok = -1; + + memset(iv, 0, sizeof(iv)); + out->ptr = NULL; + out->len = 0; + + /* sanity check */ +- if (in->len > INT_MAX || (in->len % 16) != 0 || +- (out->ptr = calloc(1, in->len)) == NULL) { ++ if ((in->len % 16) != 0 || (out->ptr = calloc(1, in->len)) == NULL) { + fido_log_debug("%s: in->len=%zu", __func__, in->len); + goto fail; + } +- +- if ((ctx = EVP_CIPHER_CTX_new()) == NULL || key->len != 32 || +- !EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key->ptr, iv) || +- !EVP_CIPHER_CTX_set_padding(ctx, 0) || +- !EVP_EncryptUpdate(ctx, out->ptr, &len, in->ptr, (int)in->len) || +- len < 0 || (size_t)len != in->len) { +- fido_log_debug("%s: EVP_Encrypt", __func__); ++ if (key->len != 32) { ++ fido_log_debug("%s: key->len=%zu", __func__, key->len); + goto fail; + } + +- out->len = (size_t)len; ++ memcpy(out->ptr, in->ptr, in->len); ++ br_aes_ct64_cbcenc_init(&ctx, key->ptr, key->len); ++ br_aes_ct64_cbcenc_run(&ctx, iv, out->ptr, out->len); ++ explicit_bzero(&ctx, sizeof(ctx)); ++ ++ out->len = in->len; + + ok = 0; + fail: +- if (ctx != NULL) +- EVP_CIPHER_CTX_free(ctx); +- + if (ok < 0) { + free(out->ptr); + out->ptr = NULL; +@@ -56,38 +52,33 @@ fail: + int + aes256_cbc_dec(const fido_blob_t *key, const fido_blob_t *in, fido_blob_t *out) + { +- EVP_CIPHER_CTX *ctx = NULL; +- unsigned char iv[32]; +- int len; +- int ok = -1; ++ br_aes_ct64_cbcdec_keys ctx; ++ unsigned char iv[32]; ++ int ok = -1; + + memset(iv, 0, sizeof(iv)); + out->ptr = NULL; + out->len = 0; + + /* sanity check */ +- if (in->len > INT_MAX || (in->len % 16) != 0 || +- (out->ptr = calloc(1, in->len)) == NULL) { ++ if ((in->len % 16) != 0 || (out->ptr = calloc(1, in->len)) == NULL) { + fido_log_debug("%s: in->len=%zu", __func__, in->len); + goto fail; + } +- +- if ((ctx = EVP_CIPHER_CTX_new()) == NULL || key->len != 32 || +- !EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key->ptr, iv) || +- !EVP_CIPHER_CTX_set_padding(ctx, 0) || +- !EVP_DecryptUpdate(ctx, out->ptr, &len, in->ptr, (int)in->len) || +- len < 0 || (size_t)len > in->len + 32) { +- fido_log_debug("%s: EVP_Decrypt", __func__); ++ if (key->len != 32) { ++ fido_log_debug("%s: key->len=%zu", __func__, key->len); + goto fail; + } + +- out->len = (size_t)len; ++ memcpy(out->ptr, in->ptr, in->len); ++ br_aes_ct64_cbcdec_init(&ctx, key->ptr, key->len); ++ br_aes_ct64_cbcdec_run(&ctx, iv, out->ptr, out->len); ++ explicit_bzero(&ctx, sizeof(ctx)); ++ ++ out->len = in->len; + + ok = 0; + fail: +- if (ctx != NULL) +- EVP_CIPHER_CTX_free(ctx); +- + if (ok < 0) { + free(out->ptr); + out->ptr = NULL; +diff --git a/src/assert.c b/src/assert.c +index a21b308..fd60037 100644 +--- a/src/assert.c ++++ b/src/assert.c +@@ -4,10 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/ec.h> +-#include <openssl/ecdsa.h> +-#include <openssl/evp.h> +-#include <openssl/sha.h> ++#include <bearssl.h> + + #include <string.h> + #include "fido.h" +@@ -371,7 +368,7 @@ get_signed_hash(int cose_alg, fido_blob_t *dgst, const fido_blob_t *clientdata, + unsigned char *authdata_ptr = NULL; + size_t authdata_len; + struct cbor_load_result cbor; +- SHA256_CTX ctx; ++ br_sha256_context ctx; + int ok = -1; + + if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len, +@@ -385,14 +382,15 @@ get_signed_hash(int cose_alg, fido_blob_t *dgst, const fido_blob_t *clientdata, + authdata_len = cbor_bytestring_length(item); + + if (cose_alg != COSE_EDDSA) { +- if (dgst->len < SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || +- SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 || +- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || +- SHA256_Final(dgst->ptr, &ctx) == 0) { ++ if (dgst->len < br_sha256_SIZE) { + fido_log_debug("%s: sha256", __func__); + goto fail; + } +- dgst->len = SHA256_DIGEST_LENGTH; ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, authdata_ptr, authdata_len); ++ br_sha256_update(&ctx, clientdata->ptr, clientdata->len); ++ br_sha256_out(&ctx, dgst->ptr); ++ dgst->len = br_sha256_SIZE; + } else { + if (SIZE_MAX - authdata_len < clientdata->len || + dgst->len < authdata_len + clientdata->len) { +@@ -417,34 +415,25 @@ int + fido_verify_sig_es256(const fido_blob_t *dgst, const es256_pk_t *pk, + const fido_blob_t *sig) + { +- EVP_PKEY *pkey = NULL; +- EC_KEY *ec = NULL; +- int ok = -1; +- +- /* ECDSA_verify needs ints */ +- if (dgst->len > INT_MAX || sig->len > INT_MAX) { +- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, +- dgst->len, sig->len); +- return (-1); +- } ++ unsigned char q[BR_EC_KBUF_PUB_MAX_SIZE]; ++ br_ec_public_key pkey; ++ int ok = -1; + +- if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL || +- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { +- fido_log_debug("%s: pk -> ec", __func__); +- goto fail; +- } ++ /* BearSSL needs uncompressed format */ ++ q[0] = 4; ++ memcpy(q + 1, pk->x, 32); ++ memcpy(q + 1 + 32, pk->y, 32); ++ pkey.q = q; ++ pkey.qlen = 1 + 32 + 32; + +- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr, +- (int)sig->len, ec) != 1) { +- fido_log_debug("%s: ECDSA_verify", __func__); ++ if (br_ecdsa_vrfy_asn1_get_default()(br_ec_get_default(), dgst->ptr, ++ dgst->len, &pkey, sig->ptr, sig->len) == 0) { ++ fido_log_debug("%s: ECDSA verify", __func__); + goto fail; + } + + ok = 0; + fail: +- if (pkey != NULL) +- EVP_PKEY_free(pkey); +- + return (ok); + } + +@@ -452,34 +441,37 @@ int + fido_verify_sig_rs256(const fido_blob_t *dgst, const rs256_pk_t *pk, + const fido_blob_t *sig) + { +- EVP_PKEY *pkey = NULL; +- RSA *rsa = NULL; +- int ok = -1; +- +- /* RSA_verify needs unsigned ints */ +- if (dgst->len > UINT_MAX || sig->len > UINT_MAX) { +- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, +- dgst->len, sig->len); ++ br_rsa_public_key pkey; ++ unsigned char hash[br_sha256_SIZE]; ++ int ok = -1; ++ ++ /* RSA verify needs SHA256-sized hash */ ++ if (dgst->len != br_sha256_SIZE) { ++ fido_log_debug("%s: dgst->len=%zu", __func__, dgst->len); + return (-1); + } + +- if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL || +- (rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { +- fido_log_debug("%s: pk -> ec", __func__); +- goto fail; +- } ++#ifdef __GNUC__ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wcast-qual" ++#endif ++ pkey.n = (unsigned char *)pk->n; ++ pkey.nlen = sizeof(pk->n); ++ pkey.e = (unsigned char *)pk->e; ++ pkey.elen = sizeof(pk->e); ++#ifdef __GNUC__ ++#pragma GCC diagnostic pop ++#endif + +- if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr, +- (unsigned int)sig->len, rsa) != 1) { ++ if (br_rsa_pkcs1_vrfy_get_default()(sig->ptr, sig->len, ++ BR_HASH_OID_SHA256, dgst->len, &pkey, hash) != 1 || ++ memcmp(dgst->ptr, hash, sizeof(hash)) != 0) { + fido_log_debug("%s: RSA_verify", __func__); + goto fail; + } + + ok = 0; + fail: +- if (pkey != NULL) +- EVP_PKEY_free(pkey); +- + return (ok); + } + +@@ -487,47 +479,12 @@ int + fido_verify_sig_eddsa(const fido_blob_t *dgst, const eddsa_pk_t *pk, + const fido_blob_t *sig) + { +- EVP_PKEY *pkey = NULL; +- EVP_MD_CTX *mdctx = NULL; +- int ok = -1; +- +- /* EVP_DigestVerify needs ints */ +- if (dgst->len > INT_MAX || sig->len > INT_MAX) { +- fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__, +- dgst->len, sig->len); +- return (-1); +- } ++ (void)dgst; ++ (void)pk; ++ (void)sig; + +- if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) { +- fido_log_debug("%s: pk -> pkey", __func__); +- goto fail; +- } +- +- if ((mdctx = EVP_MD_CTX_new()) == NULL) { +- fido_log_debug("%s: EVP_MD_CTX_new", __func__); +- goto fail; +- } +- +- if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) { +- fido_log_debug("%s: EVP_DigestVerifyInit", __func__); +- goto fail; +- } +- +- if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr, +- dgst->len) != 1) { +- fido_log_debug("%s: EVP_DigestVerify", __func__); +- goto fail; +- } +- +- ok = 0; +-fail: +- if (mdctx != NULL) +- EVP_MD_CTX_free(mdctx); +- +- if (pkey != NULL) +- EVP_PKEY_free(pkey); +- +- return (ok); ++ fido_log_debug("%s: EdDSA not implemented", __func__); ++ return (-1); + } + + int +diff --git a/src/cbor.c b/src/cbor.c +index e60e5e3..22d2f8a 100644 +--- a/src/cbor.c ++++ b/src/cbor.c +@@ -4,9 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/evp.h> +-#include <openssl/hmac.h> +-#include <openssl/sha.h> ++#include <bearssl.h> + + #include <string.h> + #include "fido.h" +@@ -590,14 +588,16 @@ cbor_encode_assert_options(fido_opt_t up, fido_opt_t uv) + cbor_item_t * + cbor_encode_pin_auth(const fido_blob_t *hmac_key, const fido_blob_t *data) + { +- const EVP_MD *md = NULL; +- unsigned char dgst[SHA256_DIGEST_LENGTH]; +- unsigned int dgst_len; ++ br_hmac_context ctx; ++ br_hmac_key_context kc; ++ unsigned char dgst[br_sha256_SIZE]; + +- if ((md = EVP_sha256()) == NULL || HMAC(md, hmac_key->ptr, +- (int)hmac_key->len, data->ptr, (int)data->len, dgst, +- &dgst_len) == NULL || dgst_len != SHA256_DIGEST_LENGTH) +- return (NULL); ++ br_hmac_key_init(&kc, &br_sha256_vtable, hmac_key->ptr, hmac_key->len); ++ br_hmac_init(&ctx, &kc, 0); ++ br_hmac_update(&ctx, data->ptr, data->len); ++ br_hmac_out(&ctx, dgst); ++ explicit_bzero(&kc, sizeof(kc)); ++ explicit_bzero(&ctx, sizeof(ctx)); + + return (cbor_build_bytestring(dgst, 16)); + } +@@ -626,17 +626,16 @@ cbor_encode_pin_enc(const fido_blob_t *key, const fido_blob_t *pin) + static int + sha256(const unsigned char *data, size_t data_len, fido_blob_t *digest) + { +- if ((digest->ptr = calloc(1, SHA256_DIGEST_LENGTH)) == NULL) ++ br_sha256_context ctx; ++ ++ if ((digest->ptr = calloc(1, br_sha256_SIZE)) == NULL) + return (-1); + +- digest->len = SHA256_DIGEST_LENGTH; ++ digest->len = br_sha256_SIZE; + +- if (SHA256(data, data_len, digest->ptr) != digest->ptr) { +- free(digest->ptr); +- digest->ptr = NULL; +- digest->len = 0; +- return (-1); +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, data, data_len); ++ br_sha256_out(&ctx, digest->ptr); + + return (0); + } +@@ -645,15 +644,10 @@ cbor_item_t * + cbor_encode_change_pin_auth(const fido_blob_t *key, const fido_blob_t *new_pin, + const fido_blob_t *pin) + { +- unsigned char dgst[SHA256_DIGEST_LENGTH]; +- unsigned int dgst_len; ++ unsigned char dgst[br_sha256_SIZE]; + cbor_item_t *item = NULL; +- const EVP_MD *md = NULL; +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- HMAC_CTX ctx; +-#else +- HMAC_CTX *ctx = NULL; +-#endif ++ br_hmac_context ctx; ++ br_hmac_key_context kc; + fido_blob_t *npe = NULL; /* new pin, encrypted */ + fido_blob_t *ph = NULL; /* pin hash */ + fido_blob_t *phe = NULL; /* pin hash, encrypted */ +@@ -681,28 +675,13 @@ cbor_encode_change_pin_auth(const fido_blob_t *key, const fido_blob_t *new_pin, + goto fail; + } + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- HMAC_CTX_init(&ctx); +- +- if ((md = EVP_sha256()) == NULL || +- HMAC_Init_ex(&ctx, key->ptr, (int)key->len, md, NULL) == 0 || +- HMAC_Update(&ctx, npe->ptr, (int)npe->len) == 0 || +- HMAC_Update(&ctx, phe->ptr, (int)phe->len) == 0 || +- HMAC_Final(&ctx, dgst, &dgst_len) == 0 || dgst_len != 32) { +- fido_log_debug("%s: HMAC", __func__); +- goto fail; +- } +-#else +- if ((ctx = HMAC_CTX_new()) == NULL || +- (md = EVP_sha256()) == NULL || +- HMAC_Init_ex(ctx, key->ptr, (int)key->len, md, NULL) == 0 || +- HMAC_Update(ctx, npe->ptr, (int)npe->len) == 0 || +- HMAC_Update(ctx, phe->ptr, (int)phe->len) == 0 || +- HMAC_Final(ctx, dgst, &dgst_len) == 0 || dgst_len != 32) { +- fido_log_debug("%s: HMAC", __func__); +- goto fail; +- } +-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ ++ br_hmac_key_init(&kc, &br_sha256_vtable, key->ptr, key->len); ++ br_hmac_init(&ctx, &kc, 0); ++ br_hmac_update(&ctx, npe->ptr, npe->len); ++ br_hmac_update(&ctx, phe->ptr, phe->len); ++ br_hmac_out(&ctx, dgst); ++ explicit_bzero(&kc, sizeof(kc)); ++ explicit_bzero(&ctx, sizeof(ctx)); + + if ((item = cbor_build_bytestring(dgst, 16)) == NULL) { + fido_log_debug("%s: cbor_build_bytestring", __func__); +@@ -715,11 +694,6 @@ fail: + fido_blob_free(&ph); + fido_blob_free(&phe); + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L +- if (ctx != NULL) +- HMAC_CTX_free(ctx); +-#endif +- + if (ok < 0) { + if (item != NULL) { + cbor_decref(&item); +@@ -733,9 +707,9 @@ fail: + cbor_item_t * + cbor_encode_set_pin_auth(const fido_blob_t *key, const fido_blob_t *pin) + { +- const EVP_MD *md = NULL; +- unsigned char dgst[SHA256_DIGEST_LENGTH]; +- unsigned int dgst_len; ++ br_hmac_context ctx; ++ br_hmac_key_context kc; ++ unsigned char dgst[br_sha256_SIZE]; + cbor_item_t *item = NULL; + fido_blob_t *pe = NULL; + +@@ -747,12 +721,12 @@ cbor_encode_set_pin_auth(const fido_blob_t *key, const fido_blob_t *pin) + goto fail; + } + +- if ((md = EVP_sha256()) == NULL || key->len != 32 || HMAC(md, key->ptr, +- (int)key->len, pe->ptr, (int)pe->len, dgst, &dgst_len) == NULL || +- dgst_len != SHA256_DIGEST_LENGTH) { +- fido_log_debug("%s: HMAC", __func__); +- goto fail; +- } ++ br_hmac_key_init(&kc, &br_sha256_vtable, key->ptr, key->len); ++ br_hmac_init(&ctx, &kc, 0); ++ br_hmac_update(&ctx, pe->ptr, pe->len); ++ br_hmac_out(&ctx, dgst); ++ explicit_bzero(&kc, sizeof(kc)); ++ explicit_bzero(&ctx, sizeof(ctx)); + + item = cbor_build_bytestring(dgst, 16); + fail: +diff --git a/src/cred.c b/src/cred.c +index c4e1edb..77d1615 100644 +--- a/src/cred.c ++++ b/src/cred.c +@@ -4,10 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/ec.h> +-#include <openssl/evp.h> +-#include <openssl/sha.h> +-#include <openssl/x509.h> ++#include <bearssl.h> + + #include <string.h> + #include "fido.h" +@@ -193,18 +190,17 @@ check_extensions(int authdata_ext, int ext) + int + fido_check_rp_id(const char *id, const unsigned char *obtained_hash) + { +- unsigned char expected_hash[SHA256_DIGEST_LENGTH]; ++ br_sha256_context ctx; ++ unsigned char expected_hash[br_sha256_SIZE]; + + explicit_bzero(expected_hash, sizeof(expected_hash)); + +- if (SHA256((const unsigned char *)id, strlen(id), +- expected_hash) != expected_hash) { +- fido_log_debug("%s: sha256", __func__); +- return (-1); +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, id, strlen(id)); ++ br_sha256_out(&ctx, expected_hash); + + return (timingsafe_bcmp(expected_hash, obtained_hash, +- SHA256_DIGEST_LENGTH)); ++ br_sha256_SIZE)); + } + + static int +@@ -215,7 +211,7 @@ get_signed_hash_packed(fido_blob_t *dgst, const fido_blob_t *clientdata, + unsigned char *authdata_ptr = NULL; + size_t authdata_len; + struct cbor_load_result cbor; +- SHA256_CTX ctx; ++ br_sha256_context ctx; + int ok = -1; + + if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len, +@@ -233,13 +229,14 @@ get_signed_hash_packed(fido_blob_t *dgst, const fido_blob_t *clientdata, + authdata_ptr = cbor_bytestring_handle(item); + authdata_len = cbor_bytestring_length(item); + +- if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || +- SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 || +- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || +- SHA256_Final(dgst->ptr, &ctx) == 0) { ++ if (dgst->len != br_sha256_SIZE) { + fido_log_debug("%s: sha256", __func__); + goto fail; + } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, authdata_ptr, authdata_len); ++ br_sha256_update(&ctx, clientdata->ptr, clientdata->len); ++ br_sha256_out(&ctx, dgst->ptr); + + ok = 0; + fail: +@@ -256,21 +253,23 @@ get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id, + { + const uint8_t zero = 0; + const uint8_t four = 4; /* uncompressed point */ +- SHA256_CTX ctx; +- +- if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || +- SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 || +- SHA256_Update(&ctx, rp_id, rp_id_len) == 0 || +- SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || +- SHA256_Update(&ctx, id->ptr, id->len) == 0 || +- SHA256_Update(&ctx, &four, sizeof(four)) == 0 || +- SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 || +- SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 || +- SHA256_Final(dgst->ptr, &ctx) == 0) { ++ br_sha256_context ctx; ++ ++ if (dgst->len != br_sha256_SIZE) { + fido_log_debug("%s: sha256", __func__); + return (-1); + } + ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, &zero, sizeof(zero)); ++ br_sha256_update(&ctx, rp_id, rp_id_len); ++ br_sha256_update(&ctx, clientdata->ptr, clientdata->len); ++ br_sha256_update(&ctx, id->ptr, id->len); ++ br_sha256_update(&ctx, &four, sizeof(four)); ++ br_sha256_update(&ctx, pk->x, sizeof(pk->x)); ++ br_sha256_update(&ctx, pk->y, sizeof(pk->y)); ++ br_sha256_out(&ctx, dgst->ptr); ++ + return (0); + } + +@@ -278,42 +277,29 @@ static int + verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c, + const fido_blob_t *sig) + { +- BIO *rawcert = NULL; +- X509 *cert = NULL; +- EVP_PKEY *pkey = NULL; +- EC_KEY *ec; +- int ok = -1; +- +- /* openssl needs ints */ +- if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) { +- fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu", +- __func__, dgst->len, x5c->len, sig->len); +- return (-1); +- } ++ br_x509_decoder_context ctx; ++ br_x509_pkey *pkey; ++ int ok = -1; + + /* fetch key from x509 */ +- if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL || +- (cert = d2i_X509_bio(rawcert, NULL)) == NULL || +- (pkey = X509_get_pubkey(cert)) == NULL || +- (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { ++ br_x509_decoder_init(&ctx, NULL, NULL); ++ br_x509_decoder_push(&ctx, x5c->ptr, x5c->len); ++ if (br_x509_decoder_last_error(&ctx) != 0 || ++ (pkey = br_x509_decoder_get_pkey(&ctx)) == NULL || ++ pkey->key_type != BR_KEYTYPE_EC) { + fido_log_debug("%s: x509 key", __func__); + goto fail; + } + +- if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr, +- (int)sig->len, ec) != 1) { +- fido_log_debug("%s: ECDSA_verify", __func__); ++ if (br_ecdsa_vrfy_asn1_get_default()(br_ec_get_default(), dgst->ptr, ++ dgst->len, &pkey->key.ec, sig->ptr, sig->len) == 0) { ++ fido_log_debug("%s: ECDSA verify", __func__); + goto fail; + } + + ok = 0; + fail: +- if (rawcert != NULL) +- BIO_free(rawcert); +- if (cert != NULL) +- X509_free(cert); +- if (pkey != NULL) +- EVP_PKEY_free(pkey); ++ explicit_bzero(&ctx, sizeof(ctx)); + + return (ok); + } +@@ -321,7 +307,7 @@ fail: + int + fido_cred_verify(const fido_cred_t *cred) + { +- unsigned char buf[SHA256_DIGEST_LENGTH]; ++ unsigned char buf[br_sha256_SIZE]; + fido_blob_t dgst; + int r; + +@@ -395,7 +381,7 @@ out: + int + fido_cred_verify_self(const fido_cred_t *cred) + { +- unsigned char buf[SHA256_DIGEST_LENGTH]; ++ unsigned char buf[br_sha256_SIZE]; + fido_blob_t dgst; + int ok = -1; + int r; +diff --git a/src/credman.c b/src/credman.c +index 76327e5..6b8eeed 100644 +--- a/src/credman.c ++++ b/src/credman.c +@@ -4,7 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/sha.h> ++#include <bearssl.h> + + #include <string.h> + +@@ -369,14 +369,14 @@ static int + credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk, + const char *pin, int ms) + { +- fido_blob_t rp_dgst; +- uint8_t dgst[SHA256_DIGEST_LENGTH]; +- int r; ++ fido_blob_t rp_dgst; ++ br_sha256_context ctx; ++ uint8_t dgst[br_sha256_SIZE]; ++ int r; + +- if (SHA256((const unsigned char *)rp_id, strlen(rp_id), dgst) != dgst) { +- fido_log_debug("%s: sha256", __func__); +- return (FIDO_ERR_INTERNAL); +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, rp_id, strlen(rp_id)); ++ br_sha256_out(&ctx, dgst); + + rp_dgst.ptr = dgst; + rp_dgst.len = sizeof(dgst); +diff --git a/src/ecdh.c b/src/ecdh.c +index 7f25c7b..7576ae4 100644 +--- a/src/ecdh.c ++++ b/src/ecdh.c +@@ -4,8 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/evp.h> +-#include <openssl/sha.h> ++#include <bearssl.h> + + #include "fido.h" + #include "fido/es256.h" +@@ -13,63 +12,43 @@ + static int + do_ecdh(const es256_sk_t *sk, const es256_pk_t *pk, fido_blob_t **ecdh) + { +- EVP_PKEY *pk_evp = NULL; +- EVP_PKEY *sk_evp = NULL; +- EVP_PKEY_CTX *ctx = NULL; +- fido_blob_t *secret = NULL; +- int ok = -1; ++ unsigned char q[65]; ++ br_sha256_context ctx; ++ int ok = -1; + + *ecdh = NULL; + + /* allocate blobs for secret & ecdh */ +- if ((secret = fido_blob_new()) == NULL || +- (*ecdh = fido_blob_new()) == NULL) ++ if ((*ecdh = fido_blob_new()) == NULL) + goto fail; + +- /* wrap the keys as openssl objects */ +- if ((pk_evp = es256_pk_to_EVP_PKEY(pk)) == NULL || +- (sk_evp = es256_sk_to_EVP_PKEY(sk)) == NULL) { +- fido_log_debug("%s: es256_to_EVP_PKEY", __func__); +- goto fail; +- } +- +- /* set ecdh parameters */ +- if ((ctx = EVP_PKEY_CTX_new(sk_evp, NULL)) == NULL || +- EVP_PKEY_derive_init(ctx) <= 0 || +- EVP_PKEY_derive_set_peer(ctx, pk_evp) <= 0) { +- fido_log_debug("%s: EVP_PKEY_derive_init", __func__); +- goto fail; +- } ++ q[0] = 4; ++ memcpy(q + 1, pk->x, 32); ++ memcpy(q + 1 + 32, pk->y, 32); + + /* perform ecdh */ +- if (EVP_PKEY_derive(ctx, NULL, &secret->len) <= 0 || +- (secret->ptr = calloc(1, secret->len)) == NULL || +- EVP_PKEY_derive(ctx, secret->ptr, &secret->len) <= 0) { +- fido_log_debug("%s: EVP_PKEY_derive", __func__); ++ if (br_ec_get_default()->mul(q, sizeof(q), sk->d, sizeof(sk->d), ++ BR_EC_secp256r1) != 1) { ++ fido_log_debug("%s: ECDH", __func__); + goto fail; + } + + /* use sha256 as a kdf on the resulting secret */ +- (*ecdh)->len = SHA256_DIGEST_LENGTH; +- if (((*ecdh)->ptr = calloc(1, (*ecdh)->len)) == NULL || +- SHA256(secret->ptr, secret->len, (*ecdh)->ptr) != (*ecdh)->ptr) { ++ (*ecdh)->len = br_sha256_SIZE; ++ if (((*ecdh)->ptr = calloc(1, (*ecdh)->len)) == NULL) { + fido_log_debug("%s: sha256", __func__); + goto fail; + } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, q + 1, 32); ++ br_sha256_out(&ctx, (*ecdh)->ptr); + + ok = 0; + fail: +- if (pk_evp != NULL) +- EVP_PKEY_free(pk_evp); +- if (sk_evp != NULL) +- EVP_PKEY_free(sk_evp); +- if (ctx != NULL) +- EVP_PKEY_CTX_free(ctx); ++ explicit_bzero(q, sizeof(q)); + if (ok < 0) + fido_blob_free(ecdh); + +- fido_blob_free(&secret); +- + return (ok); + } + +diff --git a/src/eddsa.c b/src/eddsa.c +index 92a0222..252e7ec 100644 +--- a/src/eddsa.c ++++ b/src/eddsa.c +@@ -4,67 +4,10 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/bn.h> +-#include <openssl/ec.h> +-#include <openssl/evp.h> +-#include <openssl/obj_mac.h> +- + #include <string.h> + #include "fido.h" + #include "fido/eddsa.h" + +-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L +-EVP_PKEY * +-EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *key, +- size_t keylen) +-{ +- (void)type; +- (void)e; +- (void)key; +- (void)keylen; +- +- return (NULL); +-} +- +-int +-EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, +- size_t *len) +-{ +- (void)pkey; +- (void)pub; +- (void)len; +- +- return (0); +-} +- +-int +-EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, +- const unsigned char *tbs, size_t tbslen) +-{ +- (void)ctx; +- (void)sigret; +- (void)siglen; +- (void)tbs; +- (void)tbslen; +- +- return (0); +-} +-#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */ +- +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-EVP_MD_CTX * +-EVP_MD_CTX_new(void) +-{ +- return (NULL); +-} +- +-void +-EVP_MD_CTX_free(EVP_MD_CTX *ctx) +-{ +- (void)ctx; +-} +-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +- + static int + decode_coord(const cbor_item_t *item, void *xy, size_t xy_len) + { +@@ -140,30 +83,3 @@ eddsa_pk_from_ptr(eddsa_pk_t *pk, const void *ptr, size_t len) + + return (FIDO_OK); + } +- +-EVP_PKEY * +-eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *k) +-{ +- EVP_PKEY *pkey = NULL; +- +- if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, k->x, +- sizeof(k->x))) == NULL) +- fido_log_debug("%s: EVP_PKEY_new_raw_public_key", __func__); +- +- return (pkey); +-} +- +-int +-eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey) +-{ +- size_t len = 0; +- +- if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1 || +- len != sizeof(pk->x)) +- return (FIDO_ERR_INTERNAL); +- if (EVP_PKEY_get_raw_public_key(pkey, pk->x, &len) != 1 || +- len != sizeof(pk->x)) +- return (FIDO_ERR_INTERNAL); +- +- return (FIDO_OK); +-} +diff --git a/src/es256.c b/src/es256.c +index c8fd9f4..4b04a6b 100644 +--- a/src/es256.c ++++ b/src/es256.c +@@ -4,10 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/bn.h> +-#include <openssl/ec.h> +-#include <openssl/evp.h> +-#include <openssl/obj_mac.h> ++#include <bearssl.h> + + #include <string.h> + #include "fido.h" +@@ -203,232 +200,64 @@ es256_pk_set_y(es256_pk_t *pk, const unsigned char *y) + int + es256_sk_create(es256_sk_t *key) + { +- EVP_PKEY_CTX *pctx = NULL; +- EVP_PKEY_CTX *kctx = NULL; +- EVP_PKEY *p = NULL; +- EVP_PKEY *k = NULL; +- const EC_KEY *ec; +- const BIGNUM *d; +- const int nid = NID_X9_62_prime256v1; +- int n; +- int ok = -1; +- +- if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL || +- EVP_PKEY_paramgen_init(pctx) <= 0 || +- EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0 || +- EVP_PKEY_paramgen(pctx, &p) <= 0) { +- fido_log_debug("%s: EVP_PKEY_paramgen", __func__); +- goto fail; +- } +- +- if ((kctx = EVP_PKEY_CTX_new(p, NULL)) == NULL || +- EVP_PKEY_keygen_init(kctx) <= 0 || EVP_PKEY_keygen(kctx, &k) <= 0) { +- fido_log_debug("%s: EVP_PKEY_keygen", __func__); +- goto fail; +- } +- +- if ((ec = EVP_PKEY_get0_EC_KEY(k)) == NULL || +- (d = EC_KEY_get0_private_key(ec)) == NULL || +- (n = BN_num_bytes(d)) < 0 || (size_t)n > sizeof(key->d) || +- (n = BN_bn2bin(d, key->d)) < 0 || (size_t)n > sizeof(key->d)) { +- fido_log_debug("%s: EC_KEY_get0_private_key", __func__); +- goto fail; +- } +- +- ok = 0; +-fail: +- if (p != NULL) +- EVP_PKEY_free(p); +- if (k != NULL) +- EVP_PKEY_free(k); +- if (pctx != NULL) +- EVP_PKEY_CTX_free(pctx); +- if (kctx != NULL) +- EVP_PKEY_CTX_free(kctx); +- +- return (ok); +-} +- +-EVP_PKEY * +-es256_pk_to_EVP_PKEY(const es256_pk_t *k) +-{ +- BN_CTX *bnctx = NULL; +- EC_KEY *ec = NULL; +- EC_POINT *q = NULL; +- EVP_PKEY *pkey = NULL; +- BIGNUM *x = NULL; +- BIGNUM *y = NULL; +- const EC_GROUP *g = NULL; +- const int nid = NID_X9_62_prime256v1; +- int ok = -1; +- +- if ((bnctx = BN_CTX_new()) == NULL || +- (x = BN_CTX_get(bnctx)) == NULL || +- (y = BN_CTX_get(bnctx)) == NULL) +- goto fail; +- +- if (BN_bin2bn(k->x, sizeof(k->x), x) == NULL || +- BN_bin2bn(k->y, sizeof(k->y), y) == NULL) { +- fido_log_debug("%s: BN_bin2bn", __func__); +- goto fail; +- } ++ br_prng_seeder seeder; ++ br_hmac_drbg_context rng; ++ br_ec_private_key skey; ++ unsigned char kbuf[BR_EC_KBUF_PRIV_MAX_SIZE]; ++ int ok = -1; + +- if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL || +- (g = EC_KEY_get0_group(ec)) == NULL) { +- fido_log_debug("%s: EC_KEY init", __func__); ++ if ((seeder = br_prng_seeder_system(NULL)) == NULL) { ++ fido_log_debug("%s: no PRNG seeder", __func__); + goto fail; + } +- +- if ((q = EC_POINT_new(g)) == NULL || +- EC_POINT_set_affine_coordinates_GFp(g, q, x, y, bnctx) == 0 || +- EC_KEY_set_public_key(ec, q) == 0) { +- fido_log_debug("%s: EC_KEY_set_public_key", __func__); ++ br_hmac_drbg_init(&rng, &br_sha256_vtable, NULL, 0); ++ if (seeder(&rng.vtable) == 0) { ++ fido_log_debug("%s: seed PRNG", __func__); + goto fail; + } +- +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_assign_EC_KEY(pkey, ec) == 0) { +- fido_log_debug("%s: EVP_PKEY_assign_EC_KEY", __func__); ++ if (br_ec_keygen(&rng.vtable, br_ec_get_default(), &skey, kbuf, ++ BR_EC_secp256r1) != sizeof(key->d)) { ++ fido_log_debug("%s: EC keygen", __func__); + goto fail; + } +- +- ec = NULL; /* at this point, ec belongs to evp */ ++ memcpy(key->d, skey.x, sizeof(key->d)); ++ explicit_bzero(&skey, sizeof(skey)); ++ explicit_bzero(kbuf, sizeof(kbuf)); + + ok = 0; + fail: +- if (bnctx != NULL) +- BN_CTX_free(bnctx); +- if (ec != NULL) +- EC_KEY_free(ec); +- if (q != NULL) +- EC_POINT_free(q); +- if (ok < 0 && pkey != NULL) { +- EVP_PKEY_free(pkey); +- pkey = NULL; +- } +- +- return (pkey); +-} +- +-int +-es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec) +-{ +- BN_CTX *ctx = NULL; +- BIGNUM *x = NULL; +- BIGNUM *y = NULL; +- const EC_POINT *q = NULL; +- const EC_GROUP *g = NULL; +- int ok = FIDO_ERR_INTERNAL; +- int n; +- +- if ((q = EC_KEY_get0_public_key(ec)) == NULL || +- (g = EC_KEY_get0_group(ec)) == NULL) +- goto fail; +- +- if ((ctx = BN_CTX_new()) == NULL || +- (x = BN_CTX_get(ctx)) == NULL || +- (y = BN_CTX_get(ctx)) == NULL) +- goto fail; +- +- if (EC_POINT_get_affine_coordinates_GFp(g, q, x, y, ctx) == 0 || +- (n = BN_num_bytes(x)) < 0 || (size_t)n > sizeof(pk->x) || +- (n = BN_num_bytes(y)) < 0 || (size_t)n > sizeof(pk->y)) { +- fido_log_debug("%s: EC_POINT_get_affine_coordinates_GFp", +- __func__); +- goto fail; +- } +- +- if ((n = BN_bn2bin(x, pk->x)) < 0 || (size_t)n > sizeof(pk->x) || +- (n = BN_bn2bin(y, pk->y)) < 0 || (size_t)n > sizeof(pk->y)) { +- fido_log_debug("%s: BN_bn2bin", __func__); +- goto fail; +- } +- +- ok = FIDO_OK; +-fail: +- if (ctx != NULL) +- BN_CTX_free(ctx); +- + return (ok); + } + +-EVP_PKEY * +-es256_sk_to_EVP_PKEY(const es256_sk_t *k) +-{ +- BN_CTX *bnctx = NULL; +- EC_KEY *ec = NULL; +- EVP_PKEY *pkey = NULL; +- BIGNUM *d = NULL; +- const int nid = NID_X9_62_prime256v1; +- int ok = -1; +- +- if ((bnctx = BN_CTX_new()) == NULL || (d = BN_CTX_get(bnctx)) == NULL || +- BN_bin2bn(k->d, sizeof(k->d), d) == NULL) { +- fido_log_debug("%s: BN_bin2bn", __func__); +- goto fail; +- } +- +- if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL || +- EC_KEY_set_private_key(ec, d) == 0) { +- fido_log_debug("%s: EC_KEY_set_private_key", __func__); +- goto fail; +- } +- +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_assign_EC_KEY(pkey, ec) == 0) { +- fido_log_debug("%s: EVP_PKEY_assign_EC_KEY", __func__); +- goto fail; +- } +- +- ec = NULL; /* at this point, ec belongs to evp */ +- +- ok = 0; +-fail: +- if (bnctx != NULL) +- BN_CTX_free(bnctx); +- if (ec != NULL) +- EC_KEY_free(ec); +- if (ok < 0 && pkey != NULL) { +- EVP_PKEY_free(pkey); +- pkey = NULL; +- } +- +- return (pkey); +-} +- + int + es256_derive_pk(const es256_sk_t *sk, es256_pk_t *pk) + { +- BIGNUM *d = NULL; +- EC_KEY *ec = NULL; +- EC_POINT *q = NULL; +- const EC_GROUP *g = NULL; +- const int nid = NID_X9_62_prime256v1; +- int ok = -1; +- +- if ((d = BN_bin2bn(sk->d, (int)sizeof(sk->d), NULL)) == NULL || +- (ec = EC_KEY_new_by_curve_name(nid)) == NULL || +- (g = EC_KEY_get0_group(ec)) == NULL || +- (q = EC_POINT_new(g)) == NULL) { +- fido_log_debug("%s: get", __func__); +- goto fail; +- } +- +- if (EC_POINT_mul(g, q, d, NULL, NULL, NULL) == 0 || +- EC_KEY_set_public_key(ec, q) == 0 || +- es256_pk_from_EC_KEY(pk, ec) != FIDO_OK) { +- fido_log_debug("%s: set", __func__); ++ br_ec_private_key skey; ++ br_ec_public_key pkey; ++ unsigned char kbuf[BR_EC_KBUF_PUB_MAX_SIZE]; ++ int ok = -1; ++ ++ skey.curve = BR_EC_secp256r1; ++#ifdef __GNUC__ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wcast-qual" ++#endif ++ skey.x = (unsigned char *)sk->d; ++ skey.xlen = sizeof(sk->d); ++#ifdef __GNUC__ ++#pragma GCC diagnostic pop ++#endif ++ if (br_ec_compute_pub(br_ec_get_default(), &pkey, kbuf, &skey) != 65 || ++ pkey.q[0] != 4 || ++ es256_pk_set_x(pk, pkey.q + 1) != 0 || ++ es256_pk_set_y(pk, pkey.q + 1 + 32) != 0) { ++ fido_log_debug("%s: EC compute pub", __func__); + goto fail; + } + + ok = 0; + fail: +- if (d != NULL) +- BN_clear_free(d); +- if (q != NULL) +- EC_POINT_free(q); +- if (ec != NULL) +- EC_KEY_free(ec); ++ explicit_bzero(kbuf, sizeof(kbuf)); + + return (ok); + } +diff --git a/src/fido.h b/src/fido.h +index f85a41a..7d3d71e 100644 +--- a/src/fido.h ++++ b/src/fido.h +@@ -7,9 +7,6 @@ + #ifndef _FIDO_H + #define _FIDO_H + +-#include <openssl/ec.h> +-#include <openssl/evp.h> +- + #include <stdbool.h> + #include <stdint.h> + #include <stdlib.h> +diff --git a/src/fido/eddsa.h b/src/fido/eddsa.h +index 9de272d..d85d05a 100644 +--- a/src/fido/eddsa.h ++++ b/src/fido/eddsa.h +@@ -7,34 +7,12 @@ + #ifndef _FIDO_EDDSA_H + #define _FIDO_EDDSA_H + +-#include <openssl/ec.h> +- + #include <stdint.h> + #include <stdlib.h> + + eddsa_pk_t *eddsa_pk_new(void); + void eddsa_pk_free(eddsa_pk_t **); +-EVP_PKEY *eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *); + +-int eddsa_pk_from_EVP_PKEY(eddsa_pk_t *, const EVP_PKEY *); + int eddsa_pk_from_ptr(eddsa_pk_t *, const void *, size_t); + +-#ifdef _FIDO_INTERNAL +- +-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L +-#define EVP_PKEY_ED25519 EVP_PKEY_NONE +-int EVP_PKEY_get_raw_public_key(const EVP_PKEY *, unsigned char *, size_t *); +-EVP_PKEY *EVP_PKEY_new_raw_public_key(int, ENGINE *, const unsigned char *, +- size_t); +-int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t, +- const unsigned char *, size_t); +-#endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */ +- +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-EVP_MD_CTX *EVP_MD_CTX_new(void); +-void EVP_MD_CTX_free(EVP_MD_CTX *); +-#endif +- +-#endif /* _FIDO_INTERNAL */ +- + #endif /* !_FIDO_EDDSA_H */ +diff --git a/src/fido/es256.h b/src/fido/es256.h +index d3d13dd..5ed7be1 100644 +--- a/src/fido/es256.h ++++ b/src/fido/es256.h +@@ -7,22 +7,17 @@ + #ifndef _FIDO_ES256_H + #define _FIDO_ES256_H + +-#include <openssl/ec.h> +- + #include <stdint.h> + #include <stdlib.h> + + es256_pk_t *es256_pk_new(void); + void es256_pk_free(es256_pk_t **); +-EVP_PKEY *es256_pk_to_EVP_PKEY(const es256_pk_t *); + +-int es256_pk_from_EC_KEY(es256_pk_t *, const EC_KEY *); + int es256_pk_from_ptr(es256_pk_t *, const void *, size_t); + + #ifdef _FIDO_INTERNAL + es256_sk_t *es256_sk_new(void); + void es256_sk_free(es256_sk_t **); +-EVP_PKEY *es256_sk_to_EVP_PKEY(const es256_sk_t *); + + int es256_derive_pk(const es256_sk_t *, es256_pk_t *); + int es256_sk_create(es256_sk_t *); +diff --git a/src/fido/rs256.h b/src/fido/rs256.h +index d2fa162..eb84e89 100644 +--- a/src/fido/rs256.h ++++ b/src/fido/rs256.h +@@ -7,16 +7,12 @@ + #ifndef _FIDO_RS256_H + #define _FIDO_RS256_H + +-#include <openssl/rsa.h> +- + #include <stdint.h> + #include <stdlib.h> + + rs256_pk_t *rs256_pk_new(void); + void rs256_pk_free(rs256_pk_t **); +-EVP_PKEY *rs256_pk_to_EVP_PKEY(const rs256_pk_t *); + +-int rs256_pk_from_RSA(rs256_pk_t *, const RSA *); + int rs256_pk_from_ptr(rs256_pk_t *, const void *, size_t); + + #endif /* !_FIDO_RS256_H */ +diff --git a/src/rs256.c b/src/rs256.c +index 9f30163..c9da648 100644 +--- a/src/rs256.c ++++ b/src/rs256.c +@@ -4,41 +4,12 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/bn.h> +-#include <openssl/rsa.h> +-#include <openssl/evp.h> +-#include <openssl/obj_mac.h> ++#include <bearssl.h> + + #include <string.h> + #include "fido.h" + #include "fido/rs256.h" + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-static int +-RSA_bits(const RSA *r) +-{ +- return (BN_num_bits(r->n)); +-} +- +-static int +-RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +-{ +- r->n = n; +- r->e = e; +- r->d = d; +- +- return (1); +-} +- +-static void +-RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +-{ +- *n = r->n; +- *e = r->e; +- *d = r->d; +-} +-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +- + static int + decode_bignum(const cbor_item_t *item, void *ptr, size_t len) + { +@@ -116,89 +87,3 @@ rs256_pk_from_ptr(rs256_pk_t *pk, const void *ptr, size_t len) + + return (FIDO_OK); + } +- +-EVP_PKEY * +-rs256_pk_to_EVP_PKEY(const rs256_pk_t *k) +-{ +- RSA *rsa = NULL; +- EVP_PKEY *pkey = NULL; +- BIGNUM *n = NULL; +- BIGNUM *e = NULL; +- int ok = -1; +- +- if ((n = BN_new()) == NULL || (e = BN_new()) == NULL) +- goto fail; +- +- if (BN_bin2bn(k->n, sizeof(k->n), n) == NULL || +- BN_bin2bn(k->e, sizeof(k->e), e) == NULL) { +- fido_log_debug("%s: BN_bin2bn", __func__); +- goto fail; +- } +- +- if ((rsa = RSA_new()) == NULL || RSA_set0_key(rsa, n, e, NULL) == 0) { +- fido_log_debug("%s: RSA_set0_key", __func__); +- goto fail; +- } +- +- /* at this point, n and e belong to rsa */ +- n = NULL; +- e = NULL; +- +- if ((pkey = EVP_PKEY_new()) == NULL || +- EVP_PKEY_assign_RSA(pkey, rsa) == 0) { +- fido_log_debug("%s: EVP_PKEY_assign_RSA", __func__); +- goto fail; +- } +- +- rsa = NULL; /* at this point, rsa belongs to evp */ +- +- ok = 0; +-fail: +- if (n != NULL) +- BN_free(n); +- if (e != NULL) +- BN_free(e); +- if (rsa != NULL) +- RSA_free(rsa); +- if (ok < 0 && pkey != NULL) { +- EVP_PKEY_free(pkey); +- pkey = NULL; +- } +- +- return (pkey); +-} +- +-int +-rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa) +-{ +- const BIGNUM *n = NULL; +- const BIGNUM *e = NULL; +- const BIGNUM *d = NULL; +- int k; +- +- if (RSA_bits(rsa) != 2048) { +- fido_log_debug("%s: invalid key length", __func__); +- return (FIDO_ERR_INVALID_ARGUMENT); +- } +- +- RSA_get0_key(rsa, &n, &e, &d); +- +- if (n == NULL || e == NULL) { +- fido_log_debug("%s: RSA_get0_key", __func__); +- return (FIDO_ERR_INTERNAL); +- } +- +- if ((k = BN_num_bytes(n)) < 0 || (size_t)k > sizeof(pk->n) || +- (k = BN_num_bytes(e)) < 0 || (size_t)k > sizeof(pk->e)) { +- fido_log_debug("%s: invalid key", __func__); +- return (FIDO_ERR_INTERNAL); +- } +- +- if ((k = BN_bn2bin(n, pk->n)) < 0 || (size_t)k > sizeof(pk->n) || +- (k = BN_bn2bin(e, pk->e)) < 0 || (size_t)k > sizeof(pk->e)) { +- fido_log_debug("%s: BN_bn2bin", __func__); +- return (FIDO_ERR_INTERNAL); +- } +- +- return (FIDO_OK); +-} +diff --git a/src/u2f.c b/src/u2f.c +index e02b611..56f93f1 100644 +--- a/src/u2f.c ++++ b/src/u2f.c +@@ -4,8 +4,7 @@ + * license that can be found in the LICENSE file. + */ + +-#include <openssl/sha.h> +-#include <openssl/x509.h> ++#include <bearssl.h> + + #include <string.h> + #ifdef HAVE_UNISTD_H +@@ -78,21 +77,31 @@ sig_get(fido_blob_t *sig, const unsigned char **buf, size_t *len) + static int + x5c_get(fido_blob_t *x5c, const unsigned char **buf, size_t *len) + { +- X509 *cert = NULL; +- int ok = -1; +- +- if (*len > LONG_MAX) { +- fido_log_debug("%s: invalid len %zu", __func__, *len); +- goto fail; +- } ++ br_x509_decoder_context ctx; ++ const unsigned char *seq; ++ size_t len_len; ++ int ok = -1; + + /* find out the certificate's length */ +- const unsigned char *end = *buf; +- if ((cert = d2i_X509(NULL, &end, (long)*len)) == NULL || end <= *buf || +- (x5c->len = (size_t)(end - *buf)) >= *len) { +- fido_log_debug("%s: d2i_X509", __func__); ++ seq = *buf; ++ if (*len < 2 || seq[0] != 0x30 || seq[1] == 0x80) { ++ fido_log_debug("%s: X.509 decode", __func__); + goto fail; + } ++ if ((seq[1] & 0x80) != 0) { ++ len_len = seq[1] & 0x7f; ++ if (len_len > sizeof(size_t) || len_len > *len - 2) { ++ fido_log_debug("%s: X.509 decode", __func__); ++ goto fail; ++ } ++ seq += 2; ++ x5c->len = 0; ++ while (len_len--) ++ x5c->len = x5c->len << 8 | *seq++; ++ x5c->len += seq - *buf; ++ } else { ++ x5c->len = 2 + seq[1]; ++ } + + /* read accordingly */ + if ((x5c->ptr = calloc(1, x5c->len)) == NULL || +@@ -103,8 +112,7 @@ x5c_get(fido_blob_t *x5c, const unsigned char **buf, size_t *len) + + ok = 0; + fail: +- if (cert != NULL) +- X509_free(cert); ++ explicit_bzero(&ctx, sizeof(ctx)); + + if (ok < 0) { + free(x5c->ptr); +@@ -119,6 +127,7 @@ static int + authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount, + fido_blob_t *fake_cbor_ad) + { ++ br_sha256_context ctx; + uint8_t authdata[AUTHDATA_BASE_SIZE] = {0}; + unsigned char *rp_id_hash; + cbor_item_t *item = NULL; +@@ -126,11 +135,9 @@ authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount, + + rp_id_hash = (unsigned char *)&authdata[AUTHDATA_RP_ID_HASH]; + +- if (SHA256((const void *)rp_id, strlen(rp_id), +- rp_id_hash) != rp_id_hash) { +- fido_log_debug("%s: sha256", __func__); +- return (-1); +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, rp_id, strlen(rp_id)); ++ br_sha256_out(&ctx, rp_id_hash); + + authdata[AUTHDATA_FLAGS] = flags; /* XXX translate? */ + memcpy(&authdata[AUTHDATA_SIGN_COUNT], &sigcount, 4); +@@ -159,8 +166,8 @@ send_dummy_register(fido_dev_t *dev, int ms) + { + const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; + iso7816_apdu_t *apdu = NULL; +- unsigned char challenge[SHA256_DIGEST_LENGTH]; +- unsigned char application[SHA256_DIGEST_LENGTH]; ++ unsigned char challenge[br_sha256_SIZE]; ++ unsigned char application[br_sha256_SIZE]; + unsigned char reply[2048]; + int r; + +@@ -173,7 +180,7 @@ send_dummy_register(fido_dev_t *dev, int ms) + memset(&application, 0xff, sizeof(application)); + + if ((apdu = iso7816_new(U2F_CMD_REGISTER, 0, 2 * +- SHA256_DIGEST_LENGTH)) == NULL || ++ br_sha256_SIZE)) == NULL || + iso7816_add(apdu, &challenge, sizeof(challenge)) < 0 || + iso7816_add(apdu, &application, sizeof(application)) < 0) { + fido_log_debug("%s: iso7816", __func__); +@@ -211,10 +218,11 @@ static int + key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, + int *found, int ms) + { ++ br_sha256_context ctx; + const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; + iso7816_apdu_t *apdu = NULL; +- unsigned char challenge[SHA256_DIGEST_LENGTH]; +- unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; ++ unsigned char challenge[br_sha256_SIZE]; ++ unsigned char rp_id_hash[br_sha256_SIZE]; + unsigned char reply[8]; + uint8_t key_id_len; + int r; +@@ -229,17 +237,14 @@ key_lookup(fido_dev_t *dev, const char *rp_id, const fido_blob_t *key_id, + memset(&challenge, 0xff, sizeof(challenge)); + memset(&rp_id_hash, 0, sizeof(rp_id_hash)); + +- if (SHA256((const void *)rp_id, strlen(rp_id), +- rp_id_hash) != rp_id_hash) { +- fido_log_debug("%s: sha256", __func__); +- r = FIDO_ERR_INTERNAL; +- goto fail; +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, rp_id, strlen(rp_id)); ++ br_sha256_out(&ctx, rp_id_hash); + + key_id_len = (uint8_t)key_id->len; + + if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_CHECK, 2 * +- SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len)) == NULL || ++ br_sha256_SIZE + sizeof(key_id_len) + key_id_len)) == NULL || + iso7816_add(apdu, &challenge, sizeof(challenge)) < 0 || + iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 || + iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 || +@@ -317,9 +322,10 @@ static int + do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, + const fido_blob_t *key_id, fido_blob_t *sig, fido_blob_t *ad, int ms) + { ++ br_sha256_context ctx; + const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; + iso7816_apdu_t *apdu = NULL; +- unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; ++ unsigned char rp_id_hash[br_sha256_SIZE]; + unsigned char reply[128]; + int reply_len; + uint8_t key_id_len; +@@ -329,7 +335,7 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, + ms = 0; /* XXX */ + #endif + +- if (cdh->len != SHA256_DIGEST_LENGTH || key_id->len > UINT8_MAX || ++ if (cdh->len != br_sha256_SIZE || key_id->len > UINT8_MAX || + rp_id == NULL) { + r = FIDO_ERR_INVALID_ARGUMENT; + goto fail; +@@ -337,17 +343,14 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, + + memset(&rp_id_hash, 0, sizeof(rp_id_hash)); + +- if (SHA256((const void *)rp_id, strlen(rp_id), +- rp_id_hash) != rp_id_hash) { +- fido_log_debug("%s: sha256", __func__); +- r = FIDO_ERR_INTERNAL; +- goto fail; +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, rp_id, strlen(rp_id)); ++ br_sha256_out(&ctx, rp_id_hash); + + key_id_len = (uint8_t)key_id->len; + + if ((apdu = iso7816_new(U2F_CMD_AUTH, U2F_AUTH_SIGN, 2 * +- SHA256_DIGEST_LENGTH + sizeof(key_id_len) + key_id_len)) == NULL || ++ br_sha256_SIZE + sizeof(key_id_len) + key_id_len)) == NULL || + iso7816_add(apdu, cdh->ptr, cdh->len) < 0 || + iso7816_add(apdu, &rp_id_hash, sizeof(rp_id_hash)) < 0 || + iso7816_add(apdu, &key_id_len, sizeof(key_id_len)) < 0 || +@@ -436,6 +439,7 @@ static int + encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len, + const uint8_t *pubkey, size_t pubkey_len, fido_blob_t *out) + { ++ br_sha256_context ctx; + uint8_t authdata[AUTHDATA_BASE_SIZE] = {0}; + unsigned char *rp_id_hash; + uint8_t attcred_raw[ATTCRED_BASE_SIZE] = {0}; +@@ -463,11 +467,9 @@ encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len, + + rp_id_hash = (unsigned char *)&authdata[AUTHDATA_RP_ID_HASH]; + +- if (SHA256((const void *)rp_id, strlen(rp_id), +- rp_id_hash) != rp_id_hash) { +- fido_log_debug("%s: sha256", __func__); +- goto fail; +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, rp_id, strlen(rp_id)); ++ br_sha256_out(&ctx, rp_id_hash); + + authdata[AUTHDATA_FLAGS] = (CTAP_AUTHDATA_ATT_CRED | + CTAP_AUTHDATA_USER_PRESENT); +@@ -609,9 +611,10 @@ fail: + int + u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) + { ++ br_sha256_context ctx; + const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_MSG; + iso7816_apdu_t *apdu = NULL; +- unsigned char rp_id_hash[SHA256_DIGEST_LENGTH]; ++ unsigned char rp_id_hash[br_sha256_SIZE]; + unsigned char reply[2048]; + int reply_len; + int found; +@@ -628,7 +631,7 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) + } + + if (cred->type != COSE_ES256 || cred->cdh.ptr == NULL || +- cred->rp.id == NULL || cred->cdh.len != SHA256_DIGEST_LENGTH) { ++ cred->rp.id == NULL || cred->cdh.len != br_sha256_SIZE) { + fido_log_debug("%s: type=%d, cdh=(%p,%zu)" , __func__, + cred->type, (void *)cred->cdh.ptr, cred->cdh.len); + return (FIDO_ERR_INVALID_ARGUMENT); +@@ -652,14 +655,12 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) + + memset(&rp_id_hash, 0, sizeof(rp_id_hash)); + +- if (SHA256((const void *)cred->rp.id, strlen(cred->rp.id), +- rp_id_hash) != rp_id_hash) { +- fido_log_debug("%s: sha256", __func__); +- return (FIDO_ERR_INTERNAL); +- } ++ br_sha256_init(&ctx); ++ br_sha256_update(&ctx, cred->rp.id, strlen(cred->rp.id)); ++ br_sha256_out(&ctx, rp_id_hash); + + if ((apdu = iso7816_new(U2F_CMD_REGISTER, 0, 2 * +- SHA256_DIGEST_LENGTH)) == NULL || ++ br_sha256_SIZE)) == NULL || + iso7816_add(apdu, cred->cdh.ptr, cred->cdh.len) < 0 || + iso7816_add(apdu, rp_id_hash, sizeof(rp_id_hash)) < 0) { + fido_log_debug("%s: iso7816", __func__); +-- +2.26.0 + diff --git a/pkg/libfido2/ver b/pkg/libfido2/ver @@ -1 +1 @@ -1.3.1 r1 +1.3.1 r2