{"record":{"id":"ce7c2f2ef45cb539","repo":"golang/go","slug":"crypto-cipher-use-of-gcm-with-arbitrary-ivs-is-no","errorCode":null,"errorMessage":"crypto/cipher: use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, use NewGCMWithRandomNonce","messagePattern":"crypto/cipher: use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode, use NewGCMWithRandomNonce","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/cipher/gcm.go","lineNumber":28,"sourceCode":"\t\"crypto/internal/fips140/alias\"\n\t\"crypto/internal/fips140only\"\n\t\"crypto/subtle\"\n\t\"errors\"\n\t\"internal/byteorder\"\n)\n\nconst (\n\tgcmBlockSize         = 16\n\tgcmStandardNonceSize = 12\n\tgcmTagSize           = 16\n\tgcmMinimumTagSize    = 12 // NIST SP 800-38D recommends tags with 12 or more bytes.\n)\n\n// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode\n// with the standard nonce length.\nfunc NewGCM(cipher Block) (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, gcmTagSize)\n}\n\n// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois\n// Counter Mode, which accepts nonces of the given length. The length must not\n// be zero.\n//\n// Only use this function if you require compatibility with an existing\n// cryptosystem that uses non-standard nonce lengths. All other users should use\n// [NewGCM], which is faster and more resistant to misuse.\nfunc NewGCMWithNonceSize(cipher Block, size 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, size, gcmTagSize)\n}\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/cipher/gcm.go#L10-L46","documentation":"When FIPS 140-only mode is enforced (the toolchain was built with GOEXPERIMENT=fips140 and the process opted in via GOFIPS=1, or the fips140-only toggle is otherwise active), cipher.NewGCM refuses to construct a GCM AEAD with caller-controlled nonces. FIPS 140-3 guidance requires either random nonces or a counter-based construction, supplied by NewGCMWithRandomNonce.","triggerScenarios":"Calling cipher.NewGCM(block) while fips140only.Enforced() returns true. The check fires before any AEAD is allocated, so the error is returned directly from the constructor.","commonSituations":"Running a Go FIPS build in a regulated environment (US federal, healthcare, finance), upgrading a service that previously used arbitrary-IV GCM to a FIPS-only toolchain, or shipping a binary in a container whose base image set GOFIPS=1.","solutions":["Switch to cipher.NewGCMWithRandomNonce(block), which generates a random 96-bit nonce per Seal call.","If you need deterministic encryption for compatibility, run the binary with FIPS-only mode disabled (GOFIPS=0 or do not opt in) — but verify this is acceptable to your compliance posture.","Refactor wire formats that previously transmitted nonce separately so they accept the prepended-random-nonce layout produced by NewGCMWithRandomNonce.","If you must keep arbitrary IVs for protocol compatibility, document a compensating control (e.g., a separate audit log) per your FIPS security policy."],"exampleFix":"// before\na, err := cipher.NewGCM(block) // fails in FIPS-only mode\n\n// after\na, err := cipher.NewGCMWithRandomNonce(block)\nif err != nil { return err }\nct := a.Seal(nil, nil, plaintext, nil) // nonce generated + prepended","handlingStrategy":"type-guard","validationCode":"// Decide at construction time based on whether FIPS-only mode is on.\n// (You usually know this from build/deploy flags.)\nfunc newAEAD(block cipher.Block) (cipher.AEAD, error) {\n    if fipsEnabled() {\n        return cipher.NewGCMWithRandomNonce(block)\n    }\n    return cipher.NewGCM(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 {\n    if strings.Contains(err.Error(), \"FIPS 140-only mode\") {\n        a, err = cipher.NewGCMWithRandomNonce(block)\n        if err != nil { return err }\n    } else {\n        return err\n    }\n}","preventionTips":["Standardize on NewGCMWithRandomNonce for FIPS-targeted builds.","Document the deployment's FIPS posture in CI configuration.","Refactor wire formats to accept the prepended-random-nonce layout."],"tags":["crypto","aes","gcm","fips","compliance","nonce"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}