{"record":{"id":"b72fbde324c84134","repo":"golang/go","slug":"pbkdf2-keylength-must-be-larger-than-0","errorCode":null,"errorMessage":"pbkdf2: keyLength must be larger than 0","messagePattern":"pbkdf2: keyLength must be larger than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/pbkdf2/pbkdf2.go","lineNumber":27,"sourceCode":"\t\"crypto/internal/fips140/hmac\"\n\t\"errors\"\n\t\"hash\"\n)\n\n// divRoundUp divides x+y-1 by y, rounding up if the result is not whole.\n// This function casts x and y to int64 in order to avoid cases where\n// x+y would overflow int on systems where int is an int32. The result\n// is an int, which is safe as (x+y-1)/y should always fit, regardless\n// 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))","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/pbkdf2/pbkdf2.go#L9-L45","documentation":"The PBKDF2 key derivation function requires a strictly positive keyLength. A keyLength of zero or negative makes no sense for deriving a key and would produce an empty output, so it is rejected before any computation. This is the first validation check in the Key() function.","triggerScenarios":"Calling pbkdf2.Key(...) with keyLength <= 0 — typically keyLength == 0.","commonSituations":"keyLength computed from a configuration value that defaults to 0 when unset; integer underflow in a derived length calculation; a bug where a key-size constant is read from a struct field that was never initialized.","solutions":["Validate keyLength > 0 before calling Key()","Set a sensible default key length (e.g., 32 for AES-256) in configuration","Check that the configuration source for key length is populated"],"exampleFix":"// before\ndk, err := pbkdf2.Key(sha256.New, password, salt, iter, keyLen)\n\n// after\nif keyLen <= 0 {\n    return nil, fmt.Errorf(\"keyLength must be positive, got %d\", keyLen)\n}\ndk, err := pbkdf2.Key(sha256.New, password, salt, iter, keyLen)","handlingStrategy":"validation","validationCode":"func validateKeyLength(keyLen int) error {\n    if keyLen <= 0 {\n        return fmt.Errorf(\"keyLength must be positive, got %d\", keyLen)\n    }\n    return nil\n}\n\nif err := validateKeyLength(keyLen); 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":["Set a default key length in configuration (e.g., 32 for AES-256)","Validate key length comes from a trusted source, not untrusted user input","Use named constants like 16, 32, 64 for key sizes rather than computed values"],"tags":["crypto","fips140","pbkdf2","kdf","input-validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}