github.com/jcmturner/gokrb5/v8@v8.4.4/crypto/rfc4757/keyDerivation.go (about)

     1  package rfc4757
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  
    10  	"golang.org/x/crypto/md4"
    11  )
    12  
    13  // StringToKey returns a key derived from the string provided according to the definition in RFC 4757.
    14  func StringToKey(secret string) ([]byte, error) {
    15  	b := make([]byte, len(secret)*2, len(secret)*2)
    16  	for i, r := range secret {
    17  		u := fmt.Sprintf("%04x", r)
    18  		c, err := hex.DecodeString(u)
    19  		if err != nil {
    20  			return []byte{}, errors.New("character could not be encoded")
    21  		}
    22  		// Swap round the two bytes to make little endian as we put into byte slice
    23  		b[2*i] = c[1]
    24  		b[2*i+1] = c[0]
    25  	}
    26  	r := bytes.NewReader(b)
    27  	h := md4.New()
    28  	_, err := io.Copy(h, r)
    29  	if err != nil {
    30  		return []byte{}, err
    31  	}
    32  	return h.Sum(nil), nil
    33  }
    34  
    35  func deriveKeys(key, checksum []byte, usage uint32, export bool) (k1, k2, k3 []byte) {
    36  	k1 = key
    37  	k2 = HMAC(k1, UsageToMSMsgType(usage))
    38  	k3 = HMAC(k2, checksum)
    39  	return
    40  }