Skip to content

Commit

Permalink
Add option to allow building with BoringSSL
Browse files Browse the repository at this point in the history
To build with BoringSSL CRYPTO_INCLUDE_DIRS
and CRYPTO_LIBRARY_DIRS must be defined

Also fix all the compile issues when building
with BoringSSL
  • Loading branch information
nacho committed Nov 2, 2023
1 parent 92e3d89 commit 07ecbb9
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 21 deletions.
19 changes: 17 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ option(USE_HIDAPI "Use hidapi as the HID backend" OFF)
option(USE_PCSC "Enable experimental PCSC support" ON)
option(USE_WINHELLO "Abstract Windows Hello as a FIDO device" ON)
option(NFC_LINUX "Enable NFC support on Linux" ON)
option(USE_BORINGSSL "Build with BoringSSL" OFF)

add_definitions(-D_FIDO_MAJOR=${FIDO_MAJOR})
add_definitions(-D_FIDO_MINOR=${FIDO_MINOR})
Expand Down Expand Up @@ -85,7 +86,12 @@ if(NOT MSVC)
elseif(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
set(FIDO_CFLAGS "${FIDO_CFLAGS} -D_NETBSD_SOURCE")
endif()
set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99")

# With BoringSSL we need a newer standard than c99
if(NOT USE_BORINGSSL)
set(FIDO_CFLAGS "${FIDO_CFLAGS} -std=c99")
endif()

set(CMAKE_C_FLAGS "${FIDO_CFLAGS} ${CMAKE_C_FLAGS}")
endif()

Expand Down Expand Up @@ -219,9 +225,18 @@ if(MSVC)
else()
include(FindPkgConfig)
pkg_search_module(CBOR libcbor)
pkg_search_module(CRYPTO libcrypto)
pkg_search_module(ZLIB zlib)

if(USE_BORINGSSL)
if((NOT CRYPTO_INCLUDE_DIRS) OR (NOT CRYPTO_LIBRARY_DIRS))
message(FATAL_ERROR "please define "
"{CBOR,CRYPTO,ZLIB}_{INCLUDE,LIBRARY}_DIRS when "
"building with BoringSSL")
endif()
else()
pkg_search_module(CRYPTO libcrypto)
endif()

if(NOT CBOR_FOUND AND NOT HAVE_CBOR_H)
message(FATAL_ERROR "could not find libcbor")
endif()
Expand Down
14 changes: 11 additions & 3 deletions src/cbor.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,9 +709,13 @@ cbor_encode_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,
if (prot == CTAP_PIN_PROTOCOL2 && key.len > 32)
key.len = 32;

if ((md = EVP_sha256()) == NULL || HMAC(md, key.ptr,
(int)key.len, data->ptr, data->len, dgst,
&dgst_len) == NULL || dgst_len != SHA256_DIGEST_LENGTH)
if ((md = EVP_sha256()) == NULL ||
#ifdef OPENSSL_IS_BORINGSSL
HMAC(md, key.ptr, key.len, data->ptr, data->len, dgst, &dgst_len) == NULL ||
#else
HMAC(md, key.ptr, (int)key.len, data->ptr, data->len, dgst, &dgst_len) == NULL ||
#endif
dgst_len != SHA256_DIGEST_LENGTH)
return (NULL);

outlen = (prot == CTAP_PIN_PROTOCOL1) ? 16 : dgst_len;
Expand Down Expand Up @@ -758,7 +762,11 @@ cbor_encode_change_pin_auth(const fido_dev_t *dev, const fido_blob_t *secret,

if ((ctx = HMAC_CTX_new()) == NULL ||
(md = EVP_sha256()) == NULL ||
#ifdef OPENSSL_IS_BORINGSSL
HMAC_Init_ex(ctx, key.ptr, key.len, md, NULL) == 0 ||
#else
HMAC_Init_ex(ctx, key.ptr, (int)key.len, md, NULL) == 0 ||
#endif
HMAC_Update(ctx, new_pin_enc->ptr, new_pin_enc->len) == 0 ||
HMAC_Update(ctx, pin_hash_enc->ptr, pin_hash_enc->len) == 0 ||
HMAC_Final(ctx, dgst, &dgst_len) == 0 ||
Expand Down
4 changes: 2 additions & 2 deletions src/ecdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include <openssl/evp.h>
#include <openssl/sha.h>
#if defined(LIBRESSL_VERSION_NUMBER)
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL)
#include <openssl/hkdf.h>
#else
#include <openssl/kdf.h>
Expand All @@ -16,7 +16,7 @@
#include "fido.h"
#include "fido/es256.h"

#if defined(LIBRESSL_VERSION_NUMBER)
#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL)
static int
hkdf_sha256(uint8_t *key, const char *info, const fido_blob_t *secret)
{
Expand Down
36 changes: 31 additions & 5 deletions src/es256.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,10 @@ es256_sk_create(es256_sk_t *key)
EVP_PKEY *k = NULL;
const EC_KEY *ec;
const BIGNUM *d;
int n;
int ok = -1;
#ifndef OPENSSL_IS_BORINGSSL
int n;
#endif

if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL ||
EVP_PKEY_paramgen_init(pctx) <= 0 ||
Expand All @@ -245,8 +247,13 @@ es256_sk_create(es256_sk_t *key)

if ((ec = EVP_PKEY_get0_EC_KEY(k)) == NULL ||
(d = EC_KEY_get0_private_key(ec)) == NULL ||
#ifdef OPENSSL_IS_BORINGSSL
(BN_num_bytes(d) > sizeof(key->d)) ||
(BN_bn2bin(d, key->d) > sizeof(key->d))) {
#else
(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)) {
#endif
fido_log_debug("%s: EC_KEY_get0_private_key", __func__);
goto fail;
}
Expand Down Expand Up @@ -344,8 +351,13 @@ es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec)
size_t dx;
size_t dy;
int ok = FIDO_ERR_INTERNAL;
#ifdef OPENSSL_IS_BORINGSSL
size_t nx;
size_t ny;
#else
int nx;
int ny;
#endif

if ((q = EC_KEY_get0_public_key(ec)) == NULL ||
(g = EC_GROUP_new_by_curve_name(es256_nid)) == NULL ||
Expand All @@ -364,9 +376,16 @@ es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec)
goto fail;
}

nx = BN_num_bytes(x);
ny = BN_num_bytes(y);
if (EC_POINT_get_affine_coordinates_GFp(g, q, x, y, bnctx) == 0 ||
(nx = BN_num_bytes(x)) < 0 || (size_t)nx > sizeof(pk->x) ||
(ny = BN_num_bytes(y)) < 0 || (size_t)ny > sizeof(pk->y)) {
#ifdef OPENSSL_IS_BORINGSSL
nx > sizeof(pk->x) ||
ny > sizeof(pk->y)) {
#else
nx < 0 || (size_t)nx > sizeof(pk->x) ||
ny < 0 || (size_t)ny > sizeof(pk->y)) {
#endif
fido_log_debug("%s: EC_POINT_get_affine_coordinates_GFp",
__func__);
goto fail;
Expand All @@ -375,8 +394,15 @@ es256_pk_from_EC_KEY(es256_pk_t *pk, const EC_KEY *ec)
dx = sizeof(pk->x) - (size_t)nx;
dy = sizeof(pk->y) - (size_t)ny;

if ((nx = BN_bn2bin(x, pk->x + dx)) < 0 || (size_t)nx > sizeof(pk->x) ||
(ny = BN_bn2bin(y, pk->y + dy)) < 0 || (size_t)ny > sizeof(pk->y)) {
nx = BN_bn2bin(x, pk->x + dx);
ny = BN_bn2bin(y, pk->y + dy);
#ifdef OPENSSL_IS_BORINGSSL
if (nx > sizeof(pk->x) ||
ny > sizeof(pk->y)) {
#else
if (nx < 0 || (size_t)nx > sizeof(pk->x) ||
ny < 0 || (size_t)ny > sizeof(pk->y)) {
#endif
fido_log_debug("%s: BN_bn2bin", __func__);
goto fail;
}
Expand Down
28 changes: 24 additions & 4 deletions src/es384.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,13 @@ es384_pk_from_EC_KEY(es384_pk_t *pk, const EC_KEY *ec)
size_t dx;
size_t dy;
int ok = FIDO_ERR_INTERNAL;
#ifdef OPENSSL_IS_BORINGSSL
size_t nx;
size_t ny;
#else
int nx;
int ny;
#endif

if ((q = EC_KEY_get0_public_key(ec)) == NULL ||
(g = EC_GROUP_new_by_curve_name(NID_secp384r1)) == NULL ||
Expand All @@ -207,9 +212,16 @@ es384_pk_from_EC_KEY(es384_pk_t *pk, const EC_KEY *ec)
goto fail;
}

nx = BN_num_bytes(x);
ny = BN_num_bytes(y);
if (EC_POINT_get_affine_coordinates_GFp(g, q, x, y, bnctx) == 0 ||
(nx = BN_num_bytes(x)) < 0 || (size_t)nx > sizeof(pk->x) ||
(ny = BN_num_bytes(y)) < 0 || (size_t)ny > sizeof(pk->y)) {
#ifdef OPENSSL_IS_BORINGSSL
nx > sizeof(pk->x) ||
ny > sizeof(pk->y)) {
#else
nx < 0 || (size_t)nx > sizeof(pk->x) ||
ny < 0 || (size_t)ny > sizeof(pk->y)) {
#endif
fido_log_debug("%s: EC_POINT_get_affine_coordinates_GFp",
__func__);
goto fail;
Expand All @@ -218,8 +230,16 @@ es384_pk_from_EC_KEY(es384_pk_t *pk, const EC_KEY *ec)
dx = sizeof(pk->x) - (size_t)nx;
dy = sizeof(pk->y) - (size_t)ny;

if ((nx = BN_bn2bin(x, pk->x + dx)) < 0 || (size_t)nx > sizeof(pk->x) ||
(ny = BN_bn2bin(y, pk->y + dy)) < 0 || (size_t)ny > sizeof(pk->y)) {
nx = BN_bn2bin(x, pk->x + dx);
ny = BN_bn2bin(y, pk->y + dy);
if (
#ifdef OPENSSL_IS_BORINGSSL
nx > sizeof(pk->x) ||
ny > sizeof(pk->y)) {
#else
nx < 0 || (size_t)nx > sizeof(pk->x) ||
ny < 0 || (size_t)ny > sizeof(pk->y)) {
#endif
fido_log_debug("%s: BN_bn2bin", __func__);
goto fail;
}
Expand Down
21 changes: 21 additions & 0 deletions src/rs1.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ rs1_free_EVP_MD(EVP_MD *md)
{
freezero(md, sizeof(*md));
}
#elif defined(OPENSSL_IS_BORINGSSL)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-qual"
static EVP_MD *
rs1_get_EVP_MD(void)
{
const EVP_MD *md;

if ((md = EVP_sha1()) == NULL)
return (NULL);

return (EVP_MD *)md;
}
# pragma GCC diagnostic pop

static void
rs1_free_EVP_MD(EVP_MD *md)
{
// Do not free it
(void)md;
}
#elif OPENSSL_VERSION_NUMBER >= 0x30000000
static EVP_MD *
rs1_get_EVP_MD(void)
Expand Down
51 changes: 46 additions & 5 deletions src/rs256.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@ rs256_free_EVP_MD(EVP_MD *md)
{
freezero(md, sizeof(*md));
}
#elif defined(OPENSSL_IS_BORINGSSL)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-qual"
static EVP_MD *
rs256_get_EVP_MD(void)
{
const EVP_MD *md;

if ((md = EVP_sha256()) == NULL)
return (NULL);

return (EVP_MD *)md;
}
# pragma GCC diagnostic pop

static void
rs256_free_EVP_MD(EVP_MD *md)
{
// Do not free it
(void)md;
}
#elif OPENSSL_VERSION_NUMBER >= 0x30000000
static EVP_MD *
rs256_get_EVP_MD(void)
Expand Down Expand Up @@ -214,7 +235,13 @@ 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;
#ifdef OPENSSL_IS_BORINGSSL
size_t nx;
size_t ny;
#else
int nx;
int ny;
#endif

if (RSA_bits(rsa) != 2048) {
fido_log_debug("%s: invalid key length", __func__);
Expand All @@ -228,14 +255,28 @@ rs256_pk_from_RSA(rs256_pk_t *pk, const RSA *rsa)
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)) {
nx = BN_num_bytes(n);
ny = BN_num_bytes(e);
#ifdef OPENSSL_IS_BORINGSSL
if (nx > sizeof(pk->n) ||
ny > sizeof(pk->e)) {
#else
if (nx < 0 || (size_t)nx > sizeof(pk->n) ||
ny < 0 || (size_t)ny > sizeof(pk->e)) {
#endif
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)) {
nx = BN_bn2bin(n, pk->n);
ny = BN_bn2bin(e, pk->e);
#ifdef OPENSSL_IS_BORINGSSL
if (nx > sizeof(pk->n) ||
ny > sizeof(pk->e)) {
#else
if (nx < 0 || (size_t)nx > sizeof(pk->n) ||
ny < 0 || (size_t)ny > sizeof(pk->e)) {
#endif
fido_log_debug("%s: BN_bn2bin", __func__);
return (FIDO_ERR_INTERNAL);
}
Expand Down
50 changes: 50 additions & 0 deletions tools/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,55 @@
#include "../openbsd-compat/openbsd-compat.h"
#include "extern.h"

#ifdef OPENSSL_IS_BORINGSSL
int
base64_encode(const void *ptr, size_t len, char **out)
{
size_t out_len;

if (ptr == NULL || out == NULL || len > INT_MAX)
return (-1);

*out = NULL;

if (!EVP_EncodedLength(&out_len, len))
return (-1);

if ((*out = calloc(1, (size_t)out_len + 1)) == NULL)
return (-1);

return EVP_EncodeBlock((uint8_t *)*out, (const uint8_t *)ptr, len) > 0 ? 1 : -1;
}

int
base64_decode(const char *in, void **ptr, size_t *len)
{
size_t alloc_len;
size_t in_len;
int ok = -1;

if (in == NULL || ptr == NULL || len == NULL || strlen(in) > INT_MAX)
return (-1);

in_len = strlen(in);
if (!EVP_DecodedLength(&alloc_len, in_len))
goto fail;

if ((*ptr = calloc(1, alloc_len + 1)) == NULL)
goto fail;

ok = EVP_DecodeBase64(*ptr, len, alloc_len, (const uint8_t *)in, alloc_len);

fail:
if (ok < 0) {
free(*ptr);
*ptr = NULL;
*len = 0;
}

return (ok);
}
#else
int
base64_encode(const void *ptr, size_t len, char **out)
{
Expand Down Expand Up @@ -107,6 +156,7 @@ base64_decode(const char *in, void **ptr, size_t *len)

return (ok);
}
#endif // OPENSSL_IS_BORINGSSL

int
base64_read(FILE *f, struct blob *out)
Expand Down

0 comments on commit 07ecbb9

Please sign in to comment.