BUG: Building numpy on a FIPS mode system fails due to use of md5
Describe the issue:
Linux systems with FIPS mode active disable algorithms that aren't part of the FIPS standard such as the md5 message digest/checksum.
Reproduce the code example:
If I install numpy from the git version: $ spin build numpy/_core/meson.build:55:4: ERROR: Command `/usr/bin/python3 /home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py --api-version 0x00000013` failed with status 1. A full log can be found at /home/user/current/lido/numpy/build/meson-logs/meson-log.txt Traceback (most recent call last): File "/usr/lib/python3.12/site-packages/click/core.py", line 781, in forward return __self.invoke(__cmd, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/click/core.py", line 760, in invoke return __callback(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/user/.local/lib/python3.12/site-packages/spin/cmds/meson.py", line 289, in build raise RuntimeError( RuntimeError: Meson configuration failed; please try `spin build` again with the `--clean` flag. An internal error has occurred. Please file a bug report at https://github.com/scientific-python/spin including the above traceback and the following information: spin: 0.11, package: numpy Aborting.
Error message:
Looking in `meson-log.txt`, here is if the error message: Program _build_utils/tempita.py found: YES (/usr/bin/python3 /home/user/current/lido/numpy/numpy/_build_utils/tempita.py) Running command: /usr/bin/python3 --version --- stdout --- Python 3.12.4 --- stderr --- Configuring __config__.py using configuration Running command: /usr/bin/python3 /home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py --api-version 0x00000013 --- stdout --- --- stderr --- Traceback (most recent call last): File "/home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py", line 66, in <module> main() File "/home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py", line 62, in main check_api_version(int(args.api_version, base=16)) File "/home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py", line 35, in check_api_version curapi_hash, api_hash = get_api_versions(apiversion) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py", line 25, in get_api_versions curapi_hash = m.fullapi_hash(numpy_api.full_api) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/user/current/lido/numpy/numpy/_core/code_generators/genapi.py", line 536, in fullapi_hash return hashlib.md5(''.join(a).encode('ascii')).hexdigest() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _hashlib.UnsupportedDigestmodError: [digital envelope routines] unsupported numpy/_core/meson.build:55:4: ERROR: Command `/usr/bin/python3 /home/user/current/lido/numpy/numpy/_core/code_generators/verify_c_api_version.py --api-version 0x00000013` failed with status 1.
### Python and NumPy Versions:
[user@machine numpy]$ python --version
Python 3.12.4
I used git main branch version.
### Runtime Environment:
The key aspect on my runtime environment is that Linux FIPS mode is activated.
It's a Fedora 39 system.
### Context for the issue:
This patch fixes the issue:
$ cat py-numpy/num-py-fips-mode.patch
--- a/numpy/core/code_generators/genapi.py~ 2024-02-05 13:17:48.000000000 -0800
+++ b/numpy/core/code_generators/genapi.py 2024-08-02 06:42:20.346265686 -0700
@@ -153,7 +153,13 @@
return '%s%s %s(%s)' % (doccomment, self.return_type, self.name, argstr)
-
if hashlib._hashlib.get_fips_mode(): -
m = hashlib.md5(usedforsecurity=False) -
m = hashlib.md5() m.update(remove_whitespace(self.return_type)) m.update('\000') m.update(self.name)
@@ -517,7 +523,14 @@
a.extend(name)
a.extend(','.join(map(str, data)))
- return hashlib.md5(''.join(a).encode('ascii')).hexdigest()
- try:
-
if hashlib._hashlib.get_fips_mode(): -
return hashlib.md5(''.join(a).encode('ascii'),usedforsecurity=False).hexdigest() -
return hashlib.md5(''.join(a).encode('ascii'),usedforsecurity=False).hexdigest() - except:
-
return hashlib.md5(''.join(a).encode('ascii')).hexdigest()
To parse strings like 'hex = checksum' where hex is e.g. 0x1234567F and
checksum a 128 bits md5 checksum (hex format as well)
@@ -539,7 +552,14 @@
tagname = sys.argv[1]
order_file = sys.argv[2]
functions = get_api_functions(tagname, order_file)
- m = hashlib.md5(tagname)
- try:
-
if hashlib._hashlib.get_fips_mode(): -
m = hashlib.md5(tagname, usedforsecurity=False) - except:
- for func in functions:
print(func)
ah = func.api_hash()