diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 1d63d143fd..c489df8671 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 b7a1a24cd6..23f5b57130 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 0268fc196b..bc4654e72b 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 e04f73bd11..adc98f07be 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 3260e3ff64..9954eebf37 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 caf8f125d1..06fd6b686b 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 81af56c153..6b21a2d420 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 236eadf612..2ddc529bd4 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 f39922dcbc..8f58e133f1 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 444eb8fbfd..6446de1f6a 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 74cab51ec2..821a50289d 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 4359b517b7..4978ab4ed1 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 b3ab28c4c5..209f49e90c 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 43454516bb..0000000000 --- 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 9119205ce7..14bdd46933 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 087197b8d3..0000000000 --- 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 b98c7721ed..0a646837bb 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 9ab717a66f..a258f06d24 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 10bb24bc9b..46d46a5c02 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 75c604b50d..67483c9d4e 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 4ef72383df..e8cdeeb4ae 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; }