1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package pbkdf2
6 7 import (
8 "crypto/internal/fips140"
9 "crypto/internal/fips140/hmac"
10 "errors"
11 "hash"
12 )
13 14 // divRoundUp divides x+y-1 by y, rounding up if the result is not whole.
15 // This function casts x and y to int64 in order to avoid cases where
16 // x+y would overflow int on systems where int is an int32. The result
17 // is an int, which is safe as (x+y-1)/y should always fit, regardless
18 // of the integer size.
19 func divRoundUp(x, y int) int {
20 return int((int64(x) + int64(y) - 1) / int64(y))
21 }
22 23 func Key[Hash hash.Hash](h func() Hash, password []byte, salt []byte, iter, keyLength int) ([]byte, error) {
24 setServiceIndicator(salt, keyLength)
25 26 if keyLength <= 0 {
27 return nil, errors.New("pkbdf2: keyLength must be larger than 0")
28 }
29 30 prf := hmac.New(h, password)
31 hmac.MarkAsUsedInKDF(prf)
32 hashLen := prf.Size()
33 numBlocks := divRoundUp(keyLength, hashLen)
34 const maxBlocks = int64(1<<32 - 1)
35 if keyLength+hashLen < keyLength || int64(numBlocks) > maxBlocks {
36 return nil, errors.New("pbkdf2: keyLength too long")
37 }
38 39 var buf [4]byte
40 dk := []byte{:0:numBlocks*hashLen}
41 U := []byte{:hashLen}
42 for block := 1; block <= numBlocks; block++ {
43 // N.B.: || means concatenation, ^ means XOR
44 // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
45 // U_1 = PRF(password, salt || uint(i))
46 prf.Reset()
47 prf.Write(salt)
48 buf[0] = byte(block >> 24)
49 buf[1] = byte(block >> 16)
50 buf[2] = byte(block >> 8)
51 buf[3] = byte(block)
52 prf.Write(buf[:4])
53 dk = prf.Sum(dk)
54 T := dk[len(dk)-hashLen:]
55 copy(U, T)
56 57 // U_n = PRF(password, U_(n-1))
58 for n := 2; n <= iter; n++ {
59 prf.Reset()
60 prf.Write(U)
61 U = U[:0]
62 U = prf.Sum(U)
63 for x := range U {
64 T[x] ^= U[x]
65 }
66 }
67 }
68 return dk[:keyLength], nil
69 }
70 71 func setServiceIndicator(salt []byte, keyLength int) {
72 // The HMAC construction will handle the hash function considerations for the service
73 // indicator. The remaining PBKDF2 considerations outlined by SP 800-132 pertain to
74 // salt and keyLength.
75 76 // The length of the randomly-generated portion of the salt shall be at least 128 bits.
77 if len(salt) < 128/8 {
78 fips140.RecordNonApproved()
79 }
80 81 // Per FIPS 140-3 IG C.M, key lengths below 112 bits are only allowed for
82 // legacy use (i.e. verification only) and we don't support that.
83 if keyLength < 112/8 {
84 fips140.RecordNonApproved()
85 }
86 87 fips140.RecordApproved()
88 }
89