0002-Add-support-for-BearSSL-crypto.patch (24018B)
- From ca1cd33d7a07b3344d031d9119064c2b12de8e03 Mon Sep 17 00:00:00 2001
- From: Michael Forney <mforney@mforney.org>
- Date: Wed, 1 Dec 2021 12:42:00 -0800
- Subject: [PATCH] Add support for BearSSL crypto
- ---
- config.h.in | 3 +
- configure | 50 ++++-
- configure.ac | 43 ++++-
- daemon/unbound.c | 2 +
- util/configparser.c | 4 +-
- util/configparser.y | 4 +-
- util/random.c | 46 ++++-
- validator/val_secalgo.c | 382 ++++++++++++++++++++++++++++++++++++++-
- validator/val_sigcrypt.c | 2 +-
- 9 files changed, 514 insertions(+), 22 deletions(-)
- diff --git a/config.h.in b/config.h.in
- index e8a26735..6b0b1c50 100644
- --- a/config.h.in
- +++ b/config.h.in
- @@ -72,6 +72,9 @@
- /* If we have be64toh */
- #undef HAVE_BE64TOH
- +/* Use bearssl for crypto */
- +#undef HAVE_BEARSSL
- +
- /* Define to 1 if you have the `BIO_set_callback_ex' function. */
- #undef HAVE_BIO_SET_CALLBACK_EX
- diff --git a/configure b/configure
- index 0e964568..9c33d22f 100755
- --- a/configure
- +++ b/configure
- @@ -871,6 +871,7 @@ with_pythonmodule
- enable_swig_version_check
- with_nss
- with_nettle
- +with_bearssl
- with_ssl
- with_libbsd
- enable_sha1
- @@ -1649,6 +1650,7 @@ Optional Packages:
- disable script engine. (default=no)
- --with-nss=path use libnss instead of openssl, installed at path.
- --with-nettle=path use libnettle as crypto library, installed at path.
- + --with-bearssl=path use bearssl as crypto library, installed at path.
- --with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl
- /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
- /usr or specify like /usr/include/openssl11)
- @@ -17981,11 +17983,35 @@ done
- +fi
- +
- +
- +# bearssl
- +USE_BEARSSL="no"
- +
- +# Check whether --with-bearssl was given.
- +if test ${with_bearssl+y}
- +then :
- + withval=$with_bearssl;
- + USE_BEARSSL="yes"
- +
- +printf "%s\n" "#define HAVE_BEARSSL 1" >>confdefs.h
- +
- + if test "$withval" != "" -a "$withval" != "yes"; then
- + CPPFLAGS="$CPPFLAGS -I$withval/include"
- + LDFLAGS="$LDFLAGS -L$withval/lib"
- + fi
- + LIBS="$LIBS -lbearssl"
- + SSLLIB=""
- + PC_CRYPTO_DEPENDENCY=""
- +
- +
- +
- fi
- # openssl
- -if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- +if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- # Check whether --with-ssl was given.
- @@ -18790,7 +18816,7 @@ if test "${enable_gost+set}" = set; then :
- fi
- use_gost="no"
- -if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- +if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- case "$enable_gost" in
- no)
- ;;
- @@ -18943,7 +18969,7 @@ case "$enable_ecdsa" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
- if test "x$ac_cv_func_ECDSA_sign" = xyes; then :
- @@ -19036,7 +19062,7 @@ use_dsa="no"
- case "$enable_dsa" in
- yes)
- # detect if DSA is supported, and turn it off if not.
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
- if test "x$ac_cv_func_DSA_SIG_new" = xyes; then :
- @@ -19080,6 +19106,9 @@ else
- fi
- else
- + if test $USE_BEARSSL = "yes"; then
- + as_fn_error $? "BearSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
- + fi
- cat >>confdefs.h <<_ACEOF
- #define USE_DSA 1
- @@ -19115,7 +19144,7 @@ case "$enable_ed25519" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- ac_fn_c_check_decl "$LINENO" "NID_ED25519" "ac_cv_have_decl_NID_ED25519" "$ac_includes_default
- #include <openssl/evp.h>
- @@ -19139,6 +19168,9 @@ else
- fi
- fi
- + if test $USE_BEARSSL = "yes"; then
- + as_fn_error $? "BearSSL does not support Ed25519 and you used --enable-ed25519." "$LINENO" 5
- + fi
- if test $USE_NETTLE = "yes"; then
- for ac_header in nettle/eddsa.h
- do :
- @@ -19174,7 +19206,7 @@ case "$enable_ed448" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
- #include <openssl/evp.h>
- @@ -19198,6 +19230,9 @@ else
- fi
- fi
- + if test $USE_BEARSSL = "yes"; then
- + as_fn_error $? "BearSSL does not support Ed448 and you used --enable-ed448." "$LINENO" 5
- + fi
- if test $use_ed448 = "yes"; then
- cat >>confdefs.h <<_ACEOF
- @@ -21744,6 +21779,9 @@ if test $ALLTARGET = "alltargets"; then
- if test $USE_NETTLE = "yes"; then
- as_fn_error $? "--with-nettle can only be used in combination with --with-libunbound-only." "$LINENO" 5
- fi
- + if test $USE_BEARSSL = "yes"; then
- + as_fn_error $? "--with-bearssl can only be used in combination with --with-libunbound-only." "$LINENO" 5
- + fi
- fi
- diff --git a/configure.ac b/configure.ac
- index 36fdb459..9e15aee4 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -835,8 +835,25 @@ AC_ARG_WITH([nettle], AS_HELP_STRING([--with-nettle=path],[use libnettle as cryp
- ]
- )
- +# bearssl
- +USE_BEARSSL="no"
- +AC_ARG_WITH([bearssl], AS_HELP_STRING([--with-bearssl=path],[use bearssl as crypto library, installed at path.]),
- + [
- + USE_BEARSSL="yes"
- + AC_DEFINE(HAVE_BEARSSL, 1, [Use bearssl for crypto])
- + if test "$withval" != "" -a "$withval" != "yes"; then
- + CPPFLAGS="$CPPFLAGS -I$withval/include"
- + LDFLAGS="$LDFLAGS -L$withval/lib"
- + fi
- + LIBS="$LIBS -lbearssl"
- + SSLLIB=""
- + PC_CRYPTO_DEPENDENCY=""
- + AC_SUBST(PC_CRYPTO_DEPENDENCY)
- + ]
- +)
- +
- # openssl
- -if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- +if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- ACX_WITH_SSL
- ACX_LIB_SSL
- SSLLIB="-lssl"
- @@ -1084,7 +1101,7 @@ AC_MSG_RESULT($ac_cv_c_gost_works)
- AC_ARG_ENABLE(gost, AS_HELP_STRING([--disable-gost],[Disable GOST support]))
- use_gost="no"
- -if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- +if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- case "$enable_gost" in
- no)
- ;;
- @@ -1098,7 +1115,7 @@ case "$enable_gost" in
- fi
- ;;
- esac
- -fi dnl !USE_NSS && !USE_NETTLE
- +fi dnl !USE_NSS && !USE_NETTLE && !USE_BEARSSL
- AC_ARG_ENABLE(ecdsa, AS_HELP_STRING([--disable-ecdsa],[Disable ECDSA support]))
- use_ecdsa="no"
- @@ -1106,7 +1123,7 @@ case "$enable_ecdsa" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
- AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
- AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
- @@ -1137,7 +1154,7 @@ use_dsa="no"
- case "$enable_dsa" in
- yes)
- # detect if DSA is supported, and turn it off if not.
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- AC_CHECK_FUNC(DSA_SIG_new, [
- AC_CHECK_TYPE(DSA_SIG*, [
- AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
- @@ -1163,6 +1180,9 @@ AC_INCLUDES_DEFAULT
- ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
- fi ])
- else
- + if test $USE_BEARSSL = "yes"; then
- + AC_MSG_ERROR([BearSSL does not support DSA and you used --enable-dsa.])
- + fi
- AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
- fi
- ;;
- @@ -1183,7 +1203,7 @@ case "$enable_ed25519" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- AC_CHECK_DECLS([NID_ED25519], [
- use_ed25519="yes"
- ], [ if test "x$enable_ed25519" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED25519 and you used --enable-ed25519.])
- @@ -1191,6 +1211,9 @@ case "$enable_ed25519" in
- #include <openssl/evp.h>
- ])
- fi
- + if test $USE_BEARSSL = "yes"; then
- + AC_MSG_ERROR([BearSSL does not support Ed25519 and you used --enable-ed25519.])
- + fi
- if test $USE_NETTLE = "yes"; then
- AC_CHECK_HEADERS([nettle/eddsa.h], use_ed25519="yes",, [AC_INCLUDES_DEFAULT])
- fi
- @@ -1206,7 +1229,7 @@ case "$enable_ed448" in
- no)
- ;;
- *)
- - if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
- + if test $USE_NSS = "no" -a $USE_NETTLE = "no" -a $USE_BEARSSL = "no"; then
- AC_CHECK_DECLS([NID_ED448], [
- use_ed448="yes"
- ], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
- @@ -1214,6 +1237,9 @@ case "$enable_ed448" in
- #include <openssl/evp.h>
- ])
- fi
- + if test $USE_BEARSSL = "yes"; then
- + AC_MSG_ERROR([BearSSL does not support Ed448 and you used --enable-ed448.])
- + fi
- if test $use_ed448 = "yes"; then
- AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
- fi
- @@ -1937,6 +1963,9 @@ if test $ALLTARGET = "alltargets"; then
- if test $USE_NETTLE = "yes"; then
- AC_MSG_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
- fi
- + if test $USE_BEARSSL = "yes"; then
- + AC_MSG_ERROR([--with-bearssl can only be used in combination with --with-libunbound-only.])
- + fi
- fi
- AC_SUBST(ALLTARGET)
- diff --git a/daemon/unbound.c b/daemon/unbound.c
- index 457a0803..1a31bb3e 100644
- --- a/daemon/unbound.c
- +++ b/daemon/unbound.c
- @@ -121,6 +121,8 @@ print_build_options(void)
- NSS_GetVersion()
- #elif defined(HAVE_NETTLE)
- "nettle"
- +#elif defined(HAVE_BEARSSL)
- + "bearssl"
- #endif
- );
- printf("Linked modules:");
- diff --git a/util/configparser.c b/util/configparser.c
- index 2f155650..f2749753 100644
- --- a/util/configparser.c
- +++ b/util/configparser.c
- @@ -5649,7 +5649,7 @@ yyreduce:
- OUTYY(("P(server_fake_dsa:%s)\n", (yyvsp[0].str)));
- if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0)
- yyerror("expected yes or no.");
- -#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
- +#if defined(HAVE_SSL) || defined(HAVE_NETTLE) || defined(HAVE_BEARSSL)
- else fake_dsa = (strcmp((yyvsp[0].str), "yes")==0);
- if(fake_dsa)
- log_warn("test option fake_dsa is enabled");
- @@ -5665,7 +5665,7 @@ yyreduce:
- OUTYY(("P(server_fake_sha1:%s)\n", (yyvsp[0].str)));
- if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0)
- yyerror("expected yes or no.");
- -#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
- +#if defined(HAVE_SSL) || defined(HAVE_NETTLE) || defined(HAVE_BEARSSL)
- else fake_sha1 = (strcmp((yyvsp[0].str), "yes")==0);
- if(fake_sha1)
- log_warn("test option fake_sha1 is enabled");
- diff --git a/util/configparser.y b/util/configparser.y
- index 1daf853d..844c175e 100644
- --- a/util/configparser.y
- +++ b/util/configparser.y
- @@ -2028,7 +2028,7 @@ server_fake_dsa: VAR_FAKE_DSA STRING_ARG
- OUTYY(("P(server_fake_dsa:%s)\n", $2));
- if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
- yyerror("expected yes or no.");
- -#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
- +#if defined(HAVE_SSL) || defined(HAVE_NETTLE) || defined(HAVE_BEARSSL)
- else fake_dsa = (strcmp($2, "yes")==0);
- if(fake_dsa)
- log_warn("test option fake_dsa is enabled");
- @@ -2041,7 +2041,7 @@ server_fake_sha1: VAR_FAKE_SHA1 STRING_ARG
- OUTYY(("P(server_fake_sha1:%s)\n", $2));
- if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
- yyerror("expected yes or no.");
- -#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
- +#if defined(HAVE_SSL) || defined(HAVE_NETTLE) || defined(HAVE_BEARSSL)
- else fake_sha1 = (strcmp($2, "yes")==0);
- if(fake_sha1)
- log_warn("test option fake_sha1 is enabled");
- diff --git a/util/random.c b/util/random.c
- index f7bb0a6f..6bce2f62 100644
- --- a/util/random.c
- +++ b/util/random.c
- @@ -183,10 +183,52 @@ long int ub_random(struct ub_randstate* s)
- }
- return x & MAX_VALUE;
- }
- -#endif /* HAVE_SSL or HAVE_LIBBSD or HAVE_NSS or HAVE_NETTLE */
- +#elif defined(HAVE_BEARSSL)
- -#if (defined(HAVE_NSS) || defined(HAVE_NETTLE)) && !defined(HAVE_LIBBSD)
- +#include <bearssl.h>
- +
- +struct ub_randstate {
- + br_hmac_drbg_context ctx;
- + int seeded;
- +};
- +
- +struct ub_randstate* ub_initstate(struct ub_randstate* ATTR_UNUSED(from))
- +{
- + struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
- + unsigned char buf[32];
- + if(!s) {
- + log_err("malloc failure in random init");
- + return NULL;
- + }
- + if(getentropy(buf, sizeof(buf)) == 0) {
- + /* got entropy */
- + br_hmac_drbg_init(&s->ctx, &br_sha256_vtable, buf, sizeof(buf));
- + s->seeded = 1;
- + } else {
- + log_err("bearssl random(hmac-drbg) cannot initialize, "
- + "getentropy failed: %s", strerror(errno));
- + free(s);
- + return NULL;
- + }
- +
- + return s;
- +}
- +
- +long int ub_random(struct ub_randstate* s)
- +{
- + unsigned long x = 0;
- + if (!s || !s->seeded) {
- + log_err("couldn't generate randomness, hmac-drbg generator not yet seeded");
- + } else {
- + br_hmac_drbg_generate(&s->ctx, (unsigned char *)&x, sizeof(x));
- + }
- + return x & MAX_VALUE;
- +}
- +
- +#endif /* HAVE_SSL or HAVE_LIBBSD or HAVE_NSS or HAVE_NETTLE or HAVE_BEARSSL */
- +
- +#if (defined(HAVE_NSS) || defined(HAVE_NETTLE) || defined(HAVE_BEARSSL)) && !defined(HAVE_LIBBSD)
- long int
- ub_random_max(struct ub_randstate* state, long int x)
- {
- diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c
- index 7abf66f0..aa20b57b 100644
- --- a/validator/val_secalgo.c
- +++ b/validator/val_secalgo.c
- @@ -50,7 +50,7 @@
- #include "sldns/keyraw.h"
- #include "sldns/sbuffer.h"
- -#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
- +#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) && !defined(HAVE_BEARSSL)
- #error "Need crypto library to do digital signature cryptography"
- #endif
- @@ -2067,4 +2067,382 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
- }
- }
- -#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */
- +#elif defined(HAVE_BEARSSL)
- +
- +#include <bearssl.h>
- +
- +/* return size of digest if supported, or 0 otherwise */
- +size_t
- +nsec3_hash_algo_size_supported(int id)
- +{
- + switch(id) {
- + case NSEC3_HASH_SHA1:
- + return br_sha1_SIZE;
- + default:
- + return 0;
- + }
- +}
- +
- +/* perform nsec3 hash. return false on failure */
- +int
- +secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
- + unsigned char* res)
- +{
- + br_hash_compat_context ctx;
- +
- + switch(algo) {
- + case NSEC3_HASH_SHA1:
- + br_sha1_init(&ctx.sha1);
- + br_sha1_update(&ctx.sha1, buf, len);
- + br_sha1_out(&ctx.sha1, res);
- + return 1;
- + default:
- + return 0;
- + }
- +}
- +
- +void
- +secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res)
- +{
- + br_sha256_context ctx;
- +
- + br_sha256_init(&ctx);
- + br_sha256_update(&ctx, buf, len);
- + br_sha256_out(&ctx, res);
- +}
- +
- +/** hash structure for keeping track of running hashes */
- +struct secalgo_hash {
- + br_hash_compat_context ctx;
- +};
- +
- +/** create secalgo hash with hash type */
- +static struct secalgo_hash* secalgo_hash_create(const br_hash_class *vtable)
- +{
- + struct secalgo_hash* h;
- + h = calloc(1, sizeof(*h));
- + if(!h)
- + return NULL;
- + vtable->init(&h->ctx.vtable);
- + return h;
- +}
- +
- +struct secalgo_hash* secalgo_hash_create_sha384(void)
- +{
- + return secalgo_hash_create(&br_sha384_vtable);
- +}
- +
- +struct secalgo_hash* secalgo_hash_create_sha512(void)
- +{
- + return secalgo_hash_create(&br_sha512_vtable);
- +}
- +
- +int secalgo_hash_update(struct secalgo_hash* hash, uint8_t* data, size_t len)
- +{
- + hash->ctx.vtable->update(&hash->ctx.vtable, data, len);
- + return 1;
- +}
- +
- +int secalgo_hash_final(struct secalgo_hash* hash, uint8_t* result,
- + size_t maxlen, size_t* resultlen)
- +{
- + size_t len;
- +
- + hash->ctx.vtable->out(&hash->ctx.vtable, result);
- + len = hash->ctx.vtable->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK;
- + if(len > maxlen) {
- + *resultlen = 0;
- + log_err("secalgo_hash_final: hash buffer too small");
- + return 0;
- + }
- + hash->ctx.vtable->out(&hash->ctx.vtable, result);
- + *resultlen = len;
- + return 1;
- +}
- +
- +void secalgo_hash_delete(struct secalgo_hash* hash)
- +{
- + if(!hash) return;
- + free(hash);
- +}
- +
- +size_t
- +ds_digest_size_supported(int algo)
- +{
- + switch(algo) {
- + case LDNS_SHA1:
- +#ifdef USE_SHA1
- + return br_sha1_SIZE;
- +#else
- + if(fake_sha1) return 20;
- + return 0;
- +#endif
- +#ifdef USE_SHA2
- + case LDNS_SHA256:
- + return br_sha256_SIZE;
- +#endif
- +#ifdef USE_ECDSA
- + case LDNS_SHA384:
- + return br_sha384_SIZE;
- +#endif
- + }
- + return 0;
- +}
- +
- +int
- +secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
- + unsigned char* res)
- +{
- + br_hash_compat_context ctx;
- +
- + switch(algo) {
- +#ifdef USE_SHA1
- + case LDNS_SHA1:
- + br_sha1_init(&ctx.sha1);
- + br_sha1_update(&ctx.sha1, buf, len);
- + br_sha1_out(&ctx.sha1, res);
- + return 1;
- +#endif
- +#ifdef USE_SHA2
- + case LDNS_SHA256:
- + br_sha256_init(&ctx.sha256);
- + br_sha256_update(&ctx.sha256, buf, len);
- + br_sha256_out(&ctx.sha256, res);
- + return 1;
- +#endif
- +#ifdef USE_ECDSA
- + case LDNS_SHA384:
- + br_sha384_init(&ctx.sha384);
- + br_sha384_update(&ctx.sha384, buf, len);
- + br_sha384_out(&ctx.sha384, res);
- + return 1;
- +#endif
- + default:
- + verbose(VERB_QUERY, "unknown DS digest algorithm %d", algo);
- + break;
- + }
- + return 0;
- +}
- +
- +int
- +dnskey_algo_id_is_supported(int id)
- +{
- + switch(id) {
- + case LDNS_DSA:
- + case LDNS_DSA_NSEC3:
- + if(fake_dsa || fake_sha1) return 1;
- + return 0;
- + case LDNS_RSASHA1:
- + case LDNS_RSASHA1_NSEC3:
- +#ifdef USE_SHA1
- + return 1;
- +#else
- + if(fake_sha1) return 1;
- + return 0;
- +#endif
- +#ifdef USE_SHA2
- + case LDNS_RSASHA256:
- + case LDNS_RSASHA512:
- +#endif
- +#ifdef USE_ECDSA
- + case LDNS_ECDSAP256SHA256:
- + case LDNS_ECDSAP384SHA384:
- +#endif
- +#if defined(USE_SHA1) || defined(USE_SHA2)
- + return 1;
- +#endif
- +
- + default:
- + return 0;
- + }
- +}
- +
- +#if defined(USE_SHA1) || defined(USE_SHA2)
- +static char *
- +_verify_bearssl_rsa(sldns_buffer* buf, const unsigned char* hash,
- + size_t hashlen, const unsigned char* oid, const unsigned char* sig,
- + size_t siglen, unsigned char* key, size_t keylen)
- +{
- + br_rsa_public_key pubkey;
- + unsigned char sighash[64];
- +
- + /* RSA pubkey parsing as per RFC 3110 sec. 2 */
- + if(keylen <= 1) {
- + return "null RSA key";
- + }
- + if (key[0] != 0) {
- + /* 1-byte length */
- + pubkey.e = key + 1;
- + pubkey.elen = key[0];
- + } else {
- + /* 1-byte NUL + 2-bytes exponent length */
- + if (keylen < 3) {
- + return "incorrect RSA key length";
- + }
- + pubkey.e = key + 3;
- + pubkey.elen = (unsigned)key[1] << 8 | (unsigned)key[2];
- + if (pubkey.elen == 0)
- + return "null RSA exponent length";
- + }
- + /* Check that we are not over-running input length */
- + if (keylen < (pubkey.e - key) + pubkey.elen + 1) {
- + return "RSA key content shorter than expected";
- + }
- + pubkey.n = pubkey.e + pubkey.elen;
- + pubkey.nlen = keylen - (pubkey.n - key);
- +
- + if (br_rsa_pkcs1_vrfy_get_default()(sig, siglen, oid, hashlen, &pubkey,
- + sighash) != 1 || memcmp(hash, sighash, hashlen) != 0) {
- + return "RSA signature verification failed";
- + } else {
- + return NULL;
- + }
- +}
- +#endif
- +
- +#ifdef USE_ECDSA
- +static char *
- +_verify_bearssl_ecdsa(sldns_buffer* buf, int algo, const unsigned char* hash,
- + size_t hashlen, const unsigned char* sig, size_t siglen,
- + unsigned char* key, size_t keylen)
- +{
- + br_ec_public_key pubkey;
- + unsigned char q[97];
- +
- + /* uncompressed point format */
- + q[0] = 4;
- + switch(algo) {
- + case LDNS_ECDSAP256SHA256:
- + pubkey.curve = BR_EC_secp256r1;
- + if (keylen != 64) {
- + return "incorrect ECDSA P-256 key length";
- + }
- + memcpy(q + 1, key, 64);
- + break;
- + case LDNS_ECDSAP384SHA384:
- + pubkey.curve = BR_EC_secp384r1;
- + if (keylen != 96) {
- + return "incorrect ECDSA P-384 key length";
- + }
- + memcpy(q + 1, key, 96);
- + break;
- + default:
- + return "unsupported ECDSA algorithm";
- + }
- + pubkey.q = q;
- + pubkey.qlen = 1 + keylen;
- +
- + if (br_ecdsa_vrfy_raw_get_default()(br_ec_get_default(), hash, hashlen,
- + &pubkey, sig, siglen) != 1) {
- + return "ECDSA signature verification failed";
- + } else {
- + return NULL;
- + }
- +}
- +#endif
- +
- +/**
- + * Check a canonical sig+rrset and signature against a dnskey
- + * @param buf: buffer with data to verify, the first rrsig part and the
- + * canonicalized rrset.
- + * @param algo: DNSKEY algorithm.
- + * @param sigblock: signature rdata field from RRSIG
- + * @param sigblock_len: length of sigblock data.
- + * @param key: public key data from DNSKEY RR.
- + * @param keylen: length of keydata.
- + * @param reason: bogus reason in more detail.
- + * @return secure if verification succeeded, bogus on crypto failure,
- + * unchecked on format errors and alloc failures.
- + */
- +enum sec_status
- +verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sig,
- + unsigned int siglen, unsigned char* key, unsigned int keylen,
- + char** reason)
- +{
- + br_hash_compat_context ctx;
- + const unsigned char *oid;
- + unsigned char hash[64];
- + size_t hashlen;
- +
- + if (siglen == 0 || keylen == 0) {
- + *reason = "null signature";
- + return sec_status_bogus;
- + }
- +
- +#ifndef USE_DSA
- + if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && (fake_dsa || fake_sha1))
- + return sec_status_secure;
- +#endif
- +#ifndef USE_SHA1
- + if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3))
- + return sec_status_secure;
- +#endif
- +
- + switch(algo) {
- +#ifdef USE_SHA1
- + case LDNS_RSASHA1:
- + case LDNS_RSASHA1_NSEC3:
- + ctx.vtable = &br_sha1_vtable;
- + oid = BR_HASH_OID_SHA1;
- + break;
- +#endif
- +#ifdef USE_SHA2
- + case LDNS_RSASHA256:
- + ctx.vtable = &br_sha256_vtable;
- + oid = BR_HASH_OID_SHA256;
- + break;
- + case LDNS_RSASHA512:
- + ctx.vtable = &br_sha512_vtable;
- + oid = BR_HASH_OID_SHA512;
- + break;
- +#endif
- +#ifdef USE_ECDSA
- + case LDNS_ECDSAP256SHA256:
- + ctx.vtable = &br_sha256_vtable;
- + break;
- + case LDNS_ECDSAP384SHA384:
- + ctx.vtable = &br_sha384_vtable;
- + break;
- +#endif
- + default:
- + *reason = "unable to verify signature, unknown algorithm";
- + return sec_status_bogus;
- + }
- +
- + ctx.vtable->init(&ctx.vtable);
- + ctx.vtable->update(&ctx.vtable, sldns_buffer_begin(buf), sldns_buffer_limit(buf));
- + ctx.vtable->out(&ctx.vtable, hash);
- + hashlen = ctx.vtable->desc >> BR_HASHDESC_OUT_OFF & BR_HASHDESC_OUT_MASK;
- +
- + switch(algo) {
- +#if defined(USE_SHA1) || defined(USE_SHA2)
- +#ifdef USE_SHA1
- + case LDNS_RSASHA1:
- + case LDNS_RSASHA1_NSEC3:
- +#endif
- +#ifdef USE_SHA2
- + case LDNS_RSASHA256:
- + case LDNS_RSASHA512:
- +#endif
- + *reason = _verify_bearssl_rsa(buf, hash, hashlen, oid, sig,
- + siglen, key, keylen);
- + break;
- +#endif
- +#ifdef USE_ECDSA
- + case LDNS_ECDSAP256SHA256:
- + case LDNS_ECDSAP384SHA384:
- + *reason = _verify_bearssl_ecdsa(buf, algo, hash, hashlen,
- + sig, siglen, key, keylen);
- + break;
- +#endif
- + default:
- + *reason = "unable to verify signature, unknown algorithm";
- + }
- + if (*reason != NULL) {
- + return sec_status_bogus;
- + } else {
- + return sec_status_secure;
- + }
- +}
- +
- +#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE or HAVE_BEARSSL */
- diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c
- index b15fba3f..2ffe73b8 100644
- --- a/validator/val_sigcrypt.c
- +++ b/validator/val_sigcrypt.c
- @@ -58,7 +58,7 @@
- #include "sldns/wire2str.h"
- #include <ctype.h>
- -#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
- +#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) && !defined(HAVE_BEARSSL)
- #error "Need crypto library to do digital signature cryptography"
- #endif
- --
- 2.34.1