{"record":{"id":"26613336200c68fe","repo":"golang/go","slug":"crypto-rsa-unsupported-hash-function-d","errorCode":null,"errorMessage":"crypto/rsa: unsupported hash function: %d","messagePattern":"crypto/rsa: unsupported hash function: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/boring/rsa.go","lineNumber":336,"sourceCode":"\nfunc SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {\n\tif h == 0 {\n\t\t// No hashing.\n\t\tvar out []byte\n\t\tvar outLen C.size_t\n\t\tif priv.withKey(func(key *C.GO_RSA) C.int {\n\t\t\tout = make([]byte, C._goboringcrypto_RSA_size(key))\n\t\t\treturn C._goboringcrypto_RSA_sign_raw(key, &outLen, base(out), C.size_t(len(out)),\n\t\t\t\tbase(hashed), C.size_t(len(hashed)), C.GO_RSA_PKCS1_PADDING)\n\t\t}) == 0 {\n\t\t\treturn nil, fail(\"RSA_sign_raw\")\n\t\t}\n\t\treturn out[:outLen], nil\n\t}\n\n\tmd := cryptoHashToMD(h)\n\tif md == nil {\n\t\treturn nil, errors.New(\"crypto/rsa: unsupported hash function: \" + strconv.Itoa(int(h)))\n\t}\n\tnid := C._goboringcrypto_EVP_MD_type(md)\n\tvar out []byte\n\tvar outLen C.uint\n\tif priv.withKey(func(key *C.GO_RSA) C.int {\n\t\tout = make([]byte, C._goboringcrypto_RSA_size(key))\n\t\treturn C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)),\n\t\t\tbase(out), &outLen, key)\n\t}) == 0 {\n\t\treturn nil, fail(\"RSA_sign\")\n\t}\n\treturn out[:outLen], nil\n}\n\nfunc VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {\n\tif h == 0 {\n\t\tvar out []byte\n\t\tvar outLen C.size_t","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/boring/rsa.go#L318-L354","documentation":"Thrown by the BoringCrypto backend of crypto/rsa when SignRSAPKCS1v15 is called with a crypto.Hash value that cryptoHashToMD does not map to a known BoringSSL EVP_MD. The integer value of the hash is appended so you can see exactly which crypto.Hash constant was rejected. It only fires on the BoringCrypto code path (GOEXPERIMENT=boringcrypto or a BoringCrypto-built Go toolchain).","triggerScenarios":"Calling rsa.SignPKCS1v15(priv, h, hashed) where h is not 0 and not one of crypto.MD5SHA1, crypto.SHA1, crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512, crypto.SHA512_224, crypto.SHA512_256 (the set cryptoHashToMD knows), while running with the BoringCrypto build.","commonSituations":"Passing a newer or uncommon crypto.Hash (e.g. SHA3, BLAKE2) to PKCS1v15 signing; passing a zero-valued-but-not-zero crypto.Hash variable; code that worked on the standard crypto/rsa backend but fails when the binary is built with BoringCrypto because BoringCrypto supports a smaller hash set.","solutions":["Check the numeric value reported in the message against the crypto.Hash constants in crypto.go and switch to one BoringCrypto supports (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, or the SHA-512 truncations).","If you need a hash BoringCrypto does not support, hash the data yourself with h==0 (raw signing) and pass the precomputed digest, or use a non-BoringCrypto build of Go.","Ensure you are not passing an uninitialized crypto.Hash variable (value 0 means 'no hash' and takes a different branch)."],"exampleFix":"// before\nsig, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.Hash(7), digest) // 7 is not supported\n// after\nsig, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, digest)","handlingStrategy":"validation","validationCode":"// allowed hashes on the BoringCrypto backend\nvar boringSupportedHashes = map[crypto.Hash]bool{\n    crypto.MD5SHA1: true, crypto.SHA1: true, crypto.SHA224: true,\n    crypto.SHA256: true, crypto.SHA384: true, crypto.SHA512: true,\n    crypto.SHA512_224: true, crypto.SHA512_256: true,\n}\nfunc canSignPKCS1v15(h crypto.Hash) bool { return h == 0 || boringSupportedHashes[h] }","typeGuard":"// n/a: crypto.Hash is an untyped int constant; guard with an allow-set check above.","tryCatchPattern":"sig, err := rsa.SignPKCS1v15(rand.Reader, priv, h, digest)\nif err != nil {\n    if strings.Contains(err.Error(), \"unsupported hash function\") {\n        // h not supported by current backend; fall back to a supported hash\n    }\n    return err\n}","preventionTips":["Validate the crypto.Hash against the BoringCrypto-supported set at config load.","Prefer crypto.SHA256 unless the protocol mandates another hash.","Avoid building with GOEXPERIMENT=boringcrypto unless FIPS-140 certification is required."],"tags":["crypto","rsa","boringcrypto","hash","signing"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}