{"record":{"id":"dd94a3f340a73f1d","repo":"golang/go","slug":"crypto-rsa-input-must-be-hashed-with-given-hash","errorCode":null,"errorMessage":"crypto/rsa: input must be hashed with given hash","messagePattern":"crypto/rsa: input must be hashed with given hash","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/rsa/pkcs1v22.go","lineNumber":86,"sourceCode":"\t\tincCounter(&counter)\n\t}\n}\n\nfunc emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {\n\t// See RFC 8017, Section 9.1.1.\n\n\thLen := hash.Size()\n\tsLen := len(salt)\n\temLen := (emBits + 7) / 8\n\n\t// 1.  If the length of M is greater than the input limitation for the\n\t//     hash function (2^61 - 1 octets for SHA-1), output \"message too\n\t//     long\" and stop.\n\t//\n\t// 2.  Let mHash = Hash(M), an octet string of length hLen.\n\n\tif len(mHash) != hLen {\n\t\treturn nil, errors.New(\"crypto/rsa: input must be hashed with given hash\")\n\t}\n\n\t// 3.  If emLen < hLen + sLen + 2, output \"encoding error\" and stop.\n\n\tif emLen < hLen+sLen+2 {\n\t\treturn nil, ErrMessageTooLong\n\t}\n\n\tem := make([]byte, emLen)\n\tpsLen := emLen - sLen - hLen - 2\n\tdb := em[:psLen+1+sLen]\n\th := em[psLen+1+sLen : emLen-1]\n\n\t// 4.  Generate a random octet string salt of length sLen; if sLen = 0,\n\t//     then salt is the empty string.\n\t//\n\t// 5.  Let\n\t//       M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/rsa/pkcs1v22.go#L68-L104","documentation":"In RSASSA-PSS encoding (emsa_pss_encode), the mHash (message digest) must be exactly hLen bytes, where hLen is hash.Size() for the hash function passed to SignPSS. This check ensures the caller actually hashed the message with the specified algorithm before PSS padding is applied. A length mismatch indicates a protocol or caller error.","triggerScenarios":"Calling rsa.SignPSS with a hashed slice whose length does not equal hash.Size() — e.g., passing a 32-byte SHA-256 digest but with a SHA-512 hash.Hash instance, or passing a truncated digest.","commonSituations":"Mismatch between the hash.Hash instance and the actual digest bytes (common when refactoring hash algorithms); passing a pre-computed digest from a different hash function; accidentally passing the raw message instead of its hash.","solutions":["Ensure the hash.Hash passed to SignPSS is the same one used to compute the digest","Verify len(hashed) == hash.Size() before calling SignPSS","Use a helper that both hashes and signs in one step to avoid the mismatch"],"exampleFix":"// before\nhash := sha512.New()\nhash.Write(msg)\ndigest := sha256.Sum256(msg) // wrong hash!\nsig, err := rsa.SignPSS(rand, key, hash, digest[:], nil)\n\n// after\nhash := sha256.New()\nhash.Write(msg)\nsig, err := rsa.SignPSS(rand, key, crypto.SHA256, hash.Sum(nil), nil)","handlingStrategy":"validation","validationCode":"func validatePSSDigest(hash crypto.Hash, digest []byte) error {\n    if len(digest) != hash.Size() {\n        return fmt.Errorf(\"PSS digest length %d != %v size %d\", len(digest), hash, hash.Size())\n    }\n    return nil\n}\n\nif err := validatePSSDigest(hashAlg, digest); err != nil { return err }\nsig, err := rsa.SignPSS(rand, key, hashAlg, digest, nil)","typeGuard":null,"tryCatchPattern":"sig, err := rsa.SignPSS(rand, key, hashAlg, hashed, nil)\nif err != nil {\n    return fmt.Errorf(\"PSS signing failed (check hash/digest match): %w\", err)\n}","preventionTips":["Use the same hash.Hash instance for both SignPSS and computing the digest","Verify len(hashed) == hash.Size() before signing","Create a single helper that hashes-and-signs to eliminate the mismatch surface"],"tags":["crypto","fips140","rsa","pss","hash-mismatch","input-validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}