sshalgo

package
v2.35.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package sshalgo provides the SSH algorithm sets a server should offer, filtered for FIPS 140-3 compliance when the binary is built with the fips build tag.

Without the fips build tag the functions return golang.org/x/crypto/ssh's own algorithm sets unchanged, so callers can wire them in unconditionally and let the build tag decide the policy:

config := &ssh.ServerConfig{}

algorithms := sshalgo.DefaultAlgorithms()
config.Ciphers = algorithms.Ciphers
config.MACs = algorithms.MACs
config.KeyExchanges = algorithms.KeyExchanges
config.PublicKeyAuthAlgorithms = algorithms.PublicKeyAuths

signer, err := sshalgo.HostKeySigner(hostKey)
if err != nil {
    return err
}
config.AddHostKey(signer)

Assigning PublicKeyAuthAlgorithms and wrapping each host key are both required, not optional. ssh.ServerConfig has no field that can express either policy on its own: SetDefaults never populates PublicKeyAuthAlgorithms, and a server ignores Config.HostKeyAlgorithms entirely, deriving what it advertises from the keys it was given. Skip them and a FIPS server offers ssh-rsa.

Policy

The algorithms fall into three tiers, because there are three different reasons to withhold one. COMPLIANCE.md gives the per-algorithm mapping to the governing NIST document.

Tier 1 is never offered: ChaCha20-Poly1305, which has no entry in SP 800-140C Rev. 2, and standalone X25519 key agreement, which the FIPS 140-3 Implementation Guidance excludes as a curve in SP 800-186 but not SP 800-56Arev3.

Tier 2 is offered only where the native Go Cryptographic Module is active: the ML-KEM768/X25519 hybrid. ML-KEM-768 supplies an approved shared secret, so the X25519 contribution is permissible additional keying material under SP 800-227 Section 4.6.2, and x/crypto/ssh registers the hybrid ahead of its own FIPS branch so that it survives. It is withheld on BoringCrypto for an operational reason rather than a compliance one: the golang-fips toolchain patches crypto/ecdh to refuse X25519 whenever OpenSSL is active, so the handshake cannot complete.

Tier 3 is offered by default and removed by WithoutDeprecated: the SHA-1 constructions that SP 800-131A deprecates only until 2030-12-31, and finite-field Diffie-Hellman, whose groups are approved safe primes but whose implementation in x/crypto is pure-Go math/big, outside every validated boundary. Withholding these is a hardening choice, not a compliance requirement, so the default keeps older clients working.

Backends

Under the native Go Cryptographic Module (built with GOFIPS140, so crypto/fips140.Enabled reports true) the result is narrowed further to what x/crypto/ssh can actually negotiate: the non-approved algorithms are never registered in its internal maps, and ssh.Config.SetDefaults - which ssh.NewServerConn and ssh.NewClientConn both call unconditionally - drops anything absent from them. Deriving that narrowing rather than hand-maintaining a second list keeps this package in step with the linked module, whose contents depend on GOFIPS140 and may change across Go versions.

Under BoringCrypto (the golang-fips toolchain) crypto/fips140.Enabled reports false, because the OpenSSL backend is invisible to crypto/fips140. x/crypto applies no policy of its own there, so nothing narrows the result.

This package is separate from gitlab.com/gitlab-org/labkit/v2/fips so that services which only need to report their FIPS posture do not take on a golang.org/x/crypto dependency.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultAlgorithms

func DefaultAlgorithms(_ ...Option) ssh.Algorithms

DefaultAlgorithms returns the algorithms enabled by default. No FIPS policy is applied; only empty names are dropped (see dropAlgorithms).

Options are accepted and ignored, as in SupportedAlgorithms.

PublicKeyAuths is left empty here, unlike in a fips build. ssh.NewServerConn then substitutes its own default, which is what a non-FIPS server offers today; restricting it would drop ssh-rsa for deployments that have made no FIPS commitment.

func HostKeySigner added in v2.35.0

func HostKeySigner(signer ssh.Signer) (ssh.Signer, error)

HostKeySigner returns signer unchanged. Without the fips build tag there is no signature algorithm policy to enforce, so callers can wrap every host key unconditionally and let the build tag decide.

func SupportedAlgorithms

func SupportedAlgorithms(_ ...Option) ssh.Algorithms

SupportedAlgorithms returns the algorithms currently implemented by Go's SSH package. No FIPS policy is applied; only empty names are dropped (see dropAlgorithms).

Options are accepted and ignored. Without the fips build tag there is no policy to adjust, so callers can pass them unconditionally and let the build tag decide.

Types

type Option added in v2.35.0

type Option func(*options)

Option adjusts the algorithm sets returned by SupportedAlgorithms and DefaultAlgorithms.

Options are variadic so both functions stay backward compatible as the policy grows. A nil Option is ignored.

func WithoutDeprecated added in v2.35.0

func WithoutDeprecated() Option

WithoutDeprecated excludes the algorithms that FIPS 140-3 still approves but that are not part of GitLab's hardened baseline. Two groups qualify, for two different reasons:

  • The SHA-1 constructions hmac-sha1, hmac-sha1-96 and diffie-hellman-group14-sha1. HMAC-SHA-1 is an approved MAC (SP 800-140C Rev. 2, via FIPS 198-1), 96-bit truncation is permitted by SP 800-107 Rev. 1 Section 5.3.4, and SHA-1 in the SSH KDF is permitted by SP 800-135 Rev. 1 Section 5.2. SP 800-131A deprecates SHA-1 for non-signature protection through 2030-12-31, and disallows it after.
  • Finite-field Diffie-Hellman: diffie-hellman-group14-sha256, diffie-hellman-group16-sha512 and diffie-hellman-group-exchange-sha256. The groups themselves are approved safe primes (SP 800-56A Rev. 3 Appendix D), but x/crypto/ssh computes them with math/big in pure Go, so the implementation sits outside every validated module boundary. The native Go Cryptographic Module does not implement finite-field Diffie-Hellman at all, so this group is already absent there.

Both groups are offered by default, because removing them is a compatibility break rather than a compliance requirement: it stops clients too old to offer HMAC-SHA-2 or ECDH. Pass this option when the deployment can require modern clients and wants every offered algorithm inside a validated boundary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL