@@ -8,13 +8,15 @@ import (
88 "crypto/aes"
99 "crypto/cipher"
1010 "crypto/des"
11+ "crypto/fips140"
1112 "crypto/rc4"
1213 "crypto/subtle"
1314 "encoding/binary"
1415 "errors"
1516 "fmt"
1617 "hash"
1718 "io"
19+ "slices"
1820
1921 "golang.org/x/crypto/chacha20"
2022 "golang.org/x/crypto/internal/poly1305"
@@ -93,41 +95,41 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
9395}
9496
9597// cipherModes documents properties of supported ciphers. Ciphers not included
96- // are not supported and will not be negotiated, even if explicitly requested in
97- // ClientConfig.Crypto.Ciphers.
98- var cipherModes = map [string ]* cipherMode {
99- // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
100- // are defined in the order specified in the RFC.
101- CipherAES128CTR : {16 , aes .BlockSize , streamCipherMode (0 , newAESCTR )},
102- CipherAES192CTR : {24 , aes .BlockSize , streamCipherMode (0 , newAESCTR )},
103- CipherAES256CTR : {32 , aes .BlockSize , streamCipherMode (0 , newAESCTR )},
104-
105- // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
106- // They are defined in the order specified in the RFC.
107- InsecureCipherRC4128 : {16 , 0 , streamCipherMode (1536 , newRC4 )},
108- InsecureCipherRC4256 : {32 , 0 , streamCipherMode (1536 , newRC4 )},
109-
110- // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
111- // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
112- // RC4) has problems with weak keys, and should be used with caution."
113- // RFC 4345 introduces improved versions of Arcfour.
114- InsecureCipherRC4 : {16 , 0 , streamCipherMode (0 , newRC4 )},
115-
116- // AEAD ciphers
117- CipherAES128GCM : {16 , 12 , newGCMCipher },
118- CipherAES256GCM : {32 , 12 , newGCMCipher },
119- CipherChaCha20Poly1305 : {64 , 0 , newChaCha20Cipher },
120-
98+ // are not supported and will not be negotiated, even if explicitly configured.
99+ // When FIPS mode is enabled, only FIPS-approved algorithms are included.
100+ var cipherModes = map [string ]* cipherMode {}
101+
102+ func init () {
103+ cipherModes [CipherAES128CTR ] = & cipherMode {16 , aes .BlockSize , streamCipherMode (0 , newAESCTR )}
104+ cipherModes [CipherAES192CTR ] = & cipherMode {24 , aes .BlockSize , streamCipherMode (0 , newAESCTR )}
105+ cipherModes [CipherAES256CTR ] = & cipherMode {32 , aes .BlockSize , streamCipherMode (0 , newAESCTR )}
106+ // Use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode,
107+ // we'll wire it up to NewGCMForSSH in Go 1.26.
108+ //
109+ // For now it means we'll work with fips140=on but not fips140=only.
110+ cipherModes [CipherAES128GCM ] = & cipherMode {16 , 12 , newGCMCipher }
111+ cipherModes [CipherAES256GCM ] = & cipherMode {32 , 12 , newGCMCipher }
112+
113+ if fips140 .Enabled () {
114+ defaultCiphers = slices .DeleteFunc (defaultCiphers , func (algo string ) bool {
115+ _ , ok := cipherModes [algo ]
116+ return ! ok
117+ })
118+ return
119+ }
120+
121+ cipherModes [CipherChaCha20Poly1305 ] = & cipherMode {64 , 0 , newChaCha20Cipher }
122+ // Insecure ciphers not included in the default configuration.
123+ cipherModes [InsecureCipherRC4128 ] = & cipherMode {16 , 0 , streamCipherMode (1536 , newRC4 )}
124+ cipherModes [InsecureCipherRC4256 ] = & cipherMode {32 , 0 , streamCipherMode (1536 , newRC4 )}
125+ cipherModes [InsecureCipherRC4 ] = & cipherMode {16 , 0 , streamCipherMode (0 , newRC4 )}
121126 // CBC mode is insecure and so is not included in the default config.
122127 // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely
123128 // needed, it's possible to specify a custom Config to enable it.
124129 // You should expect that an active attacker can recover plaintext if
125130 // you do.
126- InsecureCipherAES128CBC : {16 , aes .BlockSize , newAESCBCCipher },
127-
128- // 3des-cbc is insecure and is not included in the default
129- // config.
130- InsecureCipherTripleDESCBC : {24 , des .BlockSize , newTripleDESCBCCipher },
131+ cipherModes [InsecureCipherAES128CBC ] = & cipherMode {16 , aes .BlockSize , newAESCBCCipher }
132+ cipherModes [InsecureCipherTripleDESCBC ] = & cipherMode {24 , des .BlockSize , newTripleDESCBCCipher }
131133}
132134
133135// prefixLen is the length of the packet prefix that contains the packet length
0 commit comments