Skip to content

Commit e3dfb9b

Browse files
vstinnerencukou
andauthored
bpo-9216: Expose OpenSSL FIPS_mode() as _hashlib.get_fips_mode() (GH-19703)
test.pythoninfo logs OpenSSL FIPS_mode() and Linux /proc/sys/crypto/fips_enabled in a new "fips" section. Co-Authored-By: Petr Viktorin <[email protected]>
1 parent e5963ee commit e3dfb9b

File tree

4 files changed

+110
-1
lines changed

4 files changed

+110
-1
lines changed

Lib/test/pythoninfo.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,25 @@ def collect_windows(info_add):
720720
pass
721721

722722

723+
def collect_fips(info_add):
724+
try:
725+
import _hashlib
726+
except ImportError:
727+
_hashlib = None
728+
729+
if _hashlib is not None:
730+
call_func(info_add, 'fips.openssl_fips_mode', _hashlib, 'get_fips_mode')
731+
732+
try:
733+
with open("/proc/sys/crypto/fips_enabled", encoding="utf-8") as fp:
734+
line = fp.readline().rstrip()
735+
736+
if line:
737+
info_add('fips.linux_crypto_fips_enabled', line)
738+
except OSError:
739+
pass
740+
741+
723742
def collect_info(info):
724743
error = False
725744
info_add = info.add
@@ -735,6 +754,7 @@ def collect_info(info):
735754
collect_datetime,
736755
collect_decimal,
737756
collect_expat,
757+
collect_fips,
738758
collect_gdb,
739759
collect_gdbm,
740760
collect_get_config,

Lib/test/test_hashlib.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,11 @@ def hash_in_chunks(chunk_size):
856856

857857
self.assertEqual(expected_hash, hasher.hexdigest())
858858

859+
@unittest.skipUnless(hasattr(c_hashlib, 'get_fips_mode'),
860+
'need _hashlib.get_fips_mode')
861+
def test_get_fips_mode(self):
862+
self.assertIsInstance(c_hashlib.get_fips_mode(), int)
863+
859864

860865
class KDFTests(unittest.TestCase):
861866

Modules/_hashopenssl.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <openssl/objects.h>
2626
#include "openssl/err.h"
2727

28+
#include <openssl/crypto.h> // FIPS_mode()
29+
2830
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
2931
/* OpenSSL < 1.1.0 */
3032
#define EVP_MD_CTX_new EVP_MD_CTX_create
@@ -1096,12 +1098,53 @@ generate_hash_name_list(void)
10961098
return state.set;
10971099
}
10981100

1101+
/* LibreSSL doesn't support FIPS:
1102+
https://marc.info/?l=openbsd-misc&m=139819485423701&w=2
1103+
1104+
Ted Unangst wrote: "I figured I should mention our current libressl policy
1105+
wrt FIPS mode. It's gone and it's not coming back." */
1106+
#ifndef LIBRESSL_VERSION_NUMBER
1107+
/*[clinic input]
1108+
_hashlib.get_fips_mode -> int
1109+
1110+
Determine the OpenSSL FIPS mode of operation.
1111+
1112+
Effectively any non-zero return value indicates FIPS mode;
1113+
values other than 1 may have additional significance.
1114+
1115+
See OpenSSL documentation for the FIPS_mode() function for details.
1116+
[clinic start generated code]*/
1117+
1118+
static int
1119+
_hashlib_get_fips_mode_impl(PyObject *module)
1120+
/*[clinic end generated code: output=87eece1bab4d3fa9 input=c2799c3132a36d6c]*/
1121+
1122+
{
1123+
ERR_clear_error();
1124+
int result = FIPS_mode();
1125+
if (result == 0) {
1126+
// "If the library was built without support of the FIPS Object Module,
1127+
// then the function will return 0 with an error code of
1128+
// CRYPTO_R_FIPS_MODE_NOT_SUPPORTED (0x0f06d065)."
1129+
// But 0 is also a valid result value.
1130+
unsigned long errcode = ERR_peek_last_error();
1131+
if (errcode) {
1132+
_setException(PyExc_ValueError);
1133+
return -1;
1134+
}
1135+
}
1136+
return result;
1137+
}
1138+
#endif // !LIBRESSL_VERSION_NUMBER
1139+
1140+
10991141
/* List of functions exported by this module */
11001142

11011143
static struct PyMethodDef EVP_functions[] = {
11021144
EVP_NEW_METHODDEF
11031145
PBKDF2_HMAC_METHODDEF
11041146
_HASHLIB_SCRYPT_METHODDEF
1147+
_HASHLIB_GET_FIPS_MODE_METHODDEF
11051148
_HASHLIB_HMAC_DIGEST_METHODDEF
11061149
_HASHLIB_OPENSSL_MD5_METHODDEF
11071150
_HASHLIB_OPENSSL_SHA1_METHODDEF

Modules/clinic/_hashopenssl.c.h

Lines changed: 42 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)