{"record":{"id":"9cbe975cdc23da1f","repo":"golang/go","slug":"cipher-newgcm-requires-128-bit-block-cipher-9cbe97","errorCode":null,"errorMessage":"cipher: NewGCM requires 128-bit block cipher","messagePattern":"cipher: NewGCM requires 128-bit block cipher","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/aes/gcm/gcm.go","lineNumber":39,"sourceCode":"\nfunc New(cipher *aes.Block, nonceSize, tagSize int) (*GCM, error) {\n\t// This function is outlined to let the allocation happen on the parent stack.\n\treturn newGCM(&GCM{}, cipher, nonceSize, tagSize)\n}\n\n// newGCM is marked go:noinline to avoid it inlining into New, and making New\n// too complex to inline itself.\n//\n//go:noinline\nfunc newGCM(g *GCM, cipher *aes.Block, nonceSize, tagSize int) (*GCM, error) {\n\tif tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize {\n\t\treturn nil, errors.New(\"cipher: incorrect tag size given to GCM\")\n\t}\n\tif nonceSize <= 0 {\n\t\treturn nil, errors.New(\"cipher: the nonce can't have zero length\")\n\t}\n\tif cipher.BlockSize() != gcmBlockSize {\n\t\treturn nil, errors.New(\"cipher: NewGCM requires 128-bit block cipher\")\n\t}\n\tg.cipher = *cipher\n\tg.nonceSize = nonceSize\n\tg.tagSize = tagSize\n\tinitGCM(g)\n\treturn g, nil\n}\n\nconst (\n\tgcmBlockSize         = 16\n\tgcmTagSize           = 16\n\tgcmMinimumTagSize    = 12 // NIST SP 800-38D recommends tags with 12 or more bytes.\n\tgcmStandardNonceSize = 12\n)\n\nfunc (g *GCM) NonceSize() int {\n\treturn g.nonceSize\n}","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/aes/gcm/gcm.go#L21-L57","documentation":"Returned by gcm.New when cipher.BlockSize() != gcmBlockSize (16). GCM is only defined over a 128-bit block cipher, i.e. AES. Passing a non-AES block cipher (e.g. a hypothetical 64-bit block cipher) is rejected at construction.","triggerScenarios":"Calling gcm.New(cipher, ...) where cipher is an aes.Block whose BlockSize() is not 16; in practice this fires when the constructor is wired to a malformed or stub Block implementation.","commonSituations":"Unit tests with a fake/mock block cipher that returns the wrong BlockSize; future 256-bit-block ciphers passed through the same constructor; corruption of the aes.Block wrapper.","solutions":["Ensure the cipher passed in is a real crypto/aes block (aes.NewCipher produces a 16-byte block).","In tests, make any stub Block return BlockSize()==16.","Construct the AES cipher via aes.NewCipher(key) before passing to NewGCM."],"exampleFix":"// before\naead, err := gcm.New(fakeBlock, 12, 16) // fakeBlock.BlockSize()==8\n// after\nblock, _ := aes.NewCipher(key)\naead, err := cipher.NewGCM(block)","handlingStrategy":"validation","validationCode":"func validGCMBlock(b cipher.Block) bool { return b.BlockSize() == 16 }\n\nblock, err := aes.NewCipher(key)\nif err != nil { return err }\nif !validGCMBlock(block) { return errors.New(\"GCM requires a 128-bit block cipher\") }","typeGuard":"// n/a","tryCatchPattern":"aead, err := cipher.NewGCM(block)\nif err != nil { return fmt.Errorf(\"gcm init: %w\", err) }","preventionTips":["Always construct the block cipher via aes.NewCipher.","Ensure test stubs return BlockSize()==16.","Do not wrap non-AES ciphers through GCM."],"tags":["crypto","aes","gcm","cipher","fips","validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}