{"record":{"id":"eabdd8d16cdc2186","repo":"golang/go","slug":"crypto-cipher-use-of-gcm-with-non-aes-ciphers-is","errorCode":null,"errorMessage":"crypto/cipher: use of GCM with non-AES ciphers is not allowed in FIPS 140-only mode","messagePattern":"crypto/cipher: use of GCM with non-AES ciphers is not allowed in FIPS 140-only mode","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/cipher/gcm.go","lineNumber":66,"sourceCode":"// Counter Mode, which generates tags with the given length.\n//\n// Tag sizes between 12 and 16 bytes are allowed.\n//\n// Only use this function if you require compatibility with an existing\n// cryptosystem that uses non-standard tag lengths. All other users should use\n// [NewGCM], which is more resistant to misuse.\nfunc NewGCMWithTagSize(cipher Block, tagSize int) (AEAD, error) {\n\tif fips140only.Enforced() {\n\t\treturn nil, errors.New(\"crypto/cipher: use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, use NewGCMWithRandomNonce\")\n\t}\n\treturn newGCM(cipher, gcmStandardNonceSize, tagSize)\n}\n\nfunc newGCM(cipher Block, nonceSize, tagSize int) (AEAD, error) {\n\tc, ok := cipher.(*aes.Block)\n\tif !ok {\n\t\tif fips140only.Enforced() {\n\t\t\treturn nil, errors.New(\"crypto/cipher: use of GCM with non-AES ciphers is not allowed in FIPS 140-only mode\")\n\t\t}\n\t\treturn newGCMFallback(cipher, nonceSize, tagSize)\n\t}\n\t// We don't return gcm.New directly, because it would always return a non-nil\n\t// AEAD interface value with type *gcm.GCM even if the *gcm.GCM is nil.\n\tg, err := gcm.New(c, nonceSize, tagSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn g, nil\n}\n\n// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter\n// Mode, with randomly-generated nonces. The cipher must have been created by\n// [crypto/aes.NewCipher].\n//\n// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,\n// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/cipher/gcm.go#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nblock, _ := des.NewCipher(key) // non-AES\na, err := cipher.NewGCM(block) // \"non-AES ciphers is not allowed\"\n\n// after\nblock, _ := aes.NewCipher(aesKey)\na, err := cipher.NewGCMWithRandomNonce(block)","handlingStrategy":"type-guard","validationCode":"func newAEADFIPS(block cipher.Block) (cipher.AEAD, error) {\n    if _, ok := block.(*aes.Block); !ok {\n        return nil, errors.New(\"FIPS GCM requires an *aes.Block; construct with aes.NewCipher\")\n    }\n    return cipher.NewGCMWithRandomNonce(block)\n}","typeGuard":"func isAESBlock(b cipher.Block) bool {\n    _, ok := b.(*aes.Block)\n    return ok\n}","tryCatchPattern":"a, err := cipher.NewGCM(block)\nif err != nil && strings.Contains(err.Error(), \"non-AES ciphers\") {\n    aesBlock, _ := aes.NewCipher(aesKey)\n    a, err = cipher.NewGCMWithRandomNonce(aesBlock)\n}","preventionTips":["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."],"tags":["crypto","aes","gcm","fips","compliance","type-assertion"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}