scram-sha-256 authentication broken in FIPS mode
It looks like scram-sha-256 doesn't work when postgres is linked against FIPS-enabled OpenSSL and FIPS mode is turned on. Specifically, all login attempts fail with an OpenSSL error saying something along the lines of "Low level API call to digest SHA256 forbidden in fips mode". I think this issue could be solved by refactoring the code in sha2_openssl.c to use the OpenSSL EVP interface (see https://wiki.openssl.org/index.php/EVP_Message_Digests ). Any thoughts? Is this a known issue? Thank you in advance.Alessandro
Re: scram-sha-256 authentication broken in FIPS mode
Hi Michael,I'm actually running postgres on Windows. I added code to fe-secure-openssl.c and be-secure-openssl.c that reads the Windows "standard" FIPS registry entry, and if FIPS is enabled calls FIPS_mode_set(1). This is to mimic to behavior of the .NET framework. Below is the code I added to fe-secure-openssl.c, the code in be-secure-openssl.c is similar: Thoughts? I can try to fix the scram-sha-256 issue by using EVP and send you a merge request for the patch and the code below if you think my approach is correct. Thanks,Alessandro intpgtls_init(PGconn *conn){... if (!ssl_lib_initialized) { if (pq_init_ssl_lib) { #ifdef WIN32 HKEY rootKey; DWORD fipsEnabled = 0; DWORD fipsEnabledSize = sizeof(DWORD); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Lsa\\FipsAlgorithmPolicy", 0, KEY_READ, &rootKey) != ERROR_SUCCESS) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not open FIPS registry key")); return -1; } if (RegQueryValueEx(rootKey, "Enabled", 0, 0, (LPBYTE) &fipsEnabled, &fipsEnabledSize) != ERROR_SUCCESS) { RegCloseKey(rootKey); printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not read FIPS registry entry")); return -1; } RegCloseKey(rootKey); if (fipsEnabled == 1 && FIPS_mode() == 0) { if (FIPS_mode_set(1) != 1) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not enable FIPS mode")); return -1; } }#endif #ifdef HAVE_OPENSSL_INIT_SSL OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);#else OPENSSL_config(NULL); SSL_library_init(); SSL_load_error_strings();#endif On Tuesday, September 4, 2018, 10:27:22 PM MDT, Michael Paquier wrote: On Wed, Sep 05, 2018 at 03:29:31AM +, Alessandro Gherardi wrote: > It looks like scram-sha-256 doesn't work when postgres is linked > against FIPS-enabled OpenSSL and FIPS mode is turned on. > > Specifically, all login attempts fail with an OpenSSL error saying > something along the lines of "Low level API call to digest SHA256 > forbidden in fips mode". The error comes from libc, right? Postgres can of course be configured to work with FIPS without patching it, it just needs to be enabled system-wide, which is what RedHat does, and what you are doing I guess? > I think this issue could be solved by refactoring the code in > sha2_openssl.c to use the OpenSSL EVP interface > (see https://wiki.openssl.org/index.php/EVP_Message_Digests ). > Any thoughts? Is this a known issue? This report is the first of this kind since Postgres 10, which is where the SHA2 interface for OpenSSL has been introduced. So likely we'd need to look into that more deeply.. This has the strong smell of a bug. If your system is new enough, you should have sha256() & co as system functions, so you would see the failure as well? The regression tests would have likely complained. -- Michael
Re: scram-sha-256 authentication broken in FIPS mode
Hi Michael, I'm attaching the output of diff . > If we could prove that sha2-openssl.c is actually unreliable even if FIPS is enabled system-wide with either SCRAM authentication or any of the other hashing functions, then I would be ready to accept a patch. Now, as far as I can see and heard from other folks for at least Linux, if FIPS is enabled at the OS level, then Postgres would use it automatically and SCRAM is able to work. Not sure why it works on Linux but not on Windows. That the low-level digest APIs can't be used when FIPS is enabled is by design, other people have encountered that problem, e.g., http://openssl.6102.n7.nabble.com/Low-Level-Digest-if-Fips-mode-td54983.html . Thanks,Alessandro be-secure-openssl.c.diff Description: Binary data fe-secure-openssl.c.diff Description: Binary data sha2.h.diff Description: Binary data sha2_openssl.c.diff Description: Binary data
Re: scram-sha-256 authentication broken in FIPS mode
I changed the implementation of the other SHA digests to use EVP also. I verified that, with these changes, scram-sha-256 works when FIPS is enabled. sha2.h.diff Description: Binary data sha2_openssl.c.diff Description: Binary data
Re: scram-sha-256 authentication broken in FIPS mode
Here's a patch for enabling FIPS in OpenSSL - by calling FIPS_mode_set(1) - on Windows if the FIPS registry entry HKLM\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\Enabled is set to 1. That's the entry that the .NET crypto libraries look at to decide whether or not to operate in FIPS mode. I thought of submitting a pull request for adding this logic to OpenSSL, however (1) https://www.openssl.org/source/ says they are working on a new FIPS module, so I doubt they would take a pull request for OpenSSL 1.0.X and (2) For Linux, this logic doesn't exist on the standard OpenSSL distribution but only on the RHEL-specific OpenSSL patch (See method init_fips_mode() in https://git.centos.org/raw/rpms/openssl.git/c7/SOURCES!openssl-1.0.2i-fips.patch ). Therefore, I believe the best option, at least for now, is calling FIPS_mode_set(1) in the application. 0001-On-Windows-call-FIPS_mode_set-1-if-FIPS-registry-ent.patch Description: Binary data