Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to allow building with BoringSSL #738

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading