Skip to content
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

FIPS 140-3 vs supported algorithms in ssh #9520

Open
yarisx opened this issue Mar 3, 2025 · 7 comments
Open

FIPS 140-3 vs supported algorithms in ssh #9520

yarisx opened this issue Mar 3, 2025 · 7 comments
Assignees
Labels
bug Issue is reported as a bug priority:medium team:PS Assigned to OTP team PS team:VM Assigned to OTP team VM

Comments

@yarisx
Copy link
Contributor

yarisx commented Mar 3, 2025

Describe the bug
The output of ssh_transport:supported_algorithms() when used with FIPS-enabled OpenSSL contains algorithms that should not be supported (if I'm reading FIPS 140-3 right, which is not an easy read):

Erlang/OTP 27 [erts-15.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Eshell V15.2.2 (press Ctrl+G to abort, type help(). for help)
1> crypto:enable_fips_mode(true).
true
2> ssh_transport:supported_algorithms().
[{kex,['ecdh-sha2-nistp521','ecdh-sha2-nistp384',
       'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
       'diffie-hellman-group16-sha512',
       'diffie-hellman-group18-sha512',
       'diffie-hellman-group14-sha256',
       'diffie-hellman-group14-sha1',
       'diffie-hellman-group-exchange-sha1',
       'diffie-hellman-group1-sha1']},
 {public_key,['ecdsa-sha2-nistp521','ecdsa-sha2-nistp384',
              'ecdsa-sha2-nistp256','rsa-sha2-512','rsa-sha2-256',
              'ssh-rsa','ssh-dss']},
 {cipher,[{client2server,['[email protected]',
                          'aes256-ctr','aes192-ctr','[email protected]',
                          'aes128-ctr','AEAD_AES_256_GCM','AEAD_AES_128_GCM',
                          'aes256-cbc','aes192-cbc','aes128-cbc','3des-cbc']},
          {server2client,['[email protected]','aes256-ctr',
                          'aes192-ctr','[email protected]','aes128-ctr',
                          'AEAD_AES_256_GCM','AEAD_AES_128_GCM','aes256-cbc',
                          'aes192-cbc','aes128-cbc','3des-cbc']}]},
 {mac,[{client2server,['[email protected]',
                       '[email protected]','hmac-sha2-512',
                       'hmac-sha2-256','[email protected]','hmac-sha1',
                       'hmac-sha1-96','AEAD_AES_256_GCM','AEAD_AES_128_GCM']},
       {server2client,['[email protected]',
                       '[email protected]','hmac-sha2-512',
                       'hmac-sha2-256','[email protected]','hmac-sha1',
                       'hmac-sha1-96','AEAD_AES_256_GCM','AEAD_AES_128_GCM']}]},
 {compression,[{client2server,[none,'[email protected]',zlib]},
               {server2client,[none,'[email protected]',zlib]}]}]
3> crypto:info_fips().
enabled
4> crypto:info_lib().
[{<<"OpenSSL">>,805306368,<<"OpenSSL 3.0.0 7 sep 2021">>}]

As one can see ssh-dss and ssh-rsa are present in the list as supported, although they use SHA1 which is not allowed for signature generation in FIPS 140-3 (and DSA has restriction on bitsize >= 2048 to be allowed, which is not supported by ssh-keygen from OpenSSH). Also among ciphers there is 3DES, which is allowed only for decryption (even in 3-key mode after 2023) so practically it cannot be used by SSH (although maybe there are clients/servers that allow for asymmetrical cipher choice - I have not met one yet).

To Reproduce
Build OTP with OpenSSL3.0.0 + FIPS provider, check the supported algorithms. Note that the output of crypto:supports() while containing SHA1, 3DES etc is technically correct as it does not assume specific usage of these algorithms.

Expected behavior
A list of supported algorithms in OTP SSH should not include those that are not allowed to be used in FIPS mode.

Affected versions
OTP27.2.2

@yarisx yarisx added the bug Issue is reported as a bug label Mar 3, 2025
@u3s u3s self-assigned this Mar 4, 2025
@u3s u3s added the team:PS Assigned to OTP team PS label Mar 4, 2025
@u3s u3s removed their assignment Mar 4, 2025
@yarisx
Copy link
Contributor Author

yarisx commented Mar 4, 2025

Also usage of Ed448 curve is approved for digital signatures by FIPS 140-3 (unlike 140-2) but OTP still says "Unsupported algorithm in FIPS mode"

@sverker
Copy link
Contributor

sverker commented Mar 4, 2025

Also usage of Ed448 curve is approved for digital signatures by FIPS 140-3 (unlike 140-2) but OTP still says "Unsupported algorithm in FIPS mode"

I did a quick commit that allows EDDSA for FIPS:
https://github.com/sverker/otp/tree/sverker/crypto/allow-eddsa-with-fips

It seems to work when I test on OpenSSL 3.0.9 with FIPS. But is it the right thing to do, to leave it up to OpenSSL?

@IngelaAndin
Copy link
Contributor

I am not a 100 % sure how the FIPS mode in OpenSSL is supposed to work. Can it be so that FIPS allows sha1 to be called for some circumstances but not for others? So that crypto:supports may correctly return that sha1 hash function can be called but although it mandates it can not be called in combination with a signature algorithm?
In that case it will be very hard for ssh (or other application) to determine the difference. Or maybe crypto:supports functions is implemented incorrectly?! I think the preferred way is OpenSSL somehow can be queried for what it can support. Otherwise I do not know how we could distinguish between FIPS 140-3 and 140-2 as we do not really control what version that will be linked with OTP and how it is built.

@yarisx
Copy link
Contributor Author

yarisx commented Mar 6, 2025

Taking into account these statements from NIST

September 22, 2020 | CMVP accepted FIPS 140-3 submissions
April 1, 2022              | CMVP no longer accepts FIPS 140-2 submissions for new validation certificates.
September 22, 2026 | All FIPS 140-2 certificates are placed on the Historical List

I would not be bothered much by supporting FIPS 140-2. Especially this is the case for OpenSSL3 which has never been certified for FIPS 140-2, and OpenSSL3 does already have special treatment in OTP.

Regarding the reporting of supported algorithms: crypto:supports() is correct, as I've noted in the description. The issue arises when an application (OTP SSH in our case) tries to use algorithms for the purposes where said algorithms are not allowed. E.g. SHA1 use is allowed to compare documents, but not allowed for digital signatures. The same applies to OpenSSL: it can refuse to encrypt/sign something with an RSA key that is too short/weak, but it cannot deny use of SHA1 because SHA1 still has legitimate use in FIPS mode.
So it is up to application to verify that algorithm combinations are valid in FIPS mode. This application can be either OTP SSH or a user of OTP SSH. In any case it would be nice to have exactly one source of authority with regard to supported algorithms, and have this source of authority clearly stated in the documentation.

@sverker
Copy link
Contributor

sverker commented Mar 6, 2025

I would prefer if the authority of what algorithms that OpenSSL supports would be OpenSSL (FIPS or not). Such that OTP crypto could query OpenSSL and present the result upwards to OTP ssh and others, in such a way that they can make decisions about what ciphers to negotiate for example. If we could trust OpenSSL as an authority for that then we (OTP) would not have to care what FIPS standard applies at the moment. Whatever OpenSSL version/configuration the user has chosen decides.

Even if crypto:supports today is "correct", it seems to be lacking. The example being that supporting rsa and sha does not imply rsa with sha is supported. Maybe we need another way for OTP crypto to present that in order to avoid OTP ssh and others to have that knowledge.

@yarisx
Copy link
Contributor Author

yarisx commented Mar 7, 2025

I agree that it would be the best if OpenSSL was the source of authority. But my knowledge of OpenSSL API is not good enough to see if there is a reliable method to get correct information from OpenSSL. For example if I try command-line openssl I get this:

$ openssl list -signature-algorithms -provider fips
  { 1.2.840.113549.1.1.1, 2.5.8.1.1, RSA, rsaEncryption } @ fips
  { 1.2.840.10040.4.1, 1.2.840.10040.4.3, 1.3.14.3.2.12, 1.3.14.3.2.13, 1.3.14.3.2.27, DSA, DSA-old, DSA-SHA, DSA-SHA1, DSA-SHA1-old, dsaEncryption, dsaEncryption-old, dsaWithSHA, dsaWithSHA1, dsaWithSHA1-old } @ fips
  { 1.3.101.112, ED25519 } @ fips
  { 1.3.101.113, ED448 } @ fips
  ECDSA @ fips
  HMAC @ fips
  CMAC @ fips

So even in FIPS mode OpenSSL3 CLI tool reports that it can use DSA with SHA1, which is true only with the caveat that this combo can be used only for legacy purposes, i.e. to verify the existing signatures. It seems to me that the only reliable way to get complete and correct information regarding support of a crypto algorithm from OpenSSL in FIPS mode is to try and use the crypto algorithm in question. This does not look as a very practical solution though. But if there are API function calls that provide more accurate information than the command-line invocation - then it would be nice to have it exposed through OTP crypto.

@IngelaAndin IngelaAndin added priority:medium team:VM Assigned to OTP team VM labels Mar 11, 2025
@yarisx
Copy link
Contributor Author

yarisx commented Mar 21, 2025

An update (technically covered by the issue title but may be a separate problem):
It is impossible to use diffie-hellman-group-exchange-sha256 in SSH server in FIPS mode, although I could not find any indication in FIPS that this method is forbidden. Any connection attempt results in the crash:

Accept failed on 0.0.0.0:2024 for connect from 127.0.0.1:47696: {{error,{"dh.c",124},"Can't generate DH key pair"},
   [{crypto,generate_key,3,
            [{file,"crypto.erl"},
             {line,2771},
             {error_info,#{erl_function_arg_num => undefined}}]},
    {ssh_transport,generate_key,2,[{file,"ssh_transport.erl"},{line,2277}]},
    {ssh_transport,parallell_gen_key,1,
                   [{file,"ssh_transport.erl"},{line,2270}]},
    {ssh_fsm_kexinit,handle_event,4,[{file,"ssh_fsm_kexinit.erl"},{line,95}]},
    {gen_statem,loop_state_callback,11,[{file,"gen_statem.erl"},{line,3737}]},
    {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,329}]}]}

even when the DH prime size limit is set to be 4096 or higher (FIPS recommendation is 2048 and higher).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug priority:medium team:PS Assigned to OTP team PS team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

4 participants