openssl: Fips self test is being triggered multiple times..

The fipsprov.c entry point OSSL_provider_init calls SELF_TEST_post() which then does a EVP_fetch (it will do more once the KATS are added) … As the provider has not yet activated the fetch causes some fallback setup to be called which then calls OSSL_provider_init() a second time…

The dummy_evp_call() will be suffering from the same issues…

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 46 (46 by maintainers)

Commits related to this issue

Most upvoted comments

Possibly we can go for the “.ini”/“.fini” solution but fallback to the run-the-tests-on-every-load solution for any platforms where this is not possible (or just using an unknown compiler where we don’t know how to do it).

IMO, the solution to this issue is as follows:

  • We fix config params so that you can associate a config file with an explicit OPENSSL_CTX. Possibly this could be done on construction of the OPENSSL_CTX itself, e.g.

OPENSSL_CTX *ctx = OPENSSL_CTX_new(“/path/to/default/config/file”);

Or possibly as some additional calls after the OPENSSL_CTX has been constructed.

  • We implement a “.ini” section and a “.fini” in the fips provider
  1. the “.ini” creates a self-test lock and initialises a status flag to “self-test not run”
  2. On a call to OSSL_init_provider inside the FIPS module we acquire the lock and check the status flag. If the status flag is “self-test not run” then we run the self tests, update the status flag and release the lock. If the status flag is “self-tests failed” then we release the lock and fail the call to OSSL_init_provider. If the status flag is “self-tests succeeded” then we release the lock and continue.
  3. In the “.fini” section we free the lock

The above solution assumes all interesting platforms can support .ini and .fini sections. Is this the case? Possible alternatives could be:

  1. Use a RUN_ONCE function to run the self-tests, This might work, but has some issues:
  • You can’t allocate any resources inside the RUN_ONCE (e.g. locks etc) that are shared between multiple OPENSSL_CTXs because you have no way of releasing them (without using a “.fini” section).
  • It’s difficult to pass parameters (e.g. the config file parameters) to the RUN_ONCE function in a thread-safe way
  1. Always run the self-tests every time the provider is loaded. This would probably work well if an application has a small number of long running OPENSSL_CTX objects - but not so well if it is frequently loading/unloading the FIPS module or has many concurrent OPENSSL_CTXs.

Considering that the fips module needs a config currently in order to work this sounds like a problem to me 😃.

The config file is not the problem. If you only use the default context then the FIPS Provider will only be loaded once. The problem is loading a default context and an explicit context. That loads the provider twice - once for each context. That is exactly the intended behaviour. The issue we have to resolve is ensuring that that the self test only happens once per physical DSO load (as opposed to provider load). A DSO gets loaded into memory once - but the provider inside it can be loaded multiple times (depending on how many contexts you are using).