]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
unify fips handling to isc_crypto and make the toggle one way
authorAydın Mercan <aydin@isc.org>
Mon, 16 Dec 2024 12:31:15 +0000 (15:31 +0300)
committerAydın Mercan <aydin@isc.org>
Thu, 27 Feb 2025 14:37:43 +0000 (17:37 +0300)
Since algorithm fetching is handled purely in libisc, FIPS mode toggling
can be purely done in within the library instead of provider fetching in
the binary for OpenSSL >=3.0.

Disabling FIPS mode isn't a realistic requirement and isn't done
anywhere in the codebase. Make the FIPS mode toggle enable-only to
reflect the situation.

21 files changed:
bin/delv/delv.c
bin/dig/dig.c
bin/dnssec/Makefile.am
bin/dnssec/dnssec-keygen.c
bin/dnssec/dnssec-ksr.c
bin/dnssec/dnssec-signzone.c
bin/named/main.c
bin/named/server.c
bin/tests/system/feature-test.c
lib/dns/dst_api.c
lib/dns/opensslecdsa_link.c
lib/isc/Makefile.am
lib/isc/crypto.c
lib/isc/fips.c [deleted file]
lib/isc/include/isc/crypto.h
lib/isc/include/isc/fips.h [deleted file]
lib/isc/tls.c
lib/isccfg/kaspconf.c
tests/dns/dst_test.c
tests/isc/hmac_test.c
tests/isc/md_test.c

index 1d63d143fd533e92426794f4e5c569291cbe29a2..c489df8671822a27984eb1da7f46c34f5a5b0f97 100644 (file)
 #include <unistd.h>
 
 #include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/err.h>
-#include <openssl/provider.h>
-#endif
 
 #include <isc/async.h>
 #include <isc/attributes.h>
 #include <isc/base64.h>
 #include <isc/buffer.h>
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/hex.h>
 #include <isc/lib.h>
 #include <isc/log.h>
@@ -167,10 +163,6 @@ static dns_fixedname_t qfn;
 /* Default trust anchors */
 static char anchortext[] = TRUST_ANCHORS;
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-static OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
-
 /*
  * Static function prototypes
  */
