Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-99890

crypto-policies not properly handling GSSAPIKexAlgorithms in FIPS policy

Linking RHIVOS CVEs to...Migration: Automation ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not a Bug
    • Icon: Undefined Undefined
    • None
    • rhel-9.6
    • crypto-policies
    • None
    • No
    • Low
    • rhel-security-crypto
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • Red Hat Enterprise Linux
    • None
    • None
    • None
    • Unspecified
    • Unspecified
    • Unspecified
    • x86_64
    • None

      What were you trying to do that didn't work?

      Attempting to connect to a server in FIPS mode over SSH.

      What is the impact of this issue to you?

      Drops SSH connection before authentication can finish.

      Please provide the package NVR for which the bug is seen:

      crypto-policies-scripts

      How reproducible is this bug?:

      Every time.

      Steps to reproduce

      1. Enable FIPS mode and if required, select the FIPS crypto policy.
      2. Ensure the policy has 'arbitrary_dh_groups = 1' enabled (FIPS.pol does by default).
      3. If modified, re-apply the policy.
      4. Edit the SSHd config to set 'GSSAPIKeyExchange' to no and 'GSSAPIAuthentication' to yes. (/etc/ssh/sshd_config.d/50-redhat.conf sets GSSAPIAuthentication to yes).
      5. run 'sshd -T'
      6. Observer the 'gssapikexalgorithms' parameter has 'gss-curve25519-sha256' enabled.
      7. Restart SSHd.
      8. Attempt to connect from an openSSH client that has ed25519/curve25519 enabled (aka not in FIPS mode). Connection will be refused.

      Expected results

      SSH connection succeeds as normal.

      Actual results

       

      Connection closed by 192.168.99.80 port 22
      

       

      Investigating:

      Server side - /var/log/secure

      Jun 24 15:04:12 localhost sshd[1959]: Connection from 192.168.99.128 port 46590 on 192.168.99.80 port 22 rdomain ""
      Jun 24 15:04:12 localhost sshd[1959]: input_kex_gen_init: Key exchange type c25519 is not allowed in FIPS mode [preauth]
      Jun 24 15:04:12 localhost sshd[1959]: ssh_dispatch_run_fatal: Connection from 192.168.99.128 port 46590: invalid argument [preauth]
      

       

      Disabling ed25519 on client machine, I can connect:

      Jun 24 15:08:21 localhost sshd[6881]: Connection from 192.168.99.128 port 48660 on 192.168.99.80 port 22 rdomain ""
      Jun 24 15:08:21 localhost sshd[6881]: userauth_pubkey: key type ssh-ed25519 not in PubkeyAcceptedAlgorithms [preauth]
      Jun 24 15:08:21 localhost sshd[6881]: Accepted key RSA SHA256:<REDACTED> found at /home/<REDACTED>/.ssh/authorized_keys:1
      Jun 24 15:08:21 localhost sshd[6881]: Postponed publickey for <REDACTED> from 192.168.99.128 port 48660 ssh2 [preauth]
      Jun 24 15:08:21 localhost sshd[6881]: Accepted key RSA SHA256:<REDACTED> found at /home/<REDACTED>/.ssh/authorized_keys:1
      Jun 24 15:08:21 localhost sshd[6881]: Accepted publickey for <REDACTED> from 192.168.99.128 port 48660 ssh2: RSA SHA256:<REDACTED>
      Jun 24 15:08:21 localhost sshd[6881]: pam_unix(sshd:session): session opened for user <REDACTED>(uid=1000) by (uid=0)
      Jun 24 15:08:21 localhost sshd[6881]: User child is on pid 6884
      Jun 24 15:08:21 localhost sshd[6884]: Starting session: shell on pts/1 for <REDACTED> from 192.168.99.128 port 48660 id 0
      

       

      Looking at '/etc/crypto-policies/back-ends/opensshserver.config' on the server:

      Ciphers aes256-gcm@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
      MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512
      GSSAPIKeyExchange no
      KexAlgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
      HostKeyAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com
      PubkeyAcceptedAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com
      CASignatureAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-256,rsa-sha2-512
      RequiredRSASize 2048
      

      We see 'GSSAPIKeyExchange no'.

       

      'sshd -T' shows:

      port 22
      addressfamily any
      listenaddress [::]:22
      listenaddress 0.0.0.0:22
      usepam yes
      logingracetime 60
      x11displayoffset 10
      x11maxdisplays 1000
      maxauthtries 4
      maxsessions 10
      clientaliveinterval 900
      clientalivecountmax 1
      requiredrsasize 2048
      streamlocalbindmask 0177
      permitrootlogin no
      ignorerhosts yes
      ignoreuserknownhosts no
      hostbasedauthentication no
      hostbasedusesnamefrompacketonly no
      pubkeyauthentication yes
      kerberosauthentication no
      kerberosorlocalpasswd yes
      kerberosticketcleanup yes
      kerberosuniqueccache no
      kerberosusekuserok yes
      gssapienablek5users no
      gssapiauthentication yes
      gssapicleanupcredentials no
      gssapikeyexchange no
      gssapistrictacceptorcheck yes
      gssapistorecredentialsonrekey no
      gssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-
      passwordauthentication yes
      kbdinteractiveauthentication no
      printmotd no
      printlastlog yes
      x11forwarding yes
      x11uselocalhost yes
      permittty yes
      permituserrc yes
      strictmodes yes
      tcpkeepalive yes
      permitemptypasswords no
      compression yes
      gatewayports no
      usedns no
      allowtcpforwarding yes
      allowagentforwarding no
      disableforwarding no
      allowstreamlocalforwarding yes
      streamlocalbindunlink no
      fingerprinthash SHA256
      exposeauthinfo no
      pidfile /var/run/sshd.pid
      modulifile /etc/ssh/moduli
      xauthlocation /usr/bin/xauth
      ciphers aes256-gcm@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
      macs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512
      banner /etc/issue.net
      forcecommand none
      chrootdirectory none
      trustedusercakeys none
      revokedkeys none
      securitykeyprovider internal
      authorizedprincipalsfile none
      versionaddendum none
      authorizedkeyscommand none
      authorizedkeyscommanduser none
      authorizedprincipalscommand none
      authorizedprincipalscommanduser none
      hostkeyagent none
      kexalgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
      casignaturealgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-256,rsa-sha2-512
      hostbasedacceptedalgorithms ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256
      hostkeyalgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com
      pubkeyacceptedalgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com
      loglevel VERBOSE
      syslogfacility AUTHPRIV
      authorizedkeysfile .ssh/authorized_keys
      hostkey /etc/ssh/ssh_host_ecdsa_key
      hostkey /etc/ssh/ssh_host_rsa_key
      denyusers root
      denyusers <REDACTED>
      allowgroups <REDACTED>
      allowgroups <REDACTED>
      authenticationmethods publickey password
      subsystem sftp /usr/libexec/openssh/sftp-server
      maxstartups 10:30:60
      persourcemaxstartups none
      persourcenetblocksize 32:128
      permittunnel no
      ipqos af21 cs1
      rekeylimit 0 0
      permitopen any
      permitlisten any
      permituserenvironment no
      pubkeyauthoptions none
      

       

      In particular look at :

      gssapikexalgorithms gss-group14-sha256-,gss-group16-sha512-,gss-nistp256-sha256-,gss-curve25519-sha256-,gss-group14-sha1-,gss-gex-sha1-
      

       

       

      Trying to find the cause, I rummaged around in '/usr/share/crypto-policies/python/cryptopolicies/cryptopolicies.py' to get the enumeration of the options:

      ALL_KEY_EXCHANGES = (
          'PSK', 'DHE-PSK', 'ECDHE-PSK', 'RSA-PSK', 'ECDHE',
          'RSA', 'DHE', 'DHE-RSA', 'DHE-DSS', 'EXPORT', 'ANON',
          'DH', 'ECDH',
          'VKO-GOST-2001', 'VKO-GOST-2012', 'VKO-GOST-KDF',
          'DHE-GSS', 'ECDHE-GSS',
          'SNTRUP',
      )
      
      ALL_HASHES = (
          'SHA2-256', 'SHA2-384', 'SHA2-512',
          'SHA3-256', 'SHA3-384', 'SHA3-512',
          'SHA2-224', 'SHA3-224',
          'SHAKE-256', 'SHAKE-128',
          'SHA1', 'MD5',
          'STREEBOG-256', 'STREEBOG-512', 'GOSTR94',
      )
      
      ALL_GROUPS = (
          'X25519', 'SECP256R1', 'SECP384R1', 'SECP521R1', 'X448',
          'FFDHE-1536', 'FFDHE-2048', 'FFDHE-3072', 'FFDHE-4096',
          'FFDHE-6144', 'FFDHE-8192', 'FFDHE-1024',
          'GOST-GC256A', 'GOST-GC256B', 'GOST-GC256C', 'GOST-GC256D',
          'GOST-GC512A', 'GOST-GC512B', 'GOST-GC512C',
      )
      

       

      which allowed me to follow in '/usr/share/crypto-policies/python/policygenerators/openssh.py' where I was able to view the key exchange map:

          gss_kx_map = {
              'DHE-GSS-SHA1': 'gss-gex-sha1-',
              'DHE-GSS-FFDHE-1024-SHA1': 'gss-group1-sha1-',
              'DHE-GSS-FFDHE-2048-SHA1': 'gss-group14-sha1-',
              'DHE-GSS-FFDHE-2048-SHA2-256': 'gss-group14-sha256-',
              'ECDHE-GSS-SECP256R1-SHA2-256': 'gss-nistp256-sha256-',
              'ECDHE-GSS-X25519-SHA2-256': 'gss-curve25519-sha256-',
              'DHE-GSS-FFDHE-4096-SHA2-512': 'gss-group16-sha512-',
          }
      

       

      Following it down to the 'generate_options' class:

      starting at line 148

              s = ''
              gss = ''
              for kx in p['key_exchange']:
                  for h in p['hash']:
                      if policy.integers['arbitrary_dh_groups']:
                          try:
                              val = cls.gx_map[kx + '-' + h]
                              s = cls.append(s, val, sep)
                          except KeyError:
                              pass
                          try:
                              val = local_gss_kx_map[kx + '-' + h]
                              gss = cls.append(gss, val, sep)
                          except KeyError:
                              pass                                                                                                                                                                                                                                                                  for g in p['group']:
                          try:                                                                                                                                                                                                                                                                              val = local_kx_map[kx + '-' + g + '-' + h]
                              s = cls.append(s, val, sep)
                          except KeyError:
                              pass                                                                                                                                                                                                                                                                      try:
                              val = local_gss_kx_map[kx + '-' + g + '-' + h]
                              gss = cls.append(gss, val, sep)
                          except KeyError:
                              pass
      
              if gss:
                  cfg += f'GSSAPIKexAlgorithms {gss}\n'
              else:
                  cfg += 'GSSAPIKeyExchange no\n'
      
              if s:
                  cfg += f'KexAlgorithms {s}\n'
      

      following the workflow, this will exclude the c25519 GSSApiKex as expected, EXCEPT when 'arbitrary_dh_groups' is set (which the FIPS crypto policy sets to 1).

      It appears even though 'GSSAPIKeyExchange' is set to no, but if 'GSSAPIAuthentication'
      is left enabled, it still tries to either use, or enumerate the GSSAPIKexAlgorithms, which throws:

      Jun 24 15:31:56 localhost sshd[33831]: Connection from 192.168.99.128 port 47382 on 192.168.99.80 port 22 rdomain ""
      Jun 24 15:31:56 localhost sshd[33831]: input_kex_gen_init: Key exchange type c25519 is not allowed in FIPS mode [preauth]
      Jun 24 15:31:56 localhost sshd[33831]: ssh_dispatch_run_fatal: Connection from 192.168.99.128 port 47382: invalid argument [preauth]
      

              asosedki@redhat.com Alexander Sosedkin
              gregoryyoung Gregory Young (Inactive)
              Alexander Sosedkin Alexander Sosedkin
              Ondrej Moris Ondrej Moris
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: