golang/go · error
crypto/cipher: use of GCM with non-AES ciphers is not allowe
Error message
crypto/cipher: use of GCM with non-AES ciphers is not allowed in FIPS 140-only mode
What it means
Inside newGCM (the internal constructor shared by NewGCM/NewGCMWithNonceSize/NewGCMWithTagSize), a type assertion checks that cipher is *aes.Block. If it is not and FIPS-only mode is on, the constructor refuses: FIPS 140-3 only certifies AES-based GCM. The non-AES fallback (newGCMFallback) is unreachable in FIPS-only mode.
Source
Thrown at src/crypto/cipher/gcm.go:66
// Counter Mode, which generates tags with the given length.
//
// Tag sizes between 12 and 16 bytes are allowed.
//
// Only use this function if you require compatibility with an existing
// cryptosystem that uses non-standard tag lengths. All other users should use
// [NewGCM], which is more resistant to misuse.
func NewGCMWithTagSize(cipher Block, tagSize int) (AEAD, error) {
if fips140only.Enforced() {
return nil, errors.New("crypto/cipher: use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, use NewGCMWithRandomNonce")
}
return newGCM(cipher, gcmStandardNonceSize, tagSize)
}
func newGCM(cipher Block, nonceSize, tagSize int) (AEAD, error) {
c, ok := cipher.(*aes.Block)
if !ok {
if fips140only.Enforced() {
return nil, errors.New("crypto/cipher: use of GCM with non-AES ciphers is not allowed in FIPS 140-only mode")
}
return newGCMFallback(cipher, nonceSize, tagSize)
}
// We don't return gcm.New directly, because it would always return a non-nil
// AEAD interface value with type *gcm.GCM even if the *gcm.GCM is nil.
g, err := gcm.New(c, nonceSize, tagSize)
if err != nil {
return nil, err
}
return g, nil
}
// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter
// Mode, with randomly-generated nonces. The cipher must have been created by
// [crypto/aes.NewCipher].
//
// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,
// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,View on GitHub (pinned to b6b368adc5)
Solutions
- Construct the block with aes.NewCipher(key) so the value passed to NewGCM* is *aes.Block.
- Drop non-AES cipher support entirely — GCM is only NIST-approved for AES anyway.
- For test stubs, gate the non-AES path behind a build tag that disables FIPS-only in tests.
Example fix
// before block, _ := des.NewCipher(key) // non-AES a, err := cipher.NewGCM(block) // "non-AES ciphers is not allowed" // after block, _ := aes.NewCipher(aesKey) a, err := cipher.NewGCMWithRandomNonce(block)
Defensive patterns
Strategy: type-guard
Validate before calling
func newAEADFIPS(block cipher.Block) (cipher.AEAD, error) {
if _, ok := block.(*aes.Block); !ok {
return nil, errors.New("FIPS GCM requires an *aes.Block; construct with aes.NewCipher")
}
return cipher.NewGCMWithRandomNonce(block)
} Type guard
func isAESBlock(b cipher.Block) bool {
_, ok := b.(*aes.Block)
return ok
} Try / catch
a, err := cipher.NewGCM(block)
if err != nil && strings.Contains(err.Error(), "non-AES ciphers") {
aesBlock, _ := aes.NewCipher(aesKey)
a, err = cipher.NewGCMWithRandomNonce(aesBlock)
} Prevention
- Construct blocks via aes.NewCipher exclusively for FIPS-targeted code paths.
- Reject non-AES cipher.Block implementations at your crypto boundary.
- Keep instrumentation outside the cipher.Block value passed to GCM.
When it happens
Trigger: Calling any NewGCM* constructor with a Block that is not *aes.Block (e.g., a *des.NonceSize, a *camellia block, or a custom Block implementation) while FIPS-only mode is enforced. Reachable when a caller smuggles a non-AES block through the Block interface.
Common situations: Generic encryption wrappers that accept cipher.Block and feed it to NewGCM; legacy code paths that still construct DES/Blowfish blocks; testing stubs that implement Block but are not AES.
Related errors
- crypto/cipher: use of GCM with arbitrary IVs is not allowed
- cipher: NewGCMWithRandomNonce requires aes.Block
- crypto/aes: GCM tag and nonce sizes can't be non-standard at
- cipher: incorrect tag size given to GCM
- cipher: the nonce can't have zero length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/eabdd8d16cdc2186.
Report an issue: GitHub.