1package rfc4757
2
3import (
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.
14func 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
35func 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}
41