From: Aydın Mercan Date: Mon, 16 Dec 2024 12:31:15 +0000 (+0300) Subject: unify fips handling to isc_crypto and make the toggle one way X-Git-Tag: ondrej/lock-free-qpzone-reads-v1~17^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4ab4f07e366b70e69c43c2e1b03cf5dac4993e4;p=thirdparty%2Fbind9.git unify fips handling to isc_crypto and make the toggle one way 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. --- diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 1d63d143fd5..c489df86718 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -26,16 +26,12 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include -#include -#endif #include #include #include #include -#include +#include #include #include #include @@ -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; } diff --git a/bin/dig/dig.c b/bin/dig/dig.c index b7a1a24cd6e..23f5b57130d 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -20,8 +20,8 @@ #include #include +#include #include -#include #include #include #include @@ -73,14 +73,6 @@ static bool short_form = false, printcmd = true, plusquest = false, static uint32_t splitwidth = 0xffffffff; #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include -#include -#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; } diff --git a/bin/dnssec/Makefile.am b/bin/dnssec/Makefile.am index 0268fc196bd..bc4654e72b3 100644 --- a/bin/dnssec/Makefile.am +++ b/bin/dnssec/Makefile.am @@ -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) diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index e04f73bd11e..adc98f07be4 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -58,11 +58,6 @@ #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include -#include -#endif - #include "dnssectool.h" const char *program = "dnssec-keygen"; @@ -151,7 +146,7 @@ usage(void) { fprintf(stderr, " -l : configuration file with dnssec-policy " "statement\n"); fprintf(stderr, " -a :\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 :\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); } diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index 3260e3ff645..9954eebf377 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -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); diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index caf8f125d1d..06fd6b686ba 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -90,10 +89,6 @@ #include #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include -#include -#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) { diff --git a/bin/named/main.c b/bin/named/main.c index 81af56c1538..6b21a2d4209 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -91,10 +90,6 @@ #include #include #include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include -#include -#endif #ifdef HAVE_LIBXML2 #include #include @@ -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 */ diff --git a/bin/named/server.c b/bin/named/server.c index 236eadf6121..2ddc529bd44 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -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, diff --git a/bin/tests/system/feature-test.c b/bin/tests/system/feature-test.c index f39922dcbc1..8f58e133f11 100644 --- a/bin/tests/system/feature-test.c +++ b/bin/tests/system/feature-test.c @@ -23,7 +23,7 @@ #include #endif -#include +#include #include #include #include @@ -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 } diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 444eb8fbfd9..6446de1f6af 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -38,9 +38,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 74cab51ec2e..821a50289d4 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -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) { diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index 4359b517b7e..4978ab4ed10 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -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 \ diff --git a/lib/isc/crypto.c b/lib/isc/crypto.c index b3ab28c4c57..209f49e90c4 100644 --- a/lib/isc/crypto.c +++ b/lib/isc/crypto.c @@ -11,13 +11,17 @@ * information regarding copyright ownership. */ +#include #include #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + #include -#include #include #include #include @@ -25,6 +29,10 @@ 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 index 43454516bbb..00000000000 --- a/lib/isc/fips.c +++ /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 -#include - -#if defined(HAVE_EVP_DEFAULT_PROPERTIES_ENABLE_FIPS) -#include -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 - -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 diff --git a/lib/isc/include/isc/crypto.h b/lib/isc/include/isc/crypto.h index 9119205ce78..14bdd469331 100644 --- a/lib/isc/include/isc/crypto.h +++ b/lib/isc/include/isc/crypto.h @@ -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 index 087197b8d30..00000000000 --- a/lib/isc/include/isc/fips.h +++ /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 - -/*** - *** 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. - */ diff --git a/lib/isc/tls.c b/lib/isc/tls.c index b98c7721eda..0a646837bbd 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 9ab717a66f0..a258f06d248 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include @@ -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; diff --git a/tests/dns/dst_test.c b/tests/dns/dst_test.c index 10bb24bc9b8..46d46a5c02b 100644 --- a/tests/dns/dst_test.c +++ b/tests/dns/dst_test.c @@ -30,8 +30,8 @@ #define UNIT_TESTING #include +#include #include -#include #include #include #include @@ -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); diff --git a/tests/isc/hmac_test.c b/tests/isc/hmac_test.c index 75c604b50d6..67483c9d4ea 100644 --- a/tests/isc/hmac_test.c +++ b/tests/isc/hmac_test.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include #include @@ -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; } diff --git a/tests/isc/md_test.c b/tests/isc/md_test.c index 4ef72383df0..e8cdeeb4ae5 100644 --- a/tests/isc/md_test.c +++ b/tests/isc/md_test.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -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; }