FIPS builds filter only key exchange algorithms
Summary
On FIPS builds, only the key exchange list is narrowed. Ciphers, MACs, and public key authentication algorithms pass through as plain Go defaults and still include hmac-sha1, hmac-sha1-96, chacha20-poly1305@openssh.com, ssh-rsa, and ssh-dss.
This may well be intended. The source comment suggests it is. Raising it to confirm, because the effective behaviour is easy to misread as "FIPS builds start from a FIPS-approved set".
Detail
internal/sshd/server_config.go calls fips.DefaultAlgorithms():
// Right now we use fips.DefaultAlgorithms() instead of fips.SupportedAlgorithms()
// to preserve backwards compatibility with clients that are not configured properly.
// fips.DefaultAlgorithms() still allows ssh-rsa and ssh-dss. Admins can lock down
// these algorithms by setting `public_key_algorithms`.In labkit/fips/ssh.go, the two functions differ substantially. SupportedAlgorithms() filters ciphers, MACs, key exchanges, and public key auth. DefaultAlgorithms() filters only key exchanges:
func DefaultAlgorithms() ssh.Algorithms {
config := &ssh.ServerConfig{}
config.SetDefaults()
return ssh.Algorithms{
Ciphers: config.Ciphers,
MACs: config.MACs,
KeyExchanges: filterFIPSCompliant(config.KeyExchanges, nonFIPSKeyExchanges),
HostKeys: nil,
PublicKeyAuths: config.PublicKeyAuthAlgorithms,
}
}nonFIPSCiphers and nonFIPSMACs are defined in that file but only SupportedAlgorithms() uses them.
There is a second effect on PublicKeyAuths. Config.SetDefaults() never populates PublicKeyAuthAlgorithms, so config.PublicKeyAuthAlgorithms is nil here. The FIPS branch assigns nil, and NewServerConn then restores the full defaultPubKeyAuthAlgos, including ssh-rsa and ssh-dss.
Verified against gitlab-shell 14.56.1, golang.org/x/crypto v0.54.0, gitlab.com/gitlab-org/labkit v1.64.2.
Questions
- Is filtering only key exchange the intended behaviour for FIPS builds, or is the narrower
SupportedAlgorithms()the eventual goal? - If it is intended, is there appetite for a log line at startup on FIPS builds noting which algorithm classes are unrestricted? An operator running a FIPS build reasonably assumes SHA-1 is excluded.
Context
Raised while documenting the gitlab-sshd algorithm settings in gitlab!252085 (merged). A paragraph describing FIPS behaviour was removed from that MR pending the answer here, so the documentation currently says nothing about FIPS.