{"record":{"id":"027f97e3880e7d5b","repo":"golang/go","slug":"pbkdf2-keylength-too-long","errorCode":null,"errorMessage":"pbkdf2: keyLength too long","messagePattern":"pbkdf2: keyLength too long","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/pbkdf2/pbkdf2.go","lineNumber":36,"sourceCode":"// of the integer size.\nfunc divRoundUp(x, y int) int {\n\treturn int((int64(x) + int64(y) - 1) / int64(y))\n}\n\nfunc Key[Hash hash.Hash](h func() Hash, password string, salt []byte, iter, keyLength int) ([]byte, error) {\n\tsetServiceIndicator(salt, keyLength)\n\n\tif keyLength <= 0 {\n\t\treturn nil, errors.New(\"pbkdf2: keyLength must be larger than 0\")\n\t}\n\n\tprf := hmac.New(h, []byte(password))\n\thmac.MarkAsUsedInKDF(prf)\n\thashLen := prf.Size()\n\tnumBlocks := divRoundUp(keyLength, hashLen)\n\tconst maxBlocks = int64(1<<32 - 1)\n\tif keyLength+hashLen < keyLength || int64(numBlocks) > maxBlocks {\n\t\treturn nil, errors.New(\"pbkdf2: keyLength too long\")\n\t}\n\n\tvar buf [4]byte\n\tdk := make([]byte, 0, numBlocks*hashLen)\n\tU := make([]byte, hashLen)\n\tfor block := 1; block <= numBlocks; block++ {\n\t\t// N.B.: || means concatenation, ^ means XOR\n\t\t// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter\n\t\t// U_1 = PRF(password, salt || uint(i))\n\t\tprf.Reset()\n\t\tprf.Write(salt)\n\t\tbuf[0] = byte(block >> 24)\n\t\tbuf[1] = byte(block >> 16)\n\t\tbuf[2] = byte(block >> 8)\n\t\tbuf[3] = byte(block)\n\t\tprf.Write(buf[:4])\n\t\tdk = prf.Sum(dk)\n\t\tT := dk[len(dk)-hashLen:]","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/pbkdf2/pbkdf2.go#L18-L54","documentation":"PBKDF2 rejects keyLength values that are unreasonably large. Two conditions trigger this: integer overflow detected via keyLength + hashLen < keyLength (signed wraparound), or numBlocks = ceil(keyLength / hashLen) exceeding 2^32 - 1 (the maximum block counter, since the block index is a 32-bit big-endian integer in the PRF input).","triggerScenarios":"Calling Key() with a very large keyLength — near INT_MAX, negative-when-cast, or requiring more than 2^32 - 1 hash-sized blocks to fill.","commonSituations":"keyLength read from an untrusted 64-bit field without clamping; a bug where a byte count and a bit count are confused (multiplying by 8); a configuration typo using an extremely large number.","solutions":["Clamp keyLength to a reasonable maximum (e.g., 64 * hashLen) before calling Key()","Validate keyLength against the formula: keyLength <= (2^32 - 1) * hashLen","Audit where keyLength originates — it should be a small, well-known constant like 16, 32, or 64"],"exampleFix":"// before\ndk, err := pbkdf2.Key(sha256.New, password, salt, iter, requestedLen)\n\n// after\nmaxKeyLen := (1<<32 - 1) * sha256.New().Size()\nif requestedLen > maxKeyLen {\n    return nil, fmt.Errorf(\"keyLength %d exceeds maximum %d\", requestedLen, maxKeyLen)\n}\ndk, err := pbkdf2.Key(sha256.New, password, salt, iter, requestedLen)","handlingStrategy":"validation","validationCode":"func validatePbkdf2KeyLength(keyLen, hashLen int) error {\n    if keyLen <= 0 {\n        return fmt.Errorf(\"keyLength must be positive\")\n    }\n    maxBlocks := int64(1<<32 - 1)\n    numBlocks := int64((int64(keyLen) + int64(hashLen) - 1) / int64(hashLen))\n    if numBlocks > maxBlocks {\n        return fmt.Errorf(\"keyLength %d too large\", keyLen)\n    }\n    return nil\n}\n\nhashLen := sha256.New().Size()\nif err := validatePbkdf2KeyLength(keyLen, hashLen); err != nil { return err }\ndk, err := pbkdf2.Key(sha256.New, password, salt, iter, keyLen)","typeGuard":null,"tryCatchPattern":"dk, err := pbkdf2.Key(h, password, salt, iter, keyLen)\nif err != nil {\n    return fmt.Errorf(\"PBKDF2 key derivation failed: %w\", err)\n}","preventionTips":["keyLength should be a small known constant (16, 32, 64), not a computed large value","Audit where keyLength originates — clamp untrusted input to a reasonable maximum","Watch for byte/bit confusion (multiplying by 8) when deriving key sizes"],"tags":["crypto","fips140","pbkdf2","kdf","overflow","input-validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}