// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pbkdf2

import (
	
	
)

func [ fips140.Hash]( func() ,  string,  []byte, ,  int) ([]byte, error) {
	setServiceIndicator(, )

	 := hmac.New(, []byte())
	hmac.MarkAsUsedInKDF()
	 := .Size()
	 := ( +  - 1) / 

	var  [4]byte
	 := make([]byte, 0, *)
	 := make([]byte, )
	for  := 1;  <= ; ++ {
		// N.B.: || means concatenation, ^ means XOR
		// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
		// U_1 = PRF(password, salt || uint(i))
		.Reset()
		.Write()
		[0] = byte( >> 24)
		[1] = byte( >> 16)
		[2] = byte( >> 8)
		[3] = byte()
		.Write([:4])
		 = .Sum()
		 := [len()-:]
		copy(, )

		// U_n = PRF(password, U_(n-1))
		for  := 2;  <= ; ++ {
			.Reset()
			.Write()
			 = [:0]
			 = .Sum()
			for  := range  {
				[] ^= []
			}
		}
	}
	return [:], nil
}

func setServiceIndicator( []byte,  int) {
	// The HMAC construction will handle the hash function considerations for the service
	// indicator. The remaining PBKDF2 considerations outlined by SP 800-132 pertain to
	// salt and keyLength.

	// The length of the randomly-generated portion of the salt shall be at least 128 bits.
	if len() < 128/8 {
		fips140.RecordNonApproved()
	}

	// Per FIPS 140-3 IG C.M, key lengths below 112 bits are only allowed for
	// legacy use (i.e. verification only) and we don't support that.
	if  < 112/8 {
		fips140.RecordNonApproved()
	}

	fips140.RecordApproved()
}