Thanks Matt. I actually had this working (loading the fips_libctx using the *load_config() API) but I was hitting other issues and thought I was doing something wrong (more on that later).
So to review, I have my own config file, /usr/local/ssl/openssl-fips, with the relevant contents(some comments snipped): .include /usr/local/ssl/fipsmodule.cnf [openssl_init] providers = provider_sect # List of providers to load [provider_sect] default = default_sect # The fips section name should match the section name inside the # included fipsmodule.cnf. fips = fips_sect base = base_sect [default_sect] # activate = 1 [base_sect] activate = 1 And then fipsmodule.cnf contains: [fips_sect] activate = 1 conditional-errors = 1 security-checks = 1 module-mac = E4:0D:C8:C3:1E:DB:2B:30:E6:F2:49:7B:F5:BD:10:5C:9A:2B:CC:C1:33:49:31:B5:C5:AF:50:AB:82:1E:AE:C9 By activating the fips and base providers via config, my application then calls: OSSL_LIB_CTX_load_config(fips_libctx, "/usr/local/ssl/openssl-fips.cnf"); Which loads the "fips" and "base" providers in the fips_libctx, which I verify with: OSSL_PROVIDER_available(fips_libctx, "fips"); and OSSL_PROVIDER_available(fips_libctx, "base") ...and both are available. However, remember I am trying to create two non-default library contexts (from earlier code): fips_libctx = OSSL_LIB_CTX_new(); non_fips_libctx = OSSL_LIB_CTX_new(); Again, I think I have what I need for the fibs_libctx. For the non_fips_libctx, I'm calling: defp = OSSL_PROVIDER_load(non_fips_libctx, "default"); nullp = OSSL_PROVIDER_load(NULL, "null"); A call to OSSL_PROVIDER_available() says the "default" provider is available; however, I'm wondering if I should be loading the default provider via *load_config() as well? I would have to uncomment the "activate = 1" in the default section of my config though. I also still have this in my code: /* Disallow falling back to the default library context */ nullp = OSSL_PROVIDER_load(NULL, "null"); But not sure it's having any affect? I do know that later in my application, both in "FIPS" or "non-FIPS" mode, I can create an SSL_CTX with SSL_CTX_new_ex(). I also successfully call several APIs using both the fips_libctx or the non_fips_libctx, for example: status = SSL_CTX_use_PrivateKey_file(ctx,<file>,SSL_FILETYPE_PEM); status = SSL_CTX_use_certificate_file(ctx,<file>,SSL_FILETYPE_PEM); status = SSL_CTX_check_private_key(ctx); All return successfully. So I think what I have between configuration files and API calls accomplishes what I need to. Would anyone reading this agree? I'm running into another issue that I need to troubleshoot a bit more before I add too much information and too many questions to a single message. Thanks to everyone for their help with this, things are starting to make more sense now. ________________________________ From: Matt Caswell <m...@openssl.org> Sent: Thursday, October 28, 2021 7:39 AM To: Jason Schultz <jetso...@hotmail.com>; Dr Paul Dale <pa...@openssl.org>; openssl-users@openssl.org <openssl-users@openssl.org> Subject: Re: OpenSSL 3.0 FIPS questions On 27/10/2021 17:28, Jason Schultz wrote: > With these config files and the code above, the > OSSL_PROVIDER_load(fips_libctx, "fips") call fails. Here are the > messages from the ERR_print_errors_fp() call: > > 2097C692B57F0000:error:1C8000D5:Provider routines:(unknown > function):missing config data:providers/fips/self_test.c:289: > 2097C692B57F0000:error:1C8000E0:Provider routines:(unknown > function):fips module entering error state:providers/fips/self_test.c:387: > 2097C692B57F0000:error:1C8000D8:Provider routines:(unknown > function):self test post failure:providers/fips/fipsprov.c:706: > 2097C692B57F0000:error:078C0105:common libcrypto routines:(unknown > function):init fail:crypto/provider_core.c:903:name=fips This tells us that the fips provider has successfully loaded, but then subsequently failed during its self-test because it cannot find its config data. I can see that you have created a separate libctx for fips. However automatic loading of the config file only works for the *default* libctx. If you create your own one then you need to explicitly load the config file: if (!OSSL_LIB_CTX_load_config(fips_libtx, "/usr/local/ssl/openssl.cnf")) { /* error handling */ } Actually if you do this then you should not need to call OSSL_PROVIDER_load() explicitly to load the fips provider since you already activated it in the config file. You can either drop the explicit call to OSSL_PROVIDER_load() for the fips provider, or remove the "activate = 1" line in "fips_sect" in fipsmodule.cnf. This is just a minor optimisation though. Doing both is redundant but harmless. You could also load the base provider via config if you wanted to. Matt