Skip to content

Commit

Permalink
rfc3962: revert to golang.org/x/crypto/pbkdf2 package
Browse files Browse the repository at this point in the history
limit the number of iterations when a zero string is provided on 32-bit systems to maxInt32 rather than 2^32
  • Loading branch information
jcmturner authored and yann-soubeyrand committed Jun 29, 2023
1 parent 67d3a7d commit dda0e81
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
2 changes: 1 addition & 1 deletion crypto/aes128-cts-hmac-sha1-96_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestAes128CtsHmacSha196_StringToKey(t *testing.T) {
b, _ = hex.DecodeString("f09d849e")
s2 := string(b)
var tests = []struct {
iterations int64
iterations int
phrase string
salt string
pbkdf2 string
Expand Down
2 changes: 1 addition & 1 deletion crypto/aes256-cts-hmac-sha1-96_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestAes256CtsHmacSha196_StringToKey(t *testing.T) {
b, _ = hex.DecodeString("f09d849e")
s2 := string(b)
var tests = []struct {
iterations int64
iterations int
phrase string
salt string
pbkdf2 string
Expand Down
28 changes: 20 additions & 8 deletions crypto/rfc3962/keyDerivation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"encoding/binary"
"encoding/hex"
"errors"
"math"
"strconv"

"github.com/jcmturner/gofork/x/crypto/pbkdf2"
"github.com/jcmturner/gokrb5/v9/crypto/etype"
"golang.org/x/crypto/pbkdf2"
)

const (
Expand All @@ -23,29 +25,39 @@ func StringToKey(secret, salt, s2kparams string, e etype.EType) ([]byte, error)
}

// StringToPBKDF2 generates an encryption key from a pass phrase and salt string using the PBKDF2 function from PKCS #5 v2.0
func StringToPBKDF2(secret, salt string, iterations int64, e etype.EType) []byte {
return pbkdf2.Key64([]byte(secret), []byte(salt), iterations, int64(e.GetKeyByteSize()), e.GetHashFunc())
func StringToPBKDF2(secret, salt string, iterations int, e etype.EType) []byte {
return pbkdf2.Key([]byte(secret), []byte(salt), iterations, e.GetKeyByteSize(), e.GetHashFunc())
}

// StringToKeyIter returns a key derived from the string provided according to the definition in RFC 3961.
func StringToKeyIter(secret, salt string, iterations int64, e etype.EType) ([]byte, error) {
func StringToKeyIter(secret, salt string, iterations int, e etype.EType) ([]byte, error) {
tkey := e.RandomToKey(StringToPBKDF2(secret, salt, iterations, e))
return e.DeriveKey(tkey, []byte("kerberos"))
}

// S2KparamsToItertions converts the string representation of iterations to an integer
func S2KparamsToItertions(s2kparams string) (int64, error) {
func S2KparamsToItertions(s2kparams string) (int, error) {
//The s2kparams string should be hex string representing 4 bytes
//The 4 bytes represent a number in big endian order
//If the value is zero then the number of iterations should be 4,294,967,296 (2^32)
//However for 32bit systems we use the max 32-bit integer value as 2^32 exceeds the max size of a 32-bit integer and
//the Go pbkdf2 package takes an int argument rather than an int64.
var i uint32
if len(s2kparams) != 8 {
return int64(s2kParamsZero), errors.New("invalid s2kparams length")
var zeroDefault int64 = math.MaxInt32
if strconv.IntSize > 32 {
zeroDefault = s2kParamsZero
}
return int(zeroDefault), errors.New("invalid s2kparams length")
}
b, err := hex.DecodeString(s2kparams)
if err != nil {
return int64(s2kParamsZero), errors.New("invalid s2kparams, cannot decode string to bytes")
var zeroDefault int64 = math.MaxInt32
if strconv.IntSize > 32 {
zeroDefault = s2kParamsZero
}
return int(zeroDefault), errors.New("invalid s2kparams, cannot decode string to bytes")
}
i = binary.BigEndian.Uint32(b)
return int64(i), nil
return int(i), nil
}

0 comments on commit dda0e81

Please sign in to comment.