{"record":{"id":"3fd4fdc41d018c18","repo":"golang/go","slug":"crypto-md5-use-of-md5-is-not-allowed-in-fips-140","errorCode":null,"errorMessage":"crypto/md5: use of MD5 is not allowed in FIPS 140-only mode","messagePattern":"crypto/md5: use of MD5 is not allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/md5/md5.go","lineNumber":128,"sourceCode":"}\n\n// New returns a new [hash.Hash] computing the MD5 checksum. The Hash\n// also implements [encoding.BinaryMarshaler], [encoding.BinaryAppender] and\n// [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal\n// state of the hash.\nfunc New() hash.Hash {\n\td := new(digest)\n\td.Reset()\n\treturn d\n}\n\nfunc (d *digest) Size() int { return Size }\n\nfunc (d *digest) BlockSize() int { return BlockSize }\n\nfunc (d *digest) Write(p []byte) (nn int, err error) {\n\tif fips140only.Enforced() {\n\t\treturn 0, errors.New(\"crypto/md5: use of MD5 is not allowed in FIPS 140-only mode\")\n\t}\n\t// Note that we currently call block or blockGeneric\n\t// directly (guarded using haveAsm) because this allows\n\t// escape analysis to see that p and d don't escape.\n\tnn = len(p)\n\td.len += uint64(nn)\n\tif d.nx > 0 {\n\t\tn := copy(d.x[d.nx:], p)\n\t\td.nx += n\n\t\tif d.nx == BlockSize {\n\t\t\tif haveAsm {\n\t\t\t\tblock(d, d.x[:])\n\t\t\t} else {\n\t\t\t\tblockGeneric(d, d.x[:])\n\t\t\t}\n\t\t\td.nx = 0\n\t\t}\n\t\tp = p[n:]","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/md5/md5.go#L110-L146","documentation":"Returned by md5 digest.Write when fips140only.Enforced() is true. In FIPS 140-only mode (GOFIPS=1 with a certified module, or the gofips build tag) the runtime blocks non-approved algorithms: MD5 is not on the FIPS 140 approved list, so any data written to an MD5 digest is rejected. The error is returned from Write, so streaming hashing fails immediately on the first Write call.","triggerScenarios":"Calling md5.New() and then Write on the returned hash while the binary is running with FIPS-only enforcement enabled (GOFIPS=1 environment variable pointing at a validated module, or built with the gofips build tag). The first Write returns (0, error).","commonSituations":"Legacy/deprecated code paths still using MD5 for checksums, ETags, cache keys, or non-cryptographic fingerprints being deployed into a FIPS-required environment (banking, healthcare, US federal); a transitive dependency (e.g. an old HTTP library) computing MD5 internally; CI vs production divergence where CI lacks the FIPS module.","solutions":["Migrate the call site to SHA-256 (or SHA-512) — the FIPS-approved replacement.","If MD5 is genuinely needed only as a non-cryptographic checksum, gate it behind a build tag that is never set in FIPS-only deployments, or vendor a non-FIPS md5 implementation.","Verify the deployment actually needs FIPS-only mode (GOFIPS=1 vs GOFIPS=0); if FIPS-available (not only) is sufficient, MD5 works.","Audit transitive dependencies for hidden MD5 usage (grep for crypto/md5 in go.sum/go.mod)."],"exampleFix":"// before\nh := md5.New()\nio.Copy(h, file) // -> error in FIPS-only mode\n// after\nh := sha256.New()\nio.Copy(h, file)","handlingStrategy":"validation","validationCode":"func isFIPSOnlyEnforced() bool { return fips140only.Enforced() }\n\n// guard before MD5 writes:\nif fips140only.Enforced() {\n    return errors.New(\"MD5 unavailable in FIPS-only mode; use SHA-256\")\n}\nh := md5.New()\nio.Copy(h, file)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Migrate MD5 call sites to SHA-256 before deploying into FIPS-required environments.","Confirm whether the deployment needs FIPS-only (GOFIPS=1) or FIPS-available mode.","Audit go.sum/go.mod for transitive crypto/md5 dependencies.","Gate legacy MD5 checksums behind a non-FIPS build tag."],"tags":["crypto","md5","fips","compliance","go-stdlib"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}