]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Probe if ED448 and ED25519 are supported
authorMark Andrews <marka@isc.org>
Mon, 15 Aug 2022 05:36:03 +0000 (15:36 +1000)
committerMark Andrews <marka@isc.org>
Mon, 3 Apr 2023 02:06:04 +0000 (12:06 +1000)
ED448 and ED25519 may or may not be supported in FIPS mode depending
upon the implementation.

lib/dns/dst_api.c
lib/dns/dst_internal.h
lib/dns/openssleddsa_link.c
util/gen-eddsa-vectors.c [new file with mode: 0644]

index 896ee7625192f041f707a283c7b1c3fabac5109f..4cd63395c26e7c8de9c4aa58ee5f753a8527497a 100644 (file)
@@ -219,10 +219,12 @@ dst_lib_init(isc_mem_t *mctx, const char *engine) {
        RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256]));
        RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384]));
 #ifdef HAVE_OPENSSL_ED25519
-       RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED25519]));
+       RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED25519],
+                                     DST_ALG_ED25519));
 #endif /* ifdef HAVE_OPENSSL_ED25519 */
 #ifdef HAVE_OPENSSL_ED448
-       RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED448]));
+       RETERR(dst__openssleddsa_init(&dst_t_func[DST_ALG_ED448],
+                                     DST_ALG_ED448));
 #endif /* ifdef HAVE_OPENSSL_ED448 */
 
 #if HAVE_GSSAPI
index 40b54dd0292b9b7db316ff115dbf3559a3d2dbf4..ad9e097fd9e3cc0c2427695492496c194cd49c10 100644 (file)
@@ -215,7 +215,7 @@ isc_result_t
 dst__opensslecdsa_init(struct dst_func **funcp);
 #if HAVE_OPENSSL_ED25519 || HAVE_OPENSSL_ED448
 isc_result_t
-dst__openssleddsa_init(struct dst_func **funcp);
+dst__openssleddsa_init(struct dst_func **funcp, unsigned char algorithm);
 #endif /* HAVE_OPENSSL_ED25519 || HAVE_OPENSSL_ED448 */
 #if HAVE_GSSAPI
 isc_result_t
index a2c6f6f4a676343fa10b58442bdf72ec055c10c9..a547ac37d4e34f31220eeb9489eff0782e6af311 100644 (file)
@@ -339,7 +339,7 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
        isc_result_t ret;
        isc_region_t r;
        size_t len;
-       EVP_PKEY *pkey;
+       EVP_PKEY *pkey = NULL;
 
        REQUIRE(alginfo != NULL);
 
@@ -565,11 +565,108 @@ static dst_func_t openssleddsa_functions = {
        NULL, /*%< restore */
 };
 
