Bug 1778939

Summary: internal pyca error with X25519, FIPS
Product: Red Hat Enterprise Linux 8 Reporter: Bill Nottingham <notting>
Component: python-cryptographyAssignee: Christian Heimes <cheimes>
Status: CLOSED ERRATA QA Contact: Kaleem <ksiddiqu>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 8.1CC: myusuf, ndehadra, sorlov, ssidhaye
Target Milestone: rc   
Target Release: 8.4   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: python-cryptography-3.2.1-3.el8 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-05-18 14:52:08 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1873581    
Bug Blocks:    

Description Bill Nottingham 2019-12-02 21:10:24 UTC
Description of problem:

[cloud-user@fipsy-fu ~]$ python3
Python 3.6.8 (default, Oct 11 2019, 15:04:54) 
[GCC 8.3.1 20190507 (Red Hat 8.3.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import (X25519PrivateKey,X25519PrivateKey)
>>> print(X25519PrivateKey.generate())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 41, in generate
    return backend.x25519_generate_key()
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1922, in x25519_generate_key
    self.openssl_assert(evp_pkey_ctx != self._ffi.NULL)
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 105, in openssl_assert
    return binding._openssl_assert(self._lib, ok)
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/bindings/openssl/binding.py", line 76, in _openssl_assert
    errors_with_text
cryptography.exceptions.InternalError: Unknown OpenSSL error. This error is commonly encountered when another library is not cleaning up the OpenSSL error stack. If you are using cryptography with another library that uses OpenSSL try disabling it before reporting a bug. Otherwise please file an issue at https://github.com/pyca/cryptography/issues with information on how to reproduce this. ([_OpenSSLErrorWithText(code=101306568, lib=6, func=157, reason=200, reason_text=b'error:0609D0C8:digital envelope routines:int_ctx_new:disabled for FIPS')])
>>> 


Version-Release number of selected component (if applicable):
2.3-2.el8
2.3-3.el8

How reproducible:
100%

Steps to Reproduce:
1. see above (trimmed from paramiko, but reproducible without it)

Additional info:

upstream poked here: https://github.com/pyca/cryptography/issues/5082

On RHEL 7 it returns a correct error:
Python 2.7.5 (default, Aug  7 2019, 00:51:29) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography
>>> print(cryptography)
<module 'cryptography' from '/home/user/.local/lib/python2.7/site-packages/cryptography/__init__.pyc'>
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import (X25519PrivateKey,X25519PrivateKey)
>>> print(X25519PrivateKey.generate())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/.local/lib/python2.7/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 42, in generate
    _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM
cryptography.exceptions.UnsupportedAlgorithm: X25519 is not supported by this version of OpenSSL.
>>>

Comment 1 Christian Heimes 2019-12-02 21:46:51 UTC
It kinda works as intended, except error handling needs improvements. X25519 is prohibited in FIPS mode. My PR https://github.com/pyca/cryptography/pull/5024 attempts to make error handling better and also contains some documentation.

AFAIK you are not allowed to use Paramiko in FIPS mode, too. Paramiko is not a FIPS approved OpenSSH implementation. Further more there are some missing features (rsa-sha2 support) and forbidden crypto (MD5 for fingerprints) in Paramiko. I have been running into issues with Paramiko in our upstream integration tests, see https://bugzilla.redhat.com/show_bug.cgi?id=1775693

Comment 2 Bill Nottingham 2019-12-02 22:00:16 UTC
I don't see how this is working as intended - on RHEL 7 this properly returns cryptography.exceptions.UnsupportedAlgorithm which can be handled and dealt with.
On RHEL 8, it returns cryptography.exceptions.InternalError, which is not useful.

Comment 3 Christian Heimes 2019-12-09 10:49:59 UTC
On RHEL 7 the official python-cryptography package version is 1.7. X25519 support was added in python-cryptography 2.0. A self-compiled build of python-cryptography raises UnsupportedAlgorithm because OpenSSL 1.0.2 on RHEL 7 does not provide X25519.

RHEL 8 comes with OpenSSL 1.1.1 and a more recent version of python-cryptography. Both support X25519, however OpenSSL blocks X25519 in FIPS mode.

python-cryptography is not FIPS aware. Instead it uses compile-time and version checks to detect support for X25519. I'm working with upstream to address the problem. I might be able to address the problem in a future version of RHEL 8.

Comment 4 Christian Heimes 2020-05-20 08:35:45 UTC
I won't be able to deliver a fix in RHEL 8.3. Upstream work is not finished yet.

Comment 9 Christian Heimes 2020-10-29 12:14:00 UTC
With python3-cryptography 3.2.1 test build

$ rpm -qa python3-cryptography
python3-cryptography-3.2.1-1.el8.x86_64

standard system

$ python3
Python 3.6.8 (default, Aug 18 2020, 08:33:21) 
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'3.2.1'
>>> from cryptography.hazmat.backends.openssl import backend
>>> backend._is_fips_enabled()
False
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
<cryptography.hazmat.backends.openssl.x25519._X25519PrivateKey object at 0x7f5ab668e1d0>

FIPS enabled system

$ python3
Python 3.6.8 (default, Aug 18 2020, 08:33:21) 
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'3.2.1'
>>> from cryptography.hazmat.backends.openssl import backend
>>> backend._is_fips_enabled()
True
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 44, in generate
    _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
cryptography.exceptions.UnsupportedAlgorithm: X25519 is not supported by this version of OpenSSL.

Comment 13 Mohammad Rizwan 2020-11-24 12:19:32 UTC
reproducer:
~~~~~~~~~~~
Non-fips:

[root@master ~]# python3
Python 3.6.8 (default, Nov  9 2020, 11:22:58) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'2.3'
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
<cryptography.hazmat.backends.openssl.x25519._X25519PrivateKey object at 0x7f533b9cea20>
>>>

FIPS mode:

[root@master ~]# fips-mode-setup --check
FIPS mode is enabled.
[root@master ~]# python3
Python 3.6.8 (default, Nov  9 2020, 11:22:58) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'2.3'
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 41, in generate
    return backend.x25519_generate_key()
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1922, in x25519_generate_key
    self.openssl_assert(evp_pkey_ctx != self._ffi.NULL)
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 105, in openssl_assert
    return binding._openssl_assert(self._lib, ok)
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/bindings/openssl/binding.py", line 76, in _openssl_assert
    errors_with_text
cryptography.exceptions.InternalError: Unknown OpenSSL error. This error is commonly encountered when another library is not cleaning up the OpenSSL error stack. If you are using cryptography with another library that uses OpenSSL try disabling it before reporting a bug. Otherwise please file an issue at https://github.com/pyca/cryptography/issues with information on how to reproduce this. ([_OpenSSLErrorWithText(code=101306568, lib=6, func=157, reason=200, reason_text=b'error:0609D0C8:digital envelope routines:int_ctx_new:disabled for FIPS')])
>>> 


Fix:
~~~~
version:
python3-cryptography-3.2.1-1.el8.x86_64


Non-FIPS mode:
[root@master ~]# python3
Python 3.6.8 (default, Nov  9 2020, 11:22:58) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'3.2.1'
>>> from cryptography.hazmat.backends.openssl import backend
>>> backend._is_fips_enabled()
False
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
<cryptography.hazmat.backends.openssl.x25519._X25519PrivateKey object at 0x7f562ec69a58>
>>> 



FIPS mode:
[root@master ~]# python3
Python 3.6.8 (default, Nov  9 2020, 11:22:58) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import cryptography.__about__
>>> cryptography.__about__.__version__
'3.2.1'
>>> from cryptography.hazmat.backends.openssl import backend
>>> backend._is_fips_enabled()
True
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
>>> X25519PrivateKey.generate()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 44, in generate
    _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
cryptography.exceptions.UnsupportedAlgorithm: X25519 is not supported by this version of OpenSSL.
>>> 


Exception prints the error properly. Based on above observations, marking it verified.

Comment 17 Mohammad Rizwan 2020-12-09 11:50:07 UTC
version:
python3-cryptography-3.2.1-1.el8.x86_64


Fips mode:
~~~~~~~~~~
[root@master ~]# fips-mode-setup --check
FIPS mode is enabled.
[root@master ~]# 
[root@master ~]# python3
Python 3.6.8 (default, Nov 24 2020, 02:51:57) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import (X25519PrivateKey,X25519PrivateKey)
>>> print(X25519PrivateKey.generate())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py", line 44, in generate
    _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM,
cryptography.exceptions.UnsupportedAlgorithm: X25519 is not supported by this version of OpenSSL.
>>> 


Non fips mode:
[root@master ~]# python3
Python 3.6.8 (default, Nov 24 2020, 02:51:57) 
[GCC 8.4.1 20200928 (Red Hat 8.4.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cryptography.hazmat.primitives.asymmetric.x25519 import (X25519PrivateKey,X25519PrivateKey)
>>> print(X25519PrivateKey.generate())
<cryptography.hazmat.backends.openssl.x25519._X25519PrivateKey object at 0x7fd3615a8ac8>
>>> 


So it works in non-fips mode and throws proper error in fips mode. Hence marking the bug as verified

Comment 20 errata-xmlrpc 2021-05-18 14:52:08 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Moderate: python-cryptography security, bug fix, and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2021:1608