From dea37aee81bb24934e41fce1c8b378369c06ff77 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 31 Jul 2017 17:02:24 +0200 Subject: [PATCH] Added Ed25519 support (#44696) --- CHANGES | 2 + bin/dnssec/dnssec-keyfromlabel.c | 6 +- bin/dnssec/dnssec-keyfromlabel.docbook | 2 +- bin/dnssec/dnssec-keygen.c | 20 ++- bin/dnssec/dnssec-keygen.docbook | 6 +- bin/python/isc/dnskey.py.in | 2 +- bin/tests/system/conf.sh.in | 2 +- bin/tests/system/testcrypto.sh | 5 + config.h.in | 12 ++ config.h.win32 | 6 + configure | 91 ++++++++++++++ configure.in | 63 ++++++++++ lib/dns/Makefile.in | 9 +- lib/dns/dst_api.c | 17 ++- lib/dns/dst_internal.h | 6 + lib/dns/dst_parse.c | 24 ++++ lib/dns/dst_parse.h | 3 + lib/dns/include/dns/keyvalues.h | 8 ++ lib/dns/include/dst/dst.h | 2 + lib/dns/rcode.c | 2 + lib/dns/win32/libdns.dsp.in | 4 + lib/dns/win32/libdns.mak.in | 24 ++++ lib/dns/win32/libdns.vcxproj.filters.in | 3 + lib/dns/win32/libdns.vcxproj.in | 1 + win32utils/Configure | 154 +++++++++++++++++++++--- 25 files changed, 445 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index b197b3bcb4..7ff3b421ad 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4665. [func] Add Ed25519 support (RFC 8080). [RT #25519] + 4663. [cleanup] Clarify error message printed by dnssec-dsfromkey. [RT #21731] diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c index 62deaa003b..8e896aad7a 100644 --- a/bin/dnssec/dnssec-keyfromlabel.c +++ b/bin/dnssec/dnssec-keyfromlabel.c @@ -54,7 +54,8 @@ int verbose; static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |" " NSEC3DSA | NSEC3RSASHA1 |" " RSASHA256 | RSASHA512 | ECCGOST |" - " ECDSAP256SHA256 | ECDSAP384SHA384"; + " ECDSAP256SHA256 | ECDSAP384SHA384 |" + " ED25519 | ED448"; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; @@ -388,7 +389,8 @@ main(int argc, char **argv) { alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 && alg != DST_ALG_ECCGOST && - alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384) { + alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384 && + alg != DST_ALG_ED25519 && alg != DST_ALG_ED448) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook index 38adbf8084..badfef0a4c 100644 --- a/bin/dnssec/dnssec-keyfromlabel.docbook +++ b/bin/dnssec/dnssec-keyfromlabel.docbook @@ -107,7 +107,7 @@ Selects the cryptographic algorithm. The value of must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256 or ECDSAP384SHA384. + ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. These values are case insensitive. diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 0b194c6a59..d21bd7f68d 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -85,7 +85,8 @@ usage(void) { " | NSEC3DSA |\n"); fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n"); fprintf(stderr, " ECDSAP256SHA256 | ECDSAP384SHA384 |\n"); - fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | " + fprintf(stderr, " ED25519 | ED448 | DH |\n"); + fprintf(stderr, " HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | " "HMAC-SHA256 | \n"); fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n"); fprintf(stderr, " (default: RSASHA1, or " @@ -104,6 +105,8 @@ usage(void) { fprintf(stderr, " ECCGOST:\tignored\n"); fprintf(stderr, " ECDSAP256SHA256:\tignored\n"); fprintf(stderr, " ECDSAP384SHA384:\tignored\n"); + fprintf(stderr, " ED25519:\tignored\n"); + fprintf(stderr, " ED448:\tignored\n"); fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); @@ -549,7 +552,8 @@ main(int argc, char **argv) { alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 && alg != DST_ALG_ECCGOST && - alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384) { + alg != DST_ALG_ECDSA256 && alg != DST_ALG_ECDSA384 && + alg != DST_ALG_ED25519 && alg != DST_ALG_ED448) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } @@ -583,7 +587,9 @@ main(int argc, char **argv) { " to %d\n", size); } else if (alg != DST_ALG_ECCGOST && alg != DST_ALG_ECDSA256 && - alg != DST_ALG_ECDSA384) + alg != DST_ALG_ECDSA384 && + alg != DST_ALG_ED25519 && + alg != DST_ALG_ED448) fatal("key size not specified (-b option)"); } @@ -720,6 +726,12 @@ main(int argc, char **argv) { case DST_ALG_ECDSA384: size = 384; break; + case DST_ALG_ED25519: + size = 256; + break; + case DST_ALG_ED448: + size = 456; + break; case DST_ALG_HMACMD5: options |= DST_TYPE_KEY; if (size < 1 || size > 512) @@ -853,6 +865,8 @@ main(int argc, char **argv) { case DST_ALG_ECCGOST: case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: + case DST_ALG_ED25519: + case DST_ALG_ED448: show_progress = ISC_TRUE; /* fall through */ diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook index 490998ecef..a797a7a4ff 100644 --- a/bin/dnssec/dnssec-keygen.docbook +++ b/bin/dnssec/dnssec-keygen.docbook @@ -122,7 +122,7 @@ Selects the cryptographic algorithm. For DNSSEC keys, the value of must be one of RSAMD5, RSASHA1, DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256 or ECDSAP384SHA384. + ECDSAP256SHA256, ECDSAP384SHA384, ED25519 or ED448. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are @@ -194,8 +194,8 @@ If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, - ECDSAP256SHA256 and ECDSAP384SHA384 algorithms - are NSEC3-capable. + ECDSAP256SHA256, ECDSAP384SHA384, ED25519 and ED448 + algorithms are NSEC3-capable. diff --git a/bin/python/isc/dnskey.py.in b/bin/python/isc/dnskey.py.in index 744e239c1f..0c54566695 100644 --- a/bin/python/isc/dnskey.py.in +++ b/bin/python/isc/dnskey.py.in @@ -38,7 +38,7 @@ class dnskey: _ALGNAMES = (None, 'RSAMD5', 'DH', 'DSA', 'ECC', 'RSASHA1', 'NSEC3DSA', 'NSEC3RSASHA1', 'RSASHA256', None, 'RSASHA512', None, 'ECCGOST', 'ECDSAP256SHA256', - 'ECDSAP384SHA384') + 'ECDSAP384SHA384', 'ED25519', 'ED448') def __init__(self, key, directory=None, keyttl=None): # this makes it possible to use algname as a class or instance method diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index 1273a68abc..81c9a5c238 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -67,7 +67,7 @@ SAMPLEUPDATE=$TOP/lib/export/samples/sample-update SUBDIRS="acl additional allow_query addzone autosign builtin cacheclean case chain checkconf @CHECKDS@ checknames checkzone @COVERAGE@ database digdelv dlv dlvauto dlz dlzexternal - dns64 dnssec ecdsa emptyzones fetchlimit filter-aaaa + dns64 dnssec ecdsa eddsa emptyzones fetchlimit filter-aaaa formerr forward glue gost inline integrity ixfr legacy limits logfileconfig lwresd masterfile masterformat metadata notify nslookup nsupdate pending pkcs11 reclimit redirect diff --git a/bin/tests/system/testcrypto.sh b/bin/tests/system/testcrypto.sh index efa5986546..93f8e59e85 100644 --- a/bin/tests/system/testcrypto.sh +++ b/bin/tests/system/testcrypto.sh @@ -47,6 +47,11 @@ while test "$#" -gt 0; do msg1="ECDSA cryptography" msg2="--with-ecdsa" ;; + eddsa|EDDSA) + alg="-a ED25519" + msg1="EDDSA cryptography" + msg2="--with-eddsa" + ;; *) echo "${prog}: unknown argument" exit 1 diff --git a/config.h.in b/config.h.in index 76578f3253..3e5b9f176e 100644 --- a/config.h.in +++ b/config.h.in @@ -138,6 +138,12 @@ int sigwait(const unsigned int *set, int *sig); /* Define if OpenSSL includes ECDSA support */ #undef HAVE_OPENSSL_ECDSA +/* Define if your OpenSSL version supports Ed25519. */ +#undef HAVE_OPENSSL_ED25519 + +/* Define if your OpenSSL version supports Ed448. */ +#undef HAVE_OPENSSL_ED448 + /* Define to the length type used by the socket API (socklen_t, size_t, int). */ #undef ISC_SOCKADDR_LEN_T @@ -329,6 +335,12 @@ int sigwait(const unsigned int *set, int *sig); /* Define if your OpenSSL version supports ECDSA. */ #undef HAVE_OPENSSL_ECDSA +/* Define if your PKCS11 provider supports Ed25519. */ +#undef HAVE_PKCS11_ED25519 + +/* Define if your PKCS11 provider supports Ed448. */ +#undef HAVE_PKCS11_ED448 + /* Define if your OpenSSL version supports GOST. */ #undef HAVE_OPENSSL_GOST diff --git a/config.h.win32 b/config.h.win32 index 14f0fe7806..8e89e71f0b 100644 --- a/config.h.win32 +++ b/config.h.win32 @@ -326,6 +326,12 @@ typedef __int64 off_t; /* Define if OpenSSL includes ECDSA support */ @HAVE_OPENSSL_ECDSA@ +/* Define if OpenSSL includes Ed25519 support */ +@HAVE_OPENSSL_ED25519@ + +/* Define if OpenSSL includes Ed448 support */ +@HAVE_OPENSSL_ED448@ + /* Define if your OpenSSL version supports GOST. */ @HAVE_OPENSSL_GOST@ diff --git a/configure b/configure index 016d63f41f..ba89f8031b 100755 --- a/configure +++ b/configure @@ -835,11 +835,14 @@ USE_PKCS11 ISC_OPENSSL_INC ISC_PLATFORM_OPENSSLHASH OPENSSL_GOST +OPENSSL_ED25519 OPENSSL_ECDSA OPENSSLLINKSRCS OPENSSLLINKOBJS OPENSSLGOSTLINKSRCS OPENSSLGOSTLINKOBJS +OPENSSLEDDSALINKSRCS +OPENSSLEDDSALINKOBJS DST_OPENSSL_INC USE_OPENSSL LWRES_PLATFORM_NEEDSYSSELECTH @@ -984,6 +987,7 @@ with_openssl enable_openssl_version_check with_ecdsa with_gost +with_eddsa enable_openssl_hash with_pkcs11 with_gssapi @@ -1710,6 +1714,7 @@ Optional Packages: (Required for DNSSEC) --with-ecdsa OpenSSL ECDSA --with-gost OpenSSL GOST + --with-eddsa OpenSSL EDDSA --with-pkcs11=PATH Build with PKCS11 support yes|no|path (PATH is for the PKCS11 provider) --with-gssapi=[PATH|[/path/]krb5-config] Specify path for system-supplied GSSAPI [default=yes] @@ -13685,6 +13690,7 @@ then done fi OPENSSL_ECDSA="" +OPENSSL_ED25519="" OPENSSL_GOST="" case "$use_openssl" in no) @@ -13694,6 +13700,8 @@ $as_echo "no" >&6; } USE_OPENSSL="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" + OPENSSLEDDSALINKOBJS="" + OPENSSLEDDSALINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; @@ -13702,6 +13710,8 @@ $as_echo "no" >&6; } USE_OPENSSL="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" + OPENSSLEDDSALINKOBJS="" + OPENSSLEDDSALINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" as_fn_error $? "OpenSSL was not found in any of $openssldirs; use --with-openssl=/path @@ -14113,6 +14123,80 @@ $as_echo "#define HAVE_OPENSSL_GOST 1" >>confdefs.h *) ;; esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL Ed25519 support" >&5 +$as_echo_n "checking for OpenSSL Ed25519 support... " >&6; } + have_ed25519="" + have_ed448="" + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using --with-eddsa" >&5 +$as_echo "using --with-eddsa" >&6; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main() { + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); + if (ctx == NULL) + return (2); + return (0); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_ed25519="yes" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_ed25519="no" +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +# Check whether --with-eddsa was given. +if test "${with_eddsa+set}" = set; then : + withval=$with_eddsa; with_eddsa="$withval" +else + with_eddsa="auto" +fi + + case "$with_eddsa" in + yes) + case "$have_ed25519" in + no) as_fn_error $? "eddsa not supported" "$LINENO" 5 ;; + *) have_ed25519=yes ;; + esac + ;; + no) + have_ed25519=no ;; + *) + case "$have_ed25519" in + yes|no) ;; + *) as_fn_error $? "need --with-eddsa=[yes or no]" "$LINENO" 5 ;; + esac + ;; + esac + case $have_ed25519 in + yes) + OPENSSL_ED25519="yes" + OPENSSLEDDSALINKOBJS='${OPENSSLEDDSALINKOBJS}' + OPENSSLEDDSALINKSRCS='${OPENSSLEDDSALINKSRCS}' + +$as_echo "#define HAVE_OPENSSL_ED25519 1" >>confdefs.h + + ;; + *) + ;; + esac + CFLAGS="$saved_cflags" LIBS="$saved_libs" OPENSSLLINKOBJS='${OPENSSLLINKOBJS}' @@ -14135,6 +14219,9 @@ esac + + + DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" # @@ -23886,6 +23973,8 @@ report() { echo " GOST algorithm support (--with-gost)" test "yes" != "$OPENSSL_ECDSA" || \ echo " ECDSA algorithm support (--with-ecdsa)" + test "yes" != "$OPENSSL_ED25519." || \ + echo " EDDSA algorithm support (--with-eddsa)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" || echo " XML statistics (--with-libxml2)" fi @@ -23932,6 +24021,8 @@ report() { echo " GOST algorithm support (--with-gost)" test "X$USE_OPENSSL" != "X" -a "$OPENSSL_ECDSA" != "yes" && \ echo " ECDSA algorithm support (--with-ecdsa)" + test "X$USE_OPENSSL" != "X" -a "$OPENSSL_ED25519" != "yes" && \ + echo " EDDSA algorithm support (--with-eddsa)" test "X$PYTHON" = "X" && echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" && echo " XML statistics (--with-libxml2)" diff --git a/configure.in b/configure.in index 8d30b35fad..48fadb745a 100644 --- a/configure.in +++ b/configure.in @@ -723,6 +723,7 @@ then done fi OPENSSL_ECDSA="" +OPENSSL_ED25519="" OPENSSL_GOST="" case "$use_openssl" in no) @@ -731,6 +732,8 @@ case "$use_openssl" in USE_OPENSSL="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" + OPENSSLEDDSALINKOBJS="" + OPENSSLEDDSALINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" ;; @@ -739,6 +742,8 @@ case "$use_openssl" in USE_OPENSSL="" OPENSSLGOSTLINKOBJS="" OPENSSLGOSTLINKSRS="" + OPENSSLEDDSALINKOBJS="" + OPENSSLEDDSALINKSRS="" OPENSSLLINKOBJS="" OPENSSLLINKSRCS="" AC_MSG_ERROR( @@ -1025,6 +1030,57 @@ int main() { *) ;; esac + + AC_MSG_CHECKING(for OpenSSL Ed25519 support) + have_ed25519="" + have_ed448="" + AC_TRY_RUN([ +#include +#include +int main() { + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); + if (ctx == NULL) + return (2); + return (0); +} +], + [AC_MSG_RESULT(yes) + have_ed25519="yes"], + [AC_MSG_RESULT(no) + have_ed25519="no"], + [AC_MSG_RESULT(using --with-eddsa)]) + AC_ARG_WITH(eddsa, [ --with-eddsa OpenSSL EDDSA], + with_eddsa="$withval", with_eddsa="auto") + case "$with_eddsa" in + yes) + case "$have_ed25519" in + no) AC_MSG_ERROR([eddsa not supported]) ;; + *) have_ed25519=yes ;; + esac + ;; + no) + have_ed25519=no ;; + *) + case "$have_ed25519" in + yes|no) ;; + *) AC_MSG_ERROR([need --with-eddsa=[[yes or no]]]) ;; + esac + ;; + esac + case $have_ed25519 in + yes) + OPENSSL_ED25519="yes" + OPENSSLEDDSALINKOBJS='${OPENSSLEDDSALINKOBJS}' + OPENSSLEDDSALINKSRCS='${OPENSSLEDDSALINKSRCS}' + AC_DEFINE(HAVE_OPENSSL_ED25519, 1, + [Define if your OpenSSL version supports Ed25519.]) + ;; + *) + ;; + esac + CFLAGS="$saved_cflags" LIBS="$saved_libs" OPENSSLLINKOBJS='${OPENSSLLINKOBJS}' @@ -1040,11 +1096,14 @@ esac AC_SUBST(USE_OPENSSL) AC_SUBST(DST_OPENSSL_INC) +AC_SUBST(OPENSSLEDDSALINKOBJS) +AC_SUBST(OPENSSLEDDSALINKSRCS) AC_SUBST(OPENSSLGOSTLINKOBJS) AC_SUBST(OPENSSLGOSTLINKSRCS) AC_SUBST(OPENSSLLINKOBJS) AC_SUBST(OPENSSLLINKSRCS) AC_SUBST(OPENSSL_ECDSA) +AC_SUBST(OPENSSL_ED25519) AC_SUBST(OPENSSL_GOST) DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" @@ -4387,6 +4446,8 @@ report() { echo " GOST algorithm support (--with-gost)" test "yes" != "$OPENSSL_ECDSA" || \ echo " ECDSA algorithm support (--with-ecdsa)" + test "yes" != "$OPENSSL_ED25519." || \ + echo " EDDSA algorithm support (--with-eddsa)" test "X$PYTHON" = "X" || echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" || echo " XML statistics (--with-libxml2)" fi @@ -4433,6 +4494,8 @@ report() { echo " GOST algorithm support (--with-gost)" test "X$USE_OPENSSL" != "X" -a "$OPENSSL_ECDSA" != "yes" && \ echo " ECDSA algorithm support (--with-ecdsa)" + test "X$USE_OPENSSL" != "X" -a "$OPENSSL_ED25519" != "yes" && \ + echo " EDDSA algorithm support (--with-eddsa)" test "X$PYTHON" = "X" && echo " Python tools (--with-python)" test "X$libxml2_libs" = "X" && echo " XML statistics (--with-libxml2)" diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index 76b7f91722..6fdbd57e95 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -45,9 +45,10 @@ LIBS = @LIBS@ # Alphabetically OPENSSLGOSTLINKOBJS = opensslgost_link.@O@ +OPENSSLEDDSALINKOBJS = openssleddsa_link.@O@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \ - opensslrsa_link.@O@ + opensslecdsa_link.@O@ @OPENSSLEDDSALINKOBJS@ \ + @OPENSSLGOSTLINKOBJS@ opensslrsa_link.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -78,8 +79,10 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} @RRLLINKOBJS@ # Alphabetically OPENSSLGOSTLINKSRCS = opensslgost_link.c +OPENSSLEDDDSALINKSRCS = openssleddsa_link.c OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ - opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c + opensslecdsa_link.c @OPENSSLEDDDSALINKSRCS@ \ + @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index eee4584225..661847f47c 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -218,6 +218,12 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); #endif +#ifdef HAVE_OPENSSL_ED25519 + RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED25519])); +#endif +#ifdef HAVE_OPENSSL_ED448 + RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED448])); +#endif #endif /* OPENSSL */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); @@ -1180,6 +1186,12 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) { case DST_ALG_ECDSA384: *n = DNS_SIG_ECDSA384SIZE; break; + case DST_ALG_ED25519: + *n = DNS_SIG_ED25519SIZE; + break; + case DST_ALG_ED448: + *n = DNS_SIG_ED448SIZE; + break; case DST_ALG_HMACMD5: *n = 16; break; @@ -1508,6 +1520,8 @@ issymmetric(const dst_key_t *key) { case DST_ALG_ECCGOST: case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: + case DST_ALG_ED25519: + case DST_ALG_ED448: return (ISC_FALSE); case DST_ALG_HMACMD5: case DST_ALG_HMACSHA1: @@ -1792,7 +1806,8 @@ algorithm_status(unsigned int alg) { alg == DST_ALG_NSEC3RSASHA1 || alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 || alg == DST_ALG_ECCGOST || - alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384) + alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384 || + alg == DST_ALG_ED25519 || alg == DST_ALG_ED448) return (DST_R_NOCRYPTO); #endif return (DST_R_UNSUPPORTEDALG); diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index 49ca424e5b..c8f0590789 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -227,6 +227,12 @@ isc_result_t dst__opensslgost_init(struct dst_func **funcp); #ifdef HAVE_OPENSSL_ECDSA isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); #endif +#if defined(HAVE_OPENSSL_ED25519) || defined(HAVE_OPENSSL_ED448) +isc_result_t dst__openssleddsa_init(struct dst_func **funcp); +#endif +#if defined(HAVE_PKCS11_ED25519) || defined(HAVE_PKCS11_ED448) +isc_result_t dst__pkcs11eddsa_init(struct dst_func **funcp); +#endif /*% * Destructors diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c index 989dc86300..13a2d9dfe9 100644 --- a/lib/dns/dst_parse.c +++ b/lib/dns/dst_parse.c @@ -111,6 +111,8 @@ static struct parse_map map[] = { {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"}, + {TAG_EDDSA_PRIVATEKEY, "PrivateKey:"}, + {TAG_HMACMD5_KEY, "Key:"}, {TAG_HMACMD5_BITS, "Bits:"}, @@ -281,6 +283,19 @@ check_ecdsa(const dst_private_t *priv, isc_boolean_t external) { return (0); } +static int +check_eddsa(const dst_private_t *priv, isc_boolean_t external) { + + if (external) + return ((priv->nelements == 0) ? 0 : -1); + + if (priv->nelements != EDDSA_NTAGS) + return (-1); + if (priv->elements[0].tag != TAG(DST_ALG_ED25519, 0)) + return (-1); + return (0); +} + static int check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) { int i, j; @@ -347,6 +362,9 @@ check_data(const dst_private_t *priv, const unsigned int alg, case DST_ALG_ECDSA256: case DST_ALG_ECDSA384: return (check_ecdsa(priv, external)); + case DST_ALG_ED25519: + case DST_ALG_ED448: + return (check_eddsa(priv, external)); case DST_ALG_HMACMD5: return (check_hmac_md5(priv, old)); case DST_ALG_HMACSHA1: @@ -682,6 +700,12 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, case DST_ALG_ECDSA384: fprintf(fp, "(ECDSAP384SHA384)\n"); break; + case DST_ALG_ED25519: + fprintf(fp, "(ED25519)\n"); + break; + case DST_ALG_ED448: + fprintf(fp, "(ED448)\n"); + break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h index f048bf0c01..8a09b44598 100644 --- a/lib/dns/dst_parse.h +++ b/lib/dns/dst_parse.h @@ -84,6 +84,9 @@ #define ECDSA_NTAGS 1 #define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0) +#define EDDSA_NTAGS 4 +#define TAG_EDDSA_PRIVATEKEY ((DST_ALG_ED25519 << TAG_SHIFT) + 0) + #define OLD_HMACMD5_NTAGS 1 #define HMACMD5_NTAGS 2 #define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h index 0c392ca14c..3638ee413f 100644 --- a/lib/dns/include/dns/keyvalues.h +++ b/lib/dns/include/dns/keyvalues.h @@ -73,6 +73,8 @@ #define DNS_KEYALG_ECCGOST 12 #define DNS_KEYALG_ECDSA256 13 #define DNS_KEYALG_ECDSA384 14 +#define DNS_KEYALG_ED25519 15 +#define DNS_KEYALG_ED448 16 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 #define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ @@ -109,4 +111,10 @@ #define DNS_KEY_ECDSA256SIZE 64 #define DNS_KEY_ECDSA384SIZE 96 +#define DNS_SIG_ED25519SIZE 64 +#define DNS_SIG_ED448SIZE 114 + +#define DNS_KEY_ED25519SIZE 32 +#define DNS_KEY_ED448SIZE 57 + #endif /* DNS_KEYVALUES_H */ diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index 1497edcb65..c27c4f71b9 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -62,6 +62,8 @@ typedef struct dst_context dst_context_t; #define DST_ALG_ECCGOST 12 #define DST_ALG_ECDSA256 13 #define DST_ALG_ECDSA384 14 +#define DST_ALG_ED25519 15 +#define DST_ALG_ED448 16 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 #define DST_ALG_HMACSHA1 161 /* XXXMPA */ diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c index 1f97ad0376..dc63c204e3 100644 --- a/lib/dns/rcode.c +++ b/lib/dns/rcode.c @@ -117,6 +117,8 @@ { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \ { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \ { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \ + { DNS_KEYALG_ED25519, "ED25519", 0 }, \ + { DNS_KEYALG_ED448, "ED448", 0 }, \ { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ diff --git a/lib/dns/win32/libdns.dsp.in b/lib/dns/win32/libdns.dsp.in index 2ccdb46727..5c1bf788a4 100644 --- a/lib/dns/win32/libdns.dsp.in +++ b/lib/dns/win32/libdns.dsp.in @@ -818,6 +818,10 @@ SOURCE=..\opensslecdsa_link.c # End Source File # Begin Source File +SOURCE=..\openssleddsa_link.c +# End Source File +# Begin Source File + SOURCE=..\opensslgost_link.c # End Source File # Begin Source File diff --git a/lib/dns/win32/libdns.mak.in b/lib/dns/win32/libdns.mak.in index 6c2e6a1ec0..d25fd505c6 100644 --- a/lib/dns/win32/libdns.mak.in +++ b/lib/dns/win32/libdns.mak.in @@ -165,6 +165,7 @@ CLEAN : -@erase "$(INTDIR)\openssldh_link.obj" -@erase "$(INTDIR)\openssldsa_link.obj" -@erase "$(INTDIR)\opensslecdsa_link.obj" + -@erase "$(INTDIR)\openssleddsa_link.obj" -@erase "$(INTDIR)\opensslgost_link.obj" -@erase "$(INTDIR)\opensslrsa_link.obj" -@erase "$(INTDIR)\order.obj" @@ -347,6 +348,7 @@ LINK32_OBJS= \ "$(INTDIR)\openssldh_link.obj" \ "$(INTDIR)\openssldsa_link.obj" \ "$(INTDIR)\opensslecdsa_link.obj" \ + "$(INTDIR)\openssleddsa_link.obj" \ "$(INTDIR)\opensslgost_link.obj" \ "$(INTDIR)\opensslrsa_link.obj" \ "..\..\isc\win32\Release\libisc.lib" @@ -472,6 +474,8 @@ CLEAN : -@erase "$(INTDIR)\openssldsa_link.sbr" -@erase "$(INTDIR)\opensslecdsa_link.obj" -@erase "$(INTDIR)\opensslecdsa_link.sbr" + -@erase "$(INTDIR)\openssleddsa_link.obj" + -@erase "$(INTDIR)\openssleddsa_link.sbr" -@erase "$(INTDIR)\opensslgost_link.obj" -@erase "$(INTDIR)\opensslgost_link.sbr" -@erase "$(INTDIR)\opensslrsa_link.obj" @@ -695,6 +699,7 @@ BSC32_SBRS= \ "$(INTDIR)\openssldh_link.sbr" \ "$(INTDIR)\openssldsa_link.sbr" \ "$(INTDIR)\opensslecdsa_link.sbr" \ + "$(INTDIR)\openssleddsa_link.sbr" \ "$(INTDIR)\opensslgost_link.sbr" \ "$(INTDIR)\opensslrsa_link.sbr" @@ -794,6 +799,7 @@ LINK32_OBJS= \ "$(INTDIR)\openssldh_link.obj" \ "$(INTDIR)\openssldsa_link.obj" \ "$(INTDIR)\opensslecdsa_link.obj" \ + "$(INTDIR)\openssleddsa_link.obj" \ "$(INTDIR)\opensslgost_link.obj" \ "$(INTDIR)\opensslrsa_link.obj" \ "..\..\isc\win32\Debug\libisc.lib" @@ -2365,6 +2371,24 @@ SOURCE=..\opensslecdsa_link.c $(CPP) $(CPP_PROJ) $(SOURCE) +!ENDIF + +SOURCE=..\openssleddsa_link.c + +!IF "$(CFG)" == "libdns - @PLATFORM@ Release" + + +"$(INTDIR)\openssleddsa_link.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "libdns - @PLATFORM@ Debug" + + +"$(INTDIR)\openssleddsa_link.obj" "$(INTDIR)\openssleddsa_link.sbr" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + !ENDIF SOURCE=..\opensslgost_link.c diff --git a/lib/dns/win32/libdns.vcxproj.filters.in b/lib/dns/win32/libdns.vcxproj.filters.in index b1f176c5f9..2525b538df 100644 --- a/lib/dns/win32/libdns.vcxproj.filters.in +++ b/lib/dns/win32/libdns.vcxproj.filters.in @@ -284,6 +284,9 @@ Dst Source Files + + Dst Source Files + Dst Source Files diff --git a/lib/dns/win32/libdns.vcxproj.in b/lib/dns/win32/libdns.vcxproj.in index 4ca2a52725..be05f92cb0 100644 --- a/lib/dns/win32/libdns.vcxproj.in +++ b/lib/dns/win32/libdns.vcxproj.in @@ -155,6 +155,7 @@ + diff --git a/win32utils/Configure b/win32utils/Configure index 10249cd03a..91177e393d 100644 --- a/win32utils/Configure +++ b/win32utils/Configure @@ -327,6 +327,8 @@ my @substdefh = ("ALLOW_FILTER_AAAA", "HAVE_LIBXML2", "HAVE_OPENSSL_DSA", "HAVE_OPENSSL_ECDSA", + "HAVE_OPENSSL_ED25519", + "HAVE_OPENSSL_ED448", "HAVE_OPENSSL_GOST", "HAVE_READLINE", "ISC_LIST_CHECKINIT", @@ -455,6 +457,7 @@ my @enablelist = ("developer", my @withlist = ("cross-compile", "ecdsa", + "eddsa", "extra-tests", "gssapi", "geoip", @@ -508,6 +511,7 @@ my @help = ( " with-openssl[=PATH] build with OpenSSL yes|no|path\n", " with-pkcs11[=PATH] build with PKCS#11 support yes|no|provider-path\n", " with-ecdsa crypto ECDSA\n", +" with-eddsa crypto EDDSA yes|all|no\n", " with-gost crypto GOST\n", " with-gssapi[=PATH] build with MIT KfW GSSAPI yes|no|path\n", " with-libxml2[=PATH] build with libxml2 library yes|no|path\n", @@ -545,6 +549,8 @@ my $openssl_path = "..\\..\\"; my $use_pkcs11 = "no"; my $pkcs11_path = "unknown"; my $use_ecdsa = "auto"; +my $use_eddsa = "auto"; +my $use_ed448 = "auto"; my $use_gost = "auto"; my $use_gssapi = "no"; my $gssapi_path = "C:\\Program\ Files\\MIT\\Kerberos\\"; @@ -619,19 +625,19 @@ if ($legacy_only && ($want_x64 ne "yes")) { } if ($want_checkfiles eq "yes") { - foreach (@filelist) { - next if -r $_ . ".in"; - s/\\/\//g; - next if -r $_ . ".in"; - print "missing $_.in from filelist\n"; - } - foreach (@projectlist) { - next if -r $_ . ".in"; - s/\\/\//g; - next if -r $_ . ".in"; - print "missing $_.in from projectlist\n"; - } - exit(0); + foreach (@filelist) { + next if -r $_ . ".in"; + s/\\/\//g; + next if -r $_ . ".in"; + print "missing $_.in from filelist\n"; + } + foreach (@projectlist) { + next if -r $_ . ".in"; + s/\\/\//g; + next if -r $_ . ".in"; + print "missing $_.in from projectlist\n"; + } + exit(0); } # configure the platform @@ -810,10 +816,19 @@ sub mywith { } elsif ($val =~ /^yes$/i) { $use_ecdsa = "yes"; } + } elsif ($key =~ /^eddsa$/i) { + if ($val =~ /^no$/i) { + $use_eddsa = "no"; + } elsif ($val !~ /^no$/i) { + $use_eddsa = "yes"; + if ($val =~ /^all$/i) { + $use_ed448 = "yes"; + } + } } elsif ($key =~ /^gost$/i) { if ($val =~ /^no$/i) { $use_gost = "no"; - } elsif ($val =~ /^yes$/i) { + } elsif ($val !~ /^no$/i) { $use_gost = "yes"; } } elsif ($key =~ /^gssapi$/i) { @@ -997,6 +1012,16 @@ if ($verbose) { } else { print "ecdsa: enabled\n"; } + if ($use_eddsa eq "no") { + print "eddsa: disabled\n"; + } else { + print "ed25519: enabled\n"; + if ($use_ed448 eq "no") { + print "ed448: disabled\n"; + } else { + print "ed448: enabled\n"; + } + } if ($use_gost eq "no") { print "gost: disabled\n"; } else { @@ -1526,6 +1551,7 @@ EOF if ($verbose) { print "EVP_sha512 test failed: disabling EVP_sha512\n"; } + $use_eddsa = "no"; } else { $configdefh{"HAVE_EVP_SHA512"} = 1; } @@ -1534,6 +1560,7 @@ EOF print "can't compile EVP_sha512 test: $compret\n"; print "disabling EVP_sha512\n"; } + $use_eddsa = "no"; } } @@ -1588,6 +1615,104 @@ if ($use_ecdsa ne "no") { $configdefh{"HAVE_OPENSSL_ECDSA"} = 1; } +# with-eddsa +if ($use_openssl eq "no") { + $use_eddsa = "no"; +} +if ($use_eddsa eq "auto") { + if ($verbose) { + print "checking for OpenSSL ED25519 support\n"; + } + open F, ">tested25519.c" || die $!; + print F << 'EOF'; +#include +#include + +int +main(void) +{ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); + if (ctx == NULL) + return (2); + return (0); +} +EOF + close F; + my $include = $configinc{"OPENSSL_INC"}; + my $library = $configlib{"OPENSSL_LIB"}; + $compret = `cl /nologo /MD /I "$include" tested25519.c "$library"`; + if (grep { -f and -x } ".\\tested25519.exe") { + `.\\tested25519.exe`; + if ($? != 0) { + if ($verbose) { + print "EDDSA test failed: disabling EDDSA\n"; + } + $use_eddsa = "no"; + } + } else { + if ($verbose) { + print "can't compile EDDSA test: $compret\n"; + print "disabling EDDSA\n"; + } + $use_eddsa = "no"; + } +} + +if ($use_eddsa ne "no") { + $use_eddsa = "yes"; + $configdefh{"HAVE_OPENSSL_ED25519"} = 1; +} else { + $use_ed448 = "no"; +} + +if ($use_ed448 eq "auto") { + if ($verbose) { + print "checking for OpenSSL ED448 support\n"; + } + open F, ">tested448.c" || die $!; + print F << 'EOF'; +#include +#include + +int +main(void) +{ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL); + if (ctx == NULL) + return (2); + return (0); +} +EOF + close F; + my $include = $configinc{"OPENSSL_INC"}; + my $library = $configlib{"OPENSSL_LIB"}; + $compret = `cl /nologo /MD /I "$include" tested448.c "$library"`; + if (grep { -f and -x } ".\\tested448.exe") { + `.\\tested448.exe`; + if ($? != 0) { + if ($verbose) { + print "ED448 test failed: disabling ED448\n"; + } + $use_ed448 = "no"; + } + } else { + if ($verbose) { + print "can't compile ED448 test: $compret\n"; + print "disabling ED448\n"; + } + $use_ed448 = "no"; + } +} + +if ($use_ed448 ne "no") { + $use_ed448 = "yes"; + $configdefh{"HAVE_OPENSSL_ED448"} = 1; +} + # with-gost if ($use_openssl eq "no") { $use_gost = "no"; @@ -2839,6 +2964,7 @@ exit 0; # --with-openssl supported # --with-pkcs11 supported # --with-ecdsa supported +# --with-eddsa supported # --with-gost supported # --with-geoip supported # --with-gssapi supported with MIT (K)erberos (f)or (W)indows