+/*
+ * The test vectors below where generated by util/gen-eddsa-vectors.c
+ */
+#if HAVE_OPENSSL_ED448
+static unsigned char ed448_pub[] =
+       "\x0a\x19\x36\xf0\x4c\x2d\xc1\xfe\xbe\xdc\xfa\xf6\xeb\xd2\x8f\x3b\x04"
+       "\x14\x2e\x88\xc6\xb5\xdc\xe8\x2a\xc6\xb9\x7c\xa8\x22\xe8\x36\xfb\x06"
+       "\x55\xa3\x3c\xdb\x9d\x68\x59\x7e\xa9\x5f\x93\x96\x87\x83\x28\xce\xdd"
+       "\x12\xc9\xb8\x78\x02\x80";
+static unsigned char ed448_sig[] =
+       "\x7e\xec\x4e\x11\xd9\x79\x89\xd2\xe2\x85\x7a\x1c\xd7\x36\xe8\x24\x1f"
+       "\x90\xa0\x9c\x84\xfb\x51\xcd\xdc\xfd\x05\xcd\x8c\x08\x51\x05\x18\xc8"
+       "\x85\xb2\x28\x00\xea\xfe\x10\x46\xad\x52\xe6\xe9\x62\x35\x3b\x2a\x14"
+       "\x8b\xe7\xf0\x66\x5f\x00\x66\x3c\xa1\x4d\x03\x95\xcc\x73\xfc\xf2\x40"
+       "\x4b\x67\x85\x5b\x9f\xa9\x87\xb6\xbb\xa3\x9d\x73\x9f\xcb\x4e\x2c\xd2"
+       "\x46\xc7\x84\xd3\x7d\x94\x32\x30\x27\xb0\xa7\xf6\x6d\xf4\x77\xe8\xf5"
+       "\xb4\xee\x3f\x0e\x2b\x35\xdd\x5a\x35\xfe\x35\x00";
+#endif
+
+#if HAVE_OPENSSL_ED25519
+static unsigned char ed25519_pub[] =
+       "\x66\x5c\x21\x59\xe3\xa0\x6e\xa3\x7d\x82\x7c\xf1\xe7\xa3\xdd\xaf\xd1"
+       "\x6d\x92\x81\xfb\x09\x0c\x7c\xfe\x6d\xf8\x87\x24\x7e\x6e\x25";
+static unsigned char ed25519_sig[] =
+       "\x26\x70\x5c\xc1\x85\xb6\x5e\x65\xe5\xa7\xd5\x85\x63\xc9\x1d\x45\x56"
+       "\x38\xa3\x9c\xa3\x42\x4d\xc8\x89\xff\x84\xea\x2c\xa8\x8b\xfa\x2f\xab"
+       "\x75\x7c\x68\x95\xfd\xdf\x62\x60\x4e\x4d\x10\xf8\x3c\xae\xcf\x18\x93"
+       "\x90\x05\xa4\x54\x38\x45\x2f\x81\x71\x1e\x0f\x46\x04";
+#endif
+
+static isc_result_t
+check_algorithm(unsigned char algorithm) {
+       EVP_MD_CTX *evp_md_ctx = EVP_MD_CTX_create();
+       EVP_PKEY *pkey = NULL;
+       const eddsa_alginfo_t *alginfo = NULL;
+       const unsigned char *key = NULL;
+       const unsigned char *sig = NULL;
+       const unsigned char test[] = "test";
+       isc_result_t ret = ISC_R_SUCCESS;
+       size_t key_len, sig_len;
+
+       if (evp_md_ctx == NULL) {
+               DST_RET(ISC_R_NOMEMORY);
+       }
+
+       switch (algorithm) {
+#if HAVE_OPENSSL_ED448
+       case DST_ALG_ED448:
+               sig = ed448_sig;
+               sig_len = sizeof(ed448_sig) - 1;
+               key = ed448_pub;
+               key_len = sizeof(ed448_pub) - 1;
+               alginfo = openssleddsa_alg_info(algorithm);
+               break;
+#endif
+#if HAVE_OPENSSL_ED25519
+       case DST_ALG_ED25519:
+               sig = ed25519_sig;
+               sig_len = sizeof(ed25519_sig) - 1;
+               key = ed25519_pub;
+               key_len = sizeof(ed25519_pub) - 1;
+               alginfo = openssleddsa_alg_info(algorithm);
+               break;
+#endif
+       default:
+               DST_RET(ISC_R_NOTIMPLEMENTED);
+       }
+
+       ret = raw_key_to_ossl(alginfo, 0, key, &key_len, &pkey);
+       if (ret != ISC_R_SUCCESS) {
+               goto err;
+       }
+
+       /*
+        * Check that we can verify the signature.
+        */
+       if (EVP_DigestVerifyInit(evp_md_ctx, NULL, NULL, NULL, pkey) != 1 ||
+           EVP_DigestVerify(evp_md_ctx, sig, sig_len, test,
+                            sizeof(test) - 1) != 1)
+       {
+               DST_RET(ISC_R_NOTIMPLEMENTED);
+       }
+
+err:
+       if (pkey != NULL) {
+               EVP_PKEY_free(pkey);
+       }
+       if (evp_md_ctx != NULL) {
+               EVP_MD_CTX_destroy(evp_md_ctx);
+       }
+       ERR_clear_error();
+       return (ret);
+}
+
 isc_result_t
