4

First I verify that my openssl is correct (compiled with FIPS support).

# openssl version
OpenSSL 1.0.2q-fips  20 Nov 2018

In normal mode:

# echo -n 123456 | openssl md5
(stdin)= e10adc3949ba59abbe56e057f20f883e

In FIPS mode:

# echo -n 123456 | OPENSSL_FIPS=1 openssl md5
Error setting digest md5
139993634896640:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180:

As expected.

Now I want to verify that python behaves as expected too.

I have python 3.6 compiled with FIPS mode support:

# ./python 
Python 3.6.8 (tags/v3.6.8-dirty:3c6b436a57, Apr 11 2019, 08:44:38) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2q-fips  20 Nov 2018'

I set it in FIPS mode:

>>> import ssl
>>> ssl.FIPS_mode_set(1)
>>> ssl.FIPS_mode()
1

And now I try to verify that it is running in FIPS mode:

>>> import hashlib
>>> 
>>> m = hashlib.md5()
>>> m.update(b"Nobody inspects")
>>> m.digest()
b'>\xf7)\xcc\xf0\xccV\x07\x9c\xa5F\xd5\x80\x83\xdc\x12'

Why is md5 allowed in FIPS mode?

EDIT

I have verified that python is using openssl implementation:

>>> hashlib.md5
<built-in function openssl_md5>
volingas
  • 1,023
  • 9
  • 21
  • 'Cause `hashlib` has little to do with `ssl`…? – deceze Apr 11 '19 at 09:55
  • 1
    *`md5()` is normally available as well, though it may be missing if you are using a rare “FIPS compliant” build of Python.* – You can't toggle the "FIPS compliant build" with a runtime setting. – deceze Apr 11 '19 at 09:57
  • @deceze hashlib uses openssl implementation (if available, which is the case in my system). Running in FIPS mode, openssl will refuse to do md5. Therefore, python md5 should fail too. – volingas Apr 11 '19 at 10:10
  • @deceze here is the relevant piece of code: https://github.com/python/cpython/blob/3.6/Lib/hashlib.py#L159 – volingas Apr 11 '19 at 10:12
  • Still, `md5` is in the `__always_supported` list and doesn't seem to depend on any `ssl` runtime settings… – deceze Apr 11 '19 at 10:14
  • @deceze I saw something strange: running python with env var OPENSSL_FIPS=1, and doing import in the right order (ssl, set fips mode, and then import hashlib) will fallback to the python md5 implementation ... – volingas Apr 11 '19 at 10:16
  • @deceze I think I got it: if FIPS mode is set, my python defaults to internal implementation, because openssl does not provide it. In no FIPS mode, it uses openssl implementation. This is unexpected: md5 should not be available at all if running in FIPS mode. And btw, the env var OPENSSL_FIPS has no effect for python. The setting is controlled with ssl.FIPS_mode_set(1). – volingas Apr 11 '19 at 10:20
  • Depends on how you define "unexpected". It's quite expected if you read the documentation. – deceze Apr 11 '19 at 10:21
  • @deceze the documentation is not for FIPS enabled pythons, since that is not official. But looking around you see that FIPS enabled pythons should not allow for md5, for example here: https://stackoverflow.com/questions/35586302/is-there-any-way-to-use-non-openssl-md5-for-hashlib-in-python – volingas Apr 11 '19 at 10:23
  • @deceze I will need to improve my python patch to prevent md5 I guess ... – volingas Apr 11 '19 at 10:23
  • @deceze here! https://docs.python.org/3.6/library/hashlib.html#hashlib.algorithms_guaranteed – volingas Apr 11 '19 at 10:24
  • @deceze "Note that ‘md5’ is in this list despite some upstream vendors offering an odd “FIPS compliant” Python build that excludes it." – volingas Apr 11 '19 at 10:25
  • How did you build *OpenSSL* that you linked in *Python* libs? Also, where did you get the changes for `ssl.FIPS_mode()`? I have a version that works perfectly (as long as fips mode is set before importing *hashlib*). – CristiFati Jun 22 '19 at 11:15
  • @volingas have you find any solution. I'm also stuck in same problem. I built fips-openssl, did changes in Python 3.7.9, built. But now, its exactly same code as yours. Not working. FIPS_mode() returns 1, still md5 works – Gorav Singal Feb 24 '21 at 12:40

1 Answers1

1

I found the solution. I made some changes to the Python patch.

The issue was, hashlib asks OpenSSL for the asked algorithm. it refuses for md5. Then, it switches to its default implementation for md5. I made a python patch for this.

See GitHub gist. https://gist.github.com/goravsingal/48986505b9efedf2c05ffd729b7eae69

Another issue was, even if you do this. Another developer can install the cryptography module, which exposes lower-level libraries which talk to Openssl directly. Cryptography modules require to be built especially for this.

See https://www.gyanblog.com/security/how-build-patch-python-3.7.9-fips-enable/

Gorav Singal
  • 508
  • 3
  • 11