@@ -1619,24 +1611,7 @@ preparse_args(int argc, char **argv) {
                while (strpbrk(option, single_dash_opts) == &option[0]) {
                        switch (option[0]) {
                        case 'F':
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-                               fips = OSSL_PROVIDER_load(NULL, "fips");
-                               if (fips == NULL) {
-                                       ERR_clear_error();
-                                       fatal("Failed to load FIPS provider");
-                               }
-                               base = OSSL_PROVIDER_load(NULL, "base");
-                               if (base == NULL) {
-                                       OSSL_PROVIDER_unload(fips);
-                                       ERR_clear_error();
-                                       fatal("Failed to load base provider");
-                               }
-#endif
-                               /* Already in FIPS mode?  */
-                               if (isc_fips_mode()) {
-                                       break;
-                               }
-                               if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
+                               if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
                                        fatal("setting FIPS mode failed");
                                }
                                break;
@@ -2309,14 +2284,5 @@ cleanup:
 
        isc_managers_destroy(&mctx, &loopmgr, &netmgr);
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (base != NULL) {
-               OSSL_PROVIDER_unload(base);
-       }
-       if (fips != NULL) {
-               OSSL_PROVIDER_unload(fips);
-       }
-#endif
-
        return 0;
 }
index b7a1a24cd6ea367edbe5d7ef295562c60830d0df..23f5b57130db7303d0b176a48efc5c95bbbe3baf 100644 (file)
@@ -20,8 +20,8 @@
 #include <time.h>
 
 #include <isc/attributes.h>
+#include <isc/crypto.h>
 #include <isc/dir.h>
-#include <isc/fips.h>
 #include <isc/lib.h>
 #include <isc/loop.h>
 #include <isc/netaddr.h>
@@ -73,14 +73,6 @@ static bool short_form = false, printcmd = true, plusquest = false,
 static uint32_t splitwidth = 0xffffffff;
 
 #include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/err.h>
-#include <openssl/provider.h>
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-static OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
 
 /*% opcode text */
 static const char *const opcodetext[] = {
@@ -2931,24 +2923,7 @@ preparse_args(int argc, char **argv) {
                                debugging = true;
                                break;
                        case 'F':
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-                               fips = OSSL_PROVIDER_load(NULL, "fips");
-                               if (fips == NULL) {
-                                       ERR_clear_error();
-                                       fatal("Failed to load FIPS provider");
-                               }
-                               base = OSSL_PROVIDER_load(NULL, "base");
-                               if (base == NULL) {
-                                       OSSL_PROVIDER_unload(fips);
-                                       ERR_clear_error();
-                                       fatal("Failed to load base provider");
-                               }
-#endif
-                               /* Already in FIPS mode?  */
-                               if (isc_fips_mode()) {
-                                       break;
-                               }
-                               if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
+                               if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
                                        fatal("setting FIPS mode failed");
                                }
                                break;
@@ -3476,14 +3451,5 @@ main(int argc, char **argv) {
        dig_startup();
        dig_shutdown();
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (base != NULL) {
-               OSSL_PROVIDER_unload(base);
-       }
-       if (fips != NULL) {
-               OSSL_PROVIDER_unload(fips);
-       }
-#endif
-
        return exitcode;
 }
index 0268fc196bd6cb1e40331c1ea2c5190f239ae104..bc4654e72b3b17c4a81ec350c5c66a1a7e321235 100644 (file)
@@ -41,6 +41,14 @@ dnssec_keygen_LDADD =                \
        $(LDADD)                \
        $(OPENSSL_LIBS)
 
+dnssec_ksr_CPPFLAGS=           \
+       $(AM_CPPFLAGS)          \
+       $(OPENSSL_CFLAGS)
+
+dnssec_ksr_LDADD =             \
+       $(LDADD)                \
+       $(OPENSSL_LIBS)
+
 dnssec_signzone_CPPFLAGS =     \
        $(AM_CPPFLAGS)          \
        $(OPENSSL_CFLAGS)
index e04f73bd11eb0aea501739eb881ebbf620015da1..adc98f07be41f4d8304116d28e963a316c8c531d 100644 (file)
@@ -38,7 +38,7 @@
 #include <isc/attributes.h>
 #include <isc/buffer.h>
 #include <isc/commandline.h>
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/lib.h>
 #include <isc/log.h>
 #include <isc/mem.h>
 
 #include <dst/dst.h>
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/err.h>
-#include <openssl/provider.h>
-#endif
-
 #include "dnssectool.h"
 
 const char *program = "dnssec-keygen";
@@ -151,7 +146,7 @@ usage(void) {
        fprintf(stderr, "    -l <file>: configuration file with dnssec-policy "
                        "statement\n");
        fprintf(stderr, "    -a <algorithm>:\n");
-       if (!isc_fips_mode()) {
+       if (!isc_crypto_fips_mode()) {
                fprintf(stderr, "        RSASHA1 | NSEC3RSASHA1 |\n");
        }
        fprintf(stderr, "        RSASHA256 | RSASHA512 |\n");
@@ -159,7 +154,7 @@ usage(void) {
        fprintf(stderr, "        ED25519 | ED448\n");
        fprintf(stderr, "    -3: use NSEC3-capable algorithm\n");
        fprintf(stderr, "    -b <key size in bits>:\n");
-       if (!isc_fips_mode()) {
+       if (!isc_crypto_fips_mode()) {
                fprintf(stderr, "        RSASHA1:\t[%d..%d]\n", min_rsa,
                        MAX_RSA);
                fprintf(stderr, "        NSEC3RSASHA1:\t[%d..%d]\n", min_rsa,
@@ -288,7 +283,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
                        fatal("unsupported algorithm: %s", algstr);
                }
 
-               if (isc_fips_mode()) {
+               if (isc_crypto_fips_mode()) {
                        /* verify only in FIPS mode */
                        switch (ctx->alg) {
                        case DST_ALG_RSASHA1:
@@ -341,7 +336,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
                        switch (ctx->alg) {
                        case DST_ALG_RSASHA1:
                        case DST_ALG_NSEC3RSASHA1:
-                               if (isc_fips_mode()) {
+                               if (isc_crypto_fips_mode()) {
                                        fatal("key size not specified (-b "
                                              "option)");
                                }
@@ -501,7 +496,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
        switch (ctx->alg) {
        case DNS_KEYALG_RSASHA1:
        case DNS_KEYALG_NSEC3RSASHA1:
-               if (isc_fips_mode()) {
+               if (isc_crypto_fips_mode()) {
                        fatal("SHA1 based keys not supported in FIPS mode");
                }
                FALLTHROUGH;
@@ -847,10 +842,6 @@ main(int argc, char **argv) {
        isc_textregion_t r;
        unsigned char c;
        int ch;
-       bool set_fips_mode = false;
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
 
        keygen_ctx_t ctx = {
                .options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC,
@@ -1109,7 +1100,9 @@ main(int argc, char **argv) {
                        ctx.prepub = strtottl(isc_commandline_argument);
                        break;
                case 'F':
-                       set_fips_mode = true;
+                       if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
+                               fatal("setting FIPS mode failed");
+                       }
                        break;
                case '?':
                        if (isc_commandline_option != '?') {
@@ -1136,32 +1129,11 @@ main(int argc, char **argv) {
                ctx.quiet = true;
        }
 
-       if (set_fips_mode) {
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-               fips = OSSL_PROVIDER_load(NULL, "fips");
-               if (fips == NULL) {
-                       ERR_clear_error();
-                       fatal("Failed to load FIPS provider");
-               }
-               base = OSSL_PROVIDER_load(NULL, "base");
-               if (base == NULL) {
-                       OSSL_PROVIDER_unload(fips);
-                       ERR_clear_error();
-                       fatal("Failed to load base provider");
-               }
-#endif
-               if (!isc_fips_mode()) {
-                       if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
-                               fatal("setting FIPS mode failed");
-                       }
-               }
-       }
-
        /*
         * The DST subsystem will set FIPS mode if requested at build time.
         * The minimum sizes are both raised to 2048.
         */
-       if (isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
                min_rsa = min_dh = 2048;
        }
 
@@ -1310,14 +1282,6 @@ main(int argc, char **argv) {
        }
        isc_mem_destroy(&mctx);
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (base != NULL) {
-               OSSL_PROVIDER_unload(base);
-       }
-       if (fips != NULL) {
-               OSSL_PROVIDER_unload(fips);
-       }
-#endif
        if (freeit != NULL) {
                free(freeit);
        }
index 3260e3ff645b99593235b9d26564dde1bdade97c..9954eebf377f063aaa5b7699922bd44a5e3f97c1 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <isc/buffer.h>
 #include <isc/commandline.h>
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/lex.h>
 #include <isc/lib.h>
 #include <isc/mem.h>
@@ -362,7 +362,7 @@ create_key(ksr_ctx_t *ksr, dns_kasp_t *kasp, dns_kasp_key_t *kaspkey,
        switch (ksr->alg) {
        case DST_ALG_RSASHA1:
        case DST_ALG_NSEC3RSASHA1:
-               if (isc_fips_mode()) {
+               if (isc_crypto_fips_mode()) {
                        /* verify-only in FIPS mode */
                        fatal("unsupported algorithm: %s", algstr);
                }
@@ -1348,10 +1348,6 @@ main(int argc, char *argv[]) {
        isc_buffer_t buf;
        int ch;
        char *endp;
-       bool set_fips_mode = false;
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
        ksr_ctx_t ksr = {
                .now = isc_stdtime_now(),
        };
@@ -1371,7 +1367,9 @@ main(int argc, char *argv[]) {
                                            ksr.now, &ksr.setend);
                        break;
                case 'F':
-                       set_fips_mode = true;
+                       if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
+                               fatal("setting FIPS mode failed");
+                       }
                        break;
                case 'f':
                        ksr.file = isc_commandline_argument;
@@ -1425,31 +1423,12 @@ main(int argc, char *argv[]) {
         * The DST subsystem will set FIPS mode if requested at build time.
         * The minimum sizes are both raised to 2048.
         */
-       if (isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
                min_rsa = min_dh = 2048;
        }
 
        setup_logging();
 
-       if (set_fips_mode) {
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-               fips = OSSL_PROVIDER_load(NULL, "fips");
-               if (fips == NULL) {
-                       fatal("Failed to load FIPS provider");
-               }
-               base = OSSL_PROVIDER_load(NULL, "base");
-               if (base == NULL) {
-                       OSSL_PROVIDER_unload(fips);
-                       fatal("Failed to load base provider");
-               }
-#endif
-               if (!isc_fips_mode()) {
-                       if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
-                               fatal("setting FIPS mode failed");
-                       }
-               }
-       }
-
        /* zone */
        namestr = argv[1];
        name = dns_fixedname_initname(&fname);
index caf8f125d1dfcf6ba57a786abc7a2d3ef5833214..06fd6b686babbe4ac34ad25377de74c0dff407b4 100644 (file)
@@ -42,7 +42,6 @@
 #include <isc/commandline.h>
 #include <isc/dir.h>
 #include <isc/file.h>
-#include <isc/fips.h>
 #include <isc/hash.h>
 #include <isc/hex.h>
 #include <isc/lib.h>
 #include <dns/zoneverify.h>
 
 #include <dst/dst.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/err.h>
-#include <openssl/provider.h>
-#endif
 
 #include "dnssectool.h"
 
@@ -3380,10 +3375,6 @@ main(int argc, char *argv[]) {
        bool set_optout = false;
        bool set_iter = false;
        bool nonsecify = false;
-       bool set_fips_mode = false;
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
 
        atomic_init(&shuttingdown, false);
        atomic_init(&finished, false);
@@ -3672,7 +3663,9 @@ main(int argc, char *argv[]) {
                        break;
 
                case 'F':
-                       set_fips_mode = true;
+                       if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
+                               fatal("setting FIPS mode failed");
+                       }
                        break;
 
                case '?':
@@ -3743,27 +3736,6 @@ main(int argc, char *argv[]) {
 
        isc_managers_create(&mctx, nloops, &loopmgr, &netmgr);
 
-       if (set_fips_mode) {
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-               fips = OSSL_PROVIDER_load(NULL, "fips");
-               if (fips == NULL) {
-                       ERR_clear_error();
-                       fatal("Failed to load FIPS provider");
-               }
-               base = OSSL_PROVIDER_load(NULL, "base");
-               if (base == NULL) {
-                       OSSL_PROVIDER_unload(fips);
-                       ERR_clear_error();
-                       fatal("Failed to load base provider");
-               }
-#endif
-               if (!isc_fips_mode()) {
-                       if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
-                               fatal("setting FIPS mode failed");
-                       }
-               }
-       }
-
        setup_logging();
 
        argc -= isc_commandline_index;
@@ -4135,15 +4107,6 @@ main(int argc, char *argv[]) {
                isc_mem_stats(mctx, stdout);
        }
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (base != NULL) {
-               OSSL_PROVIDER_unload(base);
-       }
-       if (fips != NULL) {
-               OSSL_PROVIDER_unload(fips);
-       }
-#endif
-
        isc_managers_destroy(&mctx, &loopmgr, &netmgr);
 
        if (printstats) {
index 81af56c15389271d3b99f70e1483a20cc37d4c1c..6b21a2d4209a2d75c5306988b7cfa241243d3f67 100644 (file)
@@ -30,7 +30,6 @@
 #include <isc/crypto.h>
 #include <isc/dir.h>
 #include <isc/file.h>
-#include <isc/fips.h>
 #include <isc/hash.h>
 #include <isc/httpd.h>
 #include <isc/lib.h>
 #include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/opensslv.h>
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-#include <openssl/err.h>
-#include <openssl/provider.h>
-#endif
 #ifdef HAVE_LIBXML2
 #include <libxml/parser.h>
 #include <libxml/xmlversion.h>
@@ -155,10 +150,6 @@ static bool transferstuck = false;
 static bool disable6 = false;
 static bool disable4 = false;
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-static OSSL_PROVIDER *fips = NULL, *base = NULL;
-#endif
-
 void
 named_main_earlywarning(const char *format, ...) {
        va_list args;
@@ -952,25 +943,7 @@ parse_command_line(int argc, char *argv[]) {
                        named_main_earlyfatal("option '-X' has been removed");
                        break;
                case 'F':
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-                       fips = OSSL_PROVIDER_load(NULL, "fips");
-                       if (fips == NULL) {
-                               ERR_clear_error();
-                               named_main_earlyfatal(
-                                       "Failed to load FIPS provider");
-                       }
-                       base = OSSL_PROVIDER_load(NULL, "base");
-                       if (base == NULL) {
-                               OSSL_PROVIDER_unload(fips);
-                               ERR_clear_error();
-                               named_main_earlyfatal(
-                                       "Failed to load base provider");
-                       }
-#endif
-                       if (isc_fips_mode()) { /* Already in FIPS mode. */
-                               break;
-                       }
-                       if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
+                       if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
                                named_main_earlyfatal(
                                        "setting FIPS mode failed");
                        }
@@ -1574,15 +1547,6 @@ main(int argc, char *argv[]) {
 
        named_os_shutdown();
 
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-       if (base != NULL) {
-               OSSL_PROVIDER_unload(base);
-       }
-       if (fips != NULL) {
-               OSSL_PROVIDER_unload(fips);
-       }
-#endif
-
 #ifdef HAVE_GPERFTOOLS_PROFILER
        ProfilerStop();
 #endif /* ifdef HAVE_GPERFTOOLS_PROFILER */
index 236eadf61214939970f5fa5b278b3ae28d7cc2f6..2ddc529bd442637f6642bac71a4b69db2e9c7ac9 100644 (file)
@@ -38,7 +38,6 @@
 #include <isc/commandline.h>
 #include <isc/dir.h>
 #include <isc/file.h>
-#include <isc/fips.h>
 #include <isc/hash.h>
 #include <isc/hex.h>
 #include <isc/hmac.h>
@@ -9377,7 +9376,7 @@ view_loaded(void *arg) {
 
                isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
                              ISC_LOG_NOTICE, "FIPS mode is %s",
-                             isc_fips_mode() ? "enabled" : "disabled");
+                             isc_crypto_fips_mode() ? "enabled" : "disabled");
 
 #if HAVE_LIBSYSTEMD
                sd_notifyf(0,
index f39922dcbc1c36b4d3aece6d8c6c2293484ff29e..8f58e133f11abfb0ff381b5f79dd984fc897445b 100644 (file)
@@ -23,7 +23,7 @@
 #include <openssl/provider.h>
 #endif
 
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/lib.h>
 #include <isc/md.h>
 #include <isc/mem.h>
@@ -134,7 +134,7 @@ main(int argc, char **argv) {
                return 1;
 #endif
 #else
-               if (isc_fips_mode()) {
+               if (isc_crypto_fips_mode()) {
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
                        return 0;
 #else
@@ -149,7 +149,7 @@ main(int argc, char **argv) {
 #if defined(ENABLE_FIPS_MODE)
                return 0;
 #else
-               return isc_fips_mode() ? 0 : 1;
+               return isc_crypto_fips_mode() ? 0 : 1;
 #endif
        }
 
index 444eb8fbfd9342b203e51de6b53dfa336ec1fa51..6446de1f6af0ac01f228ca5e5d23c64ef369876a 100644 (file)
@@ -38,9 +38,9 @@
 #include <unistd.h>
 
 #include <isc/buffer.h>
+#include <isc/crypto.h>
 #include <isc/dir.h>
 #include <isc/file.h>
-#include <isc/fips.h>
 #include <isc/lex.h>
 #include <isc/mem.h>
 #include <isc/once.h>
index 74cab51ec2e6f2f57fe8b931ee88d1852e5de732..821a50289d49bc434abe59b9594aa661fc06fa80 100644 (file)
@@ -26,7 +26,6 @@
 #include <openssl/param_build.h>
 #endif
 
-#include <isc/fips.h>
 #include <isc/mem.h>
 #include <isc/result.h>
 #include <isc/safe.h>
@@ -707,7 +706,7 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
                }
 
 #if OPENSSL_VERSION_NUMBER >= 0x30200000L
-               if (!isc_fips_mode()) {
+               if (!isc_crypto_fips_mode()) {
                        ret = opensslecdsa_set_deterministic(
                                pctx, dctx->key->key_alg);
                        if (ret != ISC_R_SUCCESS) {
index 4359b517b7ed437b688aac64b952109331928b1b..4978ab4ed100078dc08d3acf3683fefeb6eea5c4 100644 (file)
@@ -25,7 +25,6 @@ libisc_la_HEADERS =                   \
        include/isc/errno.h             \
        include/isc/error.h             \
        include/isc/file.h              \
-       include/isc/fips.h              \
        include/isc/formatcheck.h       \
        include/isc/fuzz.h              \
        include/isc/getaddresses.h      \
@@ -133,7 +132,6 @@ libisc_la_SOURCES =         \
        errno2result.h          \
        error.c                 \
        file.c                  \
-       fips.c                  \
        getaddresses.c          \
        hash.c                  \
        hashmap.c               \
index b3ab28c4c570fa46d940043a4aea8fdea2494c1b..209f49e90c4de83be8472323f2b27ccfbd7485b0 100644 (file)
  * information regarding copyright ownership.
  */
 
+#include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/ssl.h>
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/provider.h>
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
+
 #include <isc/crypto.h>
-#include <isc/fips.h>
 #include <isc/log.h>
 #include <isc/mem.h>
 #include <isc/tls.h>
 
 static isc_mem_t *isc__crypto_mctx = NULL;
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+static OSSL_PROVIDER *base = NULL, *fips = NULL;
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
+
 const EVP_MD *isc__crypto_md5 = NULL;
 const EVP_MD *isc__crypto_sha1 = NULL;
 const EVP_MD *isc__crypto_sha224 = NULL;
@@ -49,7 +57,6 @@ const EVP_MD *isc__crypto_sha512 = NULL;
                        isc__crypto_##alg = NULL;                \
                }                                                \
        }
-
 #else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
 #define md_register_algorithm(alg, algname)      \
        {                                        \
@@ -61,6 +68,34 @@ const EVP_MD *isc__crypto_sha512 = NULL;
 #define md_unregister_algorithm(alg)
 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
 
+static isc_result_t
+register_algorithms(void) {
+       if (!isc_crypto_fips_mode()) {
+               md_register_algorithm(md5, "MD5");
+       }
+
+       md_register_algorithm(sha1, "SHA1");
+       md_register_algorithm(sha224, "SHA224");
+       md_register_algorithm(sha256, "SHA256");
+       md_register_algorithm(sha384, "SHA384");
+       md_register_algorithm(sha512, "SHA512");
+
+       return ISC_R_SUCCESS;
+}
+
+static void
+unregister_algorithms(void) {
+       md_unregister_algorithm(sha512);
+       md_unregister_algorithm(sha384);
+       md_unregister_algorithm(sha256);
+       md_unregister_algorithm(sha224);
+       md_unregister_algorithm(sha1);
+       md_unregister_algorithm(md5);
+}
+
+#undef md_unregister_algorithm
+#undef md_register_algorithm
+
 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
 /*
  * This was crippled with LibreSSL, so just skip it:
@@ -132,6 +167,82 @@ isc__crypto_free_ex(void *ptr, const char *file, int line) {
 
 #endif /* !defined(LIBRESSL_VERSION_NUMBER) */
 
+#if defined(HAVE_EVP_DEFAULT_PROPERTIES_ENABLE_FIPS)
+bool
+isc_crypto_fips_mode(void) {
+       return EVP_default_properties_is_fips_enabled(NULL) != 0;
+}
+
+isc_result_t
+isc_crypto_fips_enable(void) {
+       if (isc_crypto_fips_mode()) {
+               return ISC_R_SUCCESS;
+       }
+
+       INSIST(fips == NULL);
+       fips = OSSL_PROVIDER_load(NULL, "fips");
+       if (fips == NULL) {
+               return isc_tlserr2result(
+                       ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
+                       "OSSL_PROVIDER_load", ISC_R_CRYPTOFAILURE);
+       }
+
+       INSIST(base == NULL);
+       base = OSSL_PROVIDER_load(NULL, "base");
+       if (base == NULL) {
+               OSSL_PROVIDER_unload(fips);
+               return isc_tlserr2result(
+                       ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
+                       "OSS_PROVIDER_load", ISC_R_CRYPTOFAILURE);
+       }
+
+       if (EVP_default_properties_enable_fips(NULL, 1) == 0) {
+               return isc_tlserr2result(ISC_LOGCATEGORY_GENERAL,
+                                        ISC_LOGMODULE_CRYPTO,
+                                        "EVP_default_properties_enable_fips",
+                                        ISC_R_CRYPTOFAILURE);
+       }
+
+       unregister_algorithms();
+       register_algorithms();
+
+       return ISC_R_SUCCESS;
+}
+#elif defined(HAVE_FIPS_MODE)
+bool
+isc_crypto_fips_mode(void) {
+       return FIPS_mode() != 0;
+}
+
+isc_result_t
+isc_crypto_fips_enable(void) {
+       if (isc_crypto_fips_mode()) {
+               return ISC_R_SUCCESS;
+       }
+
+       if (FIPS_mode_set(1) == 0) {
+               return isc_tlserr2result(ISC_LOGCATEGORY_GENERAL,
+                                        ISC_LOGMODULE_CRYPTO, "FIPS_mode_set",
+                                        ISC_R_CRYPTOFAILURE);
+       }
+
+       unregister_algorithms();
+       register_algorithms();
+
+       return ISC_R_SUCCESS;
+}
+#else
+bool
+isc_crypto_fips_mode(void) {
+       return false;
+}
+
+isc_result_t
+isc_crypto_fips_enable(void) {
+       return ISC_R_NOTIMPLEMENTED;
+}
+#endif
+
 void
 isc__crypto_setdestroycheck(bool check) {
        isc_mem_setdestroycheck(isc__crypto_mctx, check);
@@ -167,6 +278,16 @@ isc__crypto_initialize(void) {
 
        RUNTIME_CHECK(OPENSSL_init_ssl(opts, NULL) == 1);
 
+       register_algorithms();
+
+#if defined(ENABLE_FIPS_MODE)
+       if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
+               ERR_clear_error();
+               FATAL_ERROR("Failed to toggle FIPS mode but is "
+                           "required for this build");
+       }
+#endif
+
        /* Protect ourselves against unseeded PRNG */
        if (RAND_status() != 1) {
                isc_tlserr2result(ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_CRYPTO,
@@ -175,39 +296,23 @@ isc__crypto_initialize(void) {
                            "cannot be initialized (see the `PRNG not "
                            "seeded' message in the OpenSSL FAQ)");
        }
-
-#if defined(ENABLE_FIPS_MODE)
-       if (!isc_fips_mode()) {
-               if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
-                       isc_tlserr2result(ISC_LOGCATEGORY_GENERAL,
-                                         ISC_LOGMODULE_CRYPTO, "FIPS_mode_set",
-                                         ISC_R_CRYPTOFAILURE);
-                       exit(EXIT_FAILURE);
-               }
-       }
-#endif
-
-       md_register_algorithm(md5, "MD5");
-       md_register_algorithm(sha1, "SHA1");
-       md_register_algorithm(sha224, "SHA224");
-       md_register_algorithm(sha256, "SHA256");
-       md_register_algorithm(sha384, "SHA384");
-       md_register_algorithm(sha512, "SHA512");
 }
 
 void
 isc__crypto_shutdown(void) {
-       md_unregister_algorithm(sha512);
-       md_unregister_algorithm(sha384);
-       md_unregister_algorithm(sha256);
-       md_unregister_algorithm(sha224);
-       md_unregister_algorithm(sha1);
-       md_unregister_algorithm(md5);
+       unregister_algorithms();
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+       if (base != NULL) {
+               OSSL_PROVIDER_unload(base);
+       }
+
+       if (fips != NULL) {
+               OSSL_PROVIDER_unload(fips);
+       }
+#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
 
        OPENSSL_cleanup();
 
        isc_mem_destroy(&isc__crypto_mctx);
 }
-
-#undef md_unregister_algorithm
-#undef md_register_algorithm
diff --git a/lib/isc/fips.c b/lib/isc/fips.c
deleted file mode 100644 (file)
index 4345451..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-/*! \file */
-
-#include <isc/fips.h>
-#include <isc/util.h>
-
-#if defined(HAVE_EVP_DEFAULT_PROPERTIES_ENABLE_FIPS)
-#include <openssl/evp.h>
-bool
-isc_fips_mode(void) {
-       return EVP_default_properties_is_fips_enabled(NULL) != 0;
-}
-
-isc_result_t
-isc_fips_set_mode(int mode) {
-       return EVP_default_properties_enable_fips(NULL, mode) != 0
-                      ? ISC_R_SUCCESS
-                      : ISC_R_FAILURE;
-}
-#elif defined(HAVE_FIPS_MODE)
-#include <openssl/crypto.h>
-
-bool
-isc_fips_mode(void) {
-       return FIPS_mode() != 0;
-}
-
-isc_result_t
-isc_fips_set_mode(int mode) {
-       return FIPS_mode_set(mode) != 0 ? ISC_R_SUCCESS : ISC_R_FAILURE;
-}
-#else
-bool
-isc_fips_mode(void) {
-       return false;
-}
-
-isc_result_t
-isc_fips_set_mode(int mode) {
-       UNUSED(mode);
-       return ISC_R_NOTIMPLEMENTED;
-}
-#endif
index 9119205ce78e44e9634db9478cde5da5a188c11a..14bdd4693318cdbaeaf0decfbc574ce3fa624e41 100644 (file)
@@ -24,6 +24,20 @@ extern const EVP_MD *isc__crypto_sha256;
 extern const EVP_MD *isc__crypto_sha384;
 extern const EVP_MD *isc__crypto_sha512;
 
+bool
+isc_crypto_fips_mode(void);
+/*
+ * Return if FIPS mode is currently enabled or not.
+ */
+
+isc_result_t
+isc_crypto_fips_enable(void);
+/*
+ * Enable FIPS mode. It cannot be disabled afterwards.
+ *
+ * This function is NOT thread safe.
+ */
+
 /**
  * Private
  */
diff --git a/lib/isc/include/isc/fips.h b/lib/isc/include/isc/fips.h
deleted file mode 100644 (file)
index 087197b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-/*****
-***** Module Info
-*****/
-
-/***
- *** Imports
- ***/
-
-#include <isc/types.h>
-
-/***
- *** Functions
- ***/
-
-bool
-isc_fips_mode(void);
-/*
- * Return if FIPS mode is currently enabled or not
- */
-
-isc_result_t
-isc_fips_set_mode(int mode);
-/*
- * Enable FIPS mode.
- */
index b98c7721eda586cc53dee4949e8390cb14bd7657..0a646837bbd12e3f3ed33ed6b67a68383707ebee 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <isc/atomic.h>
 #include <isc/crypto.h>
-#include <isc/fips.h>
 #include <isc/ht.h>
 #include <isc/log.h>
 #include <isc/magic.h>
index 9ab717a66f0c78d110bbd54c70b6fa393da616af..a258f06d248d78236995d8daafc42c396c39a39d 100644 (file)
@@ -15,7 +15,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/log.h>
 #include <isc/mem.h>
 #include <isc/region.h>
@@ -227,7 +227,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
                        goto cleanup;
                }
 
-               if (check_algorithms && isc_fips_mode() &&
+               if (check_algorithms && isc_crypto_fips_mode() &&
                    (key->algorithm == DNS_KEYALG_RSASHA1 ||
                     key->algorithm == DNS_KEYALG_NSEC3RSASHA1))
                {
@@ -259,7 +259,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
                        case DNS_KEYALG_NSEC3RSASHA1:
                        case DNS_KEYALG_RSASHA256:
                        case DNS_KEYALG_RSASHA512:
-                               if (isc_fips_mode()) {
+                               if (isc_crypto_fips_mode()) {
                                        min = 2048;
                                } else {
                                        min = DNS_KEYALG_RSASHA512 ? 1024 : 512;
index 10bb24bc9b8ac3e0c74b7c85ddb13544846227c8..46d46a5c02be0013cce61fff152d3d95ad87b393 100644 (file)
@@ -30,8 +30,8 @@
 #define UNIT_TESTING
 #include <cmocka.h>
 
+#include <isc/crypto.h>
 #include <isc/file.h>
-#include <isc/fips.h>
 #include <isc/hex.h>
 #include <isc/lib.h>
 #include <isc/result.h>
@@ -471,7 +471,7 @@ ISC_RUN_TEST_IMPL(ecdsa_determinism_test) {
        dst_context_destroy(&ctx);
 
 #if OPENSSL_VERSION_NUMBER >= 0x30200000L
-       if (isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
                assert_memory_not_equal(sigbuf1->base, sigbuf2->base, siglen);
        } else {
                assert_memory_equal(sigbuf1->base, sigbuf2->base, siglen);
index 75c604b50d65c2fdf541d9e8b2e4ef24fc97a0b7..67483c9d4eada93ec7d408011c7797d5a82a36fb 100644 (file)
@@ -32,7 +32,7 @@
 #include <cmocka.h>
 
 #include <isc/buffer.h>
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/hex.h>
 #include <isc/hmac.h>
 #include <isc/lib.h>
@@ -134,7 +134,7 @@ ISC_RUN_TEST_IMPL(isc_hmac_init) {
        assert_int_equal(isc_hmac_init(hmac_st, "", 0, NULL),
                         ISC_R_NOTIMPLEMENTED);
 
-       if (!isc_fips_mode()) {
+       if (!isc_crypto_fips_mode()) {
                expect_assert_failure(isc_hmac_init(NULL, "", 0, ISC_MD_MD5));
 
                expect_assert_failure(
@@ -229,7 +229,7 @@ ISC_RUN_TEST_IMPL(isc_hmac_final) {
 ISC_RUN_TEST_IMPL(isc_hmac_md5) {
        isc_hmac_t *hmac_st = *state;
 
-       if (isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
                skip();
                return;
        }
index 4ef72383df0d26204cb7d9972f1af48d37702cd1..e8cdeeb4ae52980775c38fae2feb928de058c77f 100644 (file)
@@ -25,7 +25,7 @@
 #include <cmocka.h>
 
 #include <isc/buffer.h>
-#include <isc/fips.h>
+#include <isc/crypto.h>
 #include <isc/hex.h>
 #include <isc/lib.h>
 #include <isc/md.h>
@@ -120,7 +120,10 @@ ISC_RUN_TEST_IMPL(isc_md_init) {
 
        assert_int_equal(isc_md_init(md, NULL), ISC_R_NOTIMPLEMENTED);
 
-       if (!isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
+               assert_int_equal(isc_md_init(md, ISC_MD_MD5),
+                                ISC_R_NOTIMPLEMENTED);
+       } else {
                assert_int_equal(isc_md_init(md, ISC_MD_MD5), ISC_R_SUCCESS);
                assert_int_equal(isc_md_reset(md), ISC_R_SUCCESS);
        }
@@ -199,7 +202,7 @@ ISC_RUN_TEST_IMPL(isc_md_final) {
 ISC_RUN_TEST_IMPL(isc_md_md5) {
        isc_md_t *md = *state;
 
-       if (isc_fips_mode()) {
+       if (isc_crypto_fips_mode()) {
                skip();
                return;
        }