-dst__openssleddsa_init(dst_func_t **funcp) {
+dst__openssleddsa_init(dst_func_t **funcp, unsigned char algorithm) {
        REQUIRE(funcp != NULL);
+
        if (*funcp == NULL) {
-               *funcp = &openssleddsa_functions;
+               if (check_algorithm(algorithm) == ISC_R_SUCCESS) {
+                       *funcp = &openssleddsa_functions;
+               }
        }
        return (ISC_R_SUCCESS);
 }
diff --git a/util/gen-eddsa-vectors.c b/util/gen-eddsa-vectors.c
new file mode 100644 (file)
index 0000000..12faa36
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#include <stdio.h>
+
+#include <openssl/core_names.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/opensslv.h>
+#include <openssl/param_build.h>
+
+/*
+ *  The test vectors were generated using OpenSSL 3.0 and
+ *  util/gen-eddsa-vectors.c.  Rerunning will generate a new set of
+ *  test vectors as the private key is not preserved.
+ *
+ *  e.g.
+ *          cc util/gen-eddsa-vectors.c -I /opt/local/include \
+ *                  -L /opt/local/lib -lcrypto
+ */
+
+int
+main() {
+       EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL);
+       EVP_PKEY *pkey = NULL;
+       unsigned char buf[512];
+       size_t bytes;
+       EVP_MD_CTX *evp_md_ctx = EVP_MD_CTX_create();
+
+       if (ctx == NULL || evp_md_ctx == NULL) {
+               return (1);
+       }
+
+       if (EVP_PKEY_keygen_init(ctx) != 1 ||
+           EVP_PKEY_keygen(ctx, &pkey) != 1 || pkey == NULL)
+       {
+               return (1);
+       }
+
+       bytes = sizeof(buf);
+       if (EVP_PKEY_get_raw_public_key(pkey, buf, &bytes) != 1) {
+               return (1);
+       }
+
+       printf("unsigned char ed25519_pub[] = \"");
+       for (size_t i = 0; i < bytes; i++) {
+               printf("\\x%02x", buf[i]);
+       }
+       printf("\";\n");
+
+       bytes = sizeof(buf);
+       if (EVP_DigestSignInit(evp_md_ctx, NULL, NULL, NULL, pkey) != 1 ||
+           EVP_DigestSign(evp_md_ctx, buf, &bytes,
+                          (const unsigned char *)"test", 4) != 1)
+       {
+               return (1);
+       }
+
+       printf("unsigned char ed25519_sig[] = \"");
+       for (size_t i = 0; i < bytes; i++) {
+               printf("\\x%02x", buf[i]);
+       }
+       printf("\";\n\n");
+
+       EVP_MD_CTX_free(evp_md_ctx);
+       EVP_PKEY_free(pkey);
+       pkey = NULL;
+
+       ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL);
+       evp_md_ctx = EVP_MD_CTX_create();
+       if (ctx == NULL || evp_md_ctx == NULL) {
+               return (1);
+       }
+
+       if (EVP_PKEY_keygen_init(ctx) != 1 ||
+           EVP_PKEY_keygen(ctx, &pkey) != 1 || pkey == NULL)
+       {
+               return (1);
+       }
+
+       bytes = sizeof(buf);
+       if (EVP_PKEY_get_raw_public_key(pkey, buf, &bytes) != 1) {
+               return (1);
+       }
+
+       printf("unsigned char ed448_pub[] = \"");
+       for (size_t i = 0; i < bytes; i++) {
+               printf("\\x%02x", buf[i]);
+       }
+       printf("\";\n");
+
+       bytes = sizeof(buf);
+       if (EVP_DigestSignInit(evp_md_ctx, NULL, NULL, NULL, pkey) != 1 ||
+           EVP_DigestSign(evp_md_ctx, buf, &bytes,
+                          (const unsigned char *)"test", 4) != 1)
+       {
+               return (1);
+       }
+
+       printf("unsigned char ed448_sig[] = \"");
+       for (size_t i = 0; i < bytes; i++) {
+               printf("\\x%02x", buf[i]);
+       }
+       printf("\";\n\n");
+
+       return (0);
+}