Skip to content

gh-95231: Disable md5 & crypt modules if FIPS is enabled #94742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 15, 2022
Merged

gh-95231: Disable md5 & crypt modules if FIPS is enabled #94742

merged 3 commits into from
Aug 15, 2022

Conversation

sshedi
Copy link
Contributor

@sshedi sshedi commented Jul 11, 2022

If kernel fips is enabled, we get permission error upon doing
import crypt. So, if kernel fips is enabled, disable the
unallowed hashing methods.

Python 3.9.1 (default, May 10 2022, 11:36:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

import crypt
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.9/crypt.py", line 117, in
_add_method('MD5', '1', 8, 34)
File "/usr/lib/python3.9/crypt.py", line 94, in _add_method
result = crypt('', salt)
File "/usr/lib/python3.9/crypt.py", line 82, in crypt
return _crypt.crypt(word, salt)
PermissionError: [Errno 1] Operation not permitted

Signed-off-by: Shreenidhi Shedi [email protected]

Automerge-Triggered-By: GH:tiran

@ghost
Copy link

ghost commented Jul 11, 2022

All commit authors signed the Contributor License Agreement.
CLA signed

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 11, 2022

Hi @vstinner, @erlend-aasland, @rhettinger
Please take a look at my code changes. Do I need to create a github issue for this? This is my first attempt to contribute to upstream python. Please help me out.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

Hi @gvanrossum @benjaminp @birkenfeld @freddrake,

Please review this PR, need your inputs.

@birkenfeld
Copy link
Member

Please abstain from pinging random developers. See https://www.python.org/dev/core-mentorship/ for getting help with your first contributions and in general https://devguide.python.org/ for documentation of our process.

@erlend-aasland
Copy link
Contributor

Hi, @sshedi; thanks for your interest in improving CPython! Please create an issue and explain why these changes are needed.

Also, for the future, please follow Georg Brandl's advice: start with the devguide; it contains a lot of important information for new contributors.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

Thanks @erlend-aasland and @birkenfeld for your response.

I have created an issue here #95231
I will go through the development process, I checked the top contributors and tagged them here to get some insights on my PR.

I believe I have given sufficient info on the issue I'm facing.

@erlend-aasland erlend-aasland changed the title Lib/crypt.py: disable md5 & crypt modules if kernel fips is enabled. gh-95231: Disable md5 & crypt modules if FIPS is enabled Jul 25, 2022
@erlend-aasland erlend-aasland linked an issue Jul 25, 2022 that may be closed by this pull request
Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach with reading from /proc/sys/crypto/fips_enabled and manually disabling MD5 and CRYPT is not portable. The proc interface is Linux specific. The system may block more or less algorithms depending on the local crypto policy.

I recommend that we should catch more errno values in _add_method instead.

diff --git a/Lib/crypt.py b/Lib/crypt.py
index 46c3de8474b..92e70415e1a 100644
--- a/Lib/crypt.py
+++ b/Lib/crypt.py
@@ -100,6 +100,9 @@ def _add_method(name, *args, rounds=None):
         # Not all libc libraries support all encryption methods.
         if e.errno == errno.EINVAL:
             return False
+        # unsupported or blocked by crypto policy
+        if e.errno in {errno.EPERM, errno.ENOSYS}:
+            return False
         raise
     if result and len(result) == method.total_size:
         methods.append(method)

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@erlend-aasland
Copy link
Contributor

Also, please add a NEWS entry using the blurb tool.

https://devguide.python.org/getting-started/pull-request-lifecycle/

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

@tiran Valid point. But how other python modules are detecting kernel fips status?
I made my changes using

with open("/proc/sys/crypto/fips_enabled", encoding="utf-8") as fp:
as reference.

Suggested code works but can we have something to know that we got EPERM because of fips?

@tiran
Copy link
Member

tiran commented Jul 25, 2022

Your proposed solution is solving the wrong problem, or at least a too narrow part of a general problem. It is trying to detect FIPS mode and then hard-codes which algorithms it thinks are disabled in FIPS mode. FIPS is an evolving standard. For example FIPS 140-3 blocks some algorithms are are allowed in FIPS 140-2. There are also more crypto policy standards than FIPS. FIPS is only relevant for the US government. It is irrelevant for the rest of the world and non-government software inside the US.

My solution is simpler and should fix your problem with less code. It is also not tight to FIPS and can handle other crypto policies that block algorithms.

I don't know why libcrypt on your system raises a permission error. I recommend that your contact your vendor and make an inquiry.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

Thanks @tiran for the detailed explanation, I agree. I will make the suggested changes.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

The EPERM error is coming from libcrypt and glibc is doing it.

https://github.com/bminor/glibc/blob/ca4d3ea5130d66e66c5af14e958e99341bf20689/crypt/crypt-entry.c#L89

      /* FIPS rules out MD5 password encryption.  */
      if (fips_enabled_p ())
	{
	  __set_errno (EPERM);
	  return NULL;
	}

@erlend-aasland
Copy link
Contributor

erlend-aasland commented Jul 25, 2022

For the record; please do not force push PRs, as the GitHub UI do not play well with force-pushes. Please use git merge --no-ff main instead.

@sshedi ☝🏻

@sshedi
Copy link
Contributor Author

sshedi commented Jul 25, 2022

Sorry @erlend-aasland , it has become a habit for me now. git push origin -f <my-branch-name>
Will give your suggestion a try.

@sshedi
Copy link
Contributor Author

sshedi commented Jul 26, 2022

I have made the requested changes; please review again.

@erlend-aasland - Sorry, I amended y changes addressing review comments so I have to force push to my branch.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@tiran: please review the changes made to this pull request.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@erlend-aasland, @tiran: please review the changes made to this pull request.

@erlend-aasland
Copy link
Contributor

Updating branch to retrigger Azure Pipelines CI.

@miss-islington miss-islington merged commit 2fa03b1 into python:main Aug 15, 2022
@miss-islington
Copy link
Contributor

Thanks @sshedi for the PR 🌮🎉.. I'm working now to backport this PR to: 3.10, 3.11.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry @sshedi, I had trouble checking out the 3.11 backport branch.
Please backport using cherry_picker on command line.
cherry_picker 2fa03b1b0708d5d74630c351ec9abd2aac7550da 3.11

@miss-islington miss-islington self-assigned this Aug 15, 2022
@bedevere-bot bedevere-bot removed the needs backport to 3.10 only security fixes label Aug 15, 2022
@bedevere-bot
Copy link

GH-95998 is a backport of this pull request to the 3.10 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Aug 15, 2022
…nGH-94742)

If kernel fips is enabled, we get permission error upon doing
`import crypt`. So, if kernel fips is enabled, disable the
unallowed hashing methods.

Python 3.9.1 (default, May 10 2022, 11:36:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/crypt.py", line 117, in <module>
    _add_method('MD5', '1', 8, 34)
  File "/usr/lib/python3.9/crypt.py", line 94, in _add_method
    result = crypt('', salt)
  File "/usr/lib/python3.9/crypt.py", line 82, in crypt
    return _crypt.crypt(word, salt)
PermissionError: [Errno 1] Operation not permitted

Signed-off-by: Shreenidhi Shedi <[email protected]>
(cherry picked from commit 2fa03b1)

Co-authored-by: Shreenidhi Shedi <[email protected]>
@tiran tiran added needs backport to 3.11 only security fixes and removed needs backport to 3.11 only security fixes labels Aug 15, 2022
@miss-islington
Copy link
Contributor

Thanks @sshedi for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Aug 15, 2022
…nGH-94742)

If kernel fips is enabled, we get permission error upon doing
`import crypt`. So, if kernel fips is enabled, disable the
unallowed hashing methods.

Python 3.9.1 (default, May 10 2022, 11:36:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/crypt.py", line 117, in <module>
    _add_method('MD5', '1', 8, 34)
  File "/usr/lib/python3.9/crypt.py", line 94, in _add_method
    result = crypt('', salt)
  File "/usr/lib/python3.9/crypt.py", line 82, in crypt
    return _crypt.crypt(word, salt)
PermissionError: [Errno 1] Operation not permitted

Signed-off-by: Shreenidhi Shedi <[email protected]>
(cherry picked from commit 2fa03b1)

Co-authored-by: Shreenidhi Shedi <[email protected]>
@bedevere-bot bedevere-bot removed the needs backport to 3.11 only security fixes label Aug 15, 2022
@bedevere-bot
Copy link

GH-95999 is a backport of this pull request to the 3.11 branch.

miss-islington added a commit that referenced this pull request Aug 15, 2022
If kernel fips is enabled, we get permission error upon doing
`import crypt`. So, if kernel fips is enabled, disable the
unallowed hashing methods.

Python 3.9.1 (default, May 10 2022, 11:36:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/crypt.py", line 117, in <module>
    _add_method('MD5', '1', 8, 34)
  File "/usr/lib/python3.9/crypt.py", line 94, in _add_method
    result = crypt('', salt)
  File "/usr/lib/python3.9/crypt.py", line 82, in crypt
    return _crypt.crypt(word, salt)
PermissionError: [Errno 1] Operation not permitted

Signed-off-by: Shreenidhi Shedi <[email protected]>
(cherry picked from commit 2fa03b1)

Co-authored-by: Shreenidhi Shedi <[email protected]>
@sshedi sshedi deleted the crypt-fips-fix branch August 18, 2022 07:34
miss-islington added a commit that referenced this pull request Aug 30, 2022
If kernel fips is enabled, we get permission error upon doing
`import crypt`. So, if kernel fips is enabled, disable the
unallowed hashing methods.

Python 3.9.1 (default, May 10 2022, 11:36:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.9/crypt.py", line 117, in <module>
    _add_method('MD5', '1', 8, 34)
  File "/usr/lib/python3.9/crypt.py", line 94, in _add_method
    result = crypt('', salt)
  File "/usr/lib/python3.9/crypt.py", line 82, in crypt
    return _crypt.crypt(word, salt)
PermissionError: [Errno 1] Operation not permitted

Signed-off-by: Shreenidhi Shedi <[email protected]>
(cherry picked from commit 2fa03b1)

Co-authored-by: Shreenidhi Shedi <[email protected]>
@mixmind
Copy link

mixmind commented May 3, 2024

Hi everyone, any chance of backport it to 3.9 too??

@vstinner
Copy link
Member

vstinner commented May 3, 2024

Hi everyone, any chance of backport it to 3.9 too??

That's somehow a new feature, and 3.9 only accept security fixes: https://devguide.python.org/versions/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

crypt module fails to import in FIPS mode
8 participants