blob: 9df55eed4a240beb3cb9424a17b084000af7fdd7 [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001package crypto
2
3import (
4 "bytes"
5 "crypto/hmac"
6 "crypto/md5"
7 "hash"
8 "io"
9
10 "golang.org/x/crypto/md4"
11 "gopkg.in/jcmturner/gokrb5.v7/crypto/rfc3961"
12 "gopkg.in/jcmturner/gokrb5.v7/crypto/rfc4757"
13 "gopkg.in/jcmturner/gokrb5.v7/iana/chksumtype"
14 "gopkg.in/jcmturner/gokrb5.v7/iana/etypeID"
15)
16
17//http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java#ArcFourCrypto.encrypt%28byte%5B%5D%2Cint%2Cbyte%5B%5D%2Cbyte%5B%5D%2Cbyte%5B%5D%2Cint%2Cint%29
18
19// RC4HMAC implements Kerberos encryption type aes256-cts-hmac-sha1-96
20type RC4HMAC struct {
21}
22
23// GetETypeID returns the EType ID number.
24func (e RC4HMAC) GetETypeID() int32 {
25 return etypeID.RC4_HMAC
26}
27
28// GetHashID returns the checksum type ID number.
29func (e RC4HMAC) GetHashID() int32 {
30 return chksumtype.KERB_CHECKSUM_HMAC_MD5
31}
32
33// GetKeyByteSize returns the number of bytes for key of this etype.
34func (e RC4HMAC) GetKeyByteSize() int {
35 return 16
36}
37
38// GetKeySeedBitLength returns the number of bits for the seed for key generation.
39func (e RC4HMAC) GetKeySeedBitLength() int {
40 return e.GetKeyByteSize() * 8
41}
42
43// GetHashFunc returns the hash function for this etype.
44func (e RC4HMAC) GetHashFunc() func() hash.Hash {
45 return md5.New
46}
47
48// GetMessageBlockByteSize returns the block size for the etype's messages.
49func (e RC4HMAC) GetMessageBlockByteSize() int {
50 return 1
51}
52
53// GetDefaultStringToKeyParams returns the default key derivation parameters in string form.
54func (e RC4HMAC) GetDefaultStringToKeyParams() string {
55 return ""
56}
57
58// GetConfounderByteSize returns the byte count for confounder to be used during cryptographic operations.
59func (e RC4HMAC) GetConfounderByteSize() int {
60 return 8
61}
62
63// GetHMACBitLength returns the bit count size of the integrity hash.
64func (e RC4HMAC) GetHMACBitLength() int {
65 return md5.Size * 8
66}
67
68// GetCypherBlockBitLength returns the bit count size of the cypher block.
69func (e RC4HMAC) GetCypherBlockBitLength() int {
70 return 8 // doesn't really apply
71}
72
73// StringToKey returns a key derived from the string provided.
74func (e RC4HMAC) StringToKey(secret string, salt string, s2kparams string) ([]byte, error) {
75 return rfc4757.StringToKey(secret)
76}
77
78// RandomToKey returns a key from the bytes provided.
79func (e RC4HMAC) RandomToKey(b []byte) []byte {
80 r := bytes.NewReader(b)
81 h := md4.New()
82 io.Copy(h, r)
83 return h.Sum(nil)
84}
85
86// EncryptData encrypts the data provided.
87func (e RC4HMAC) EncryptData(key, data []byte) ([]byte, []byte, error) {
88 b, err := rfc4757.EncryptData(key, data, e)
89 return []byte{}, b, err
90}
91
92// EncryptMessage encrypts the message provided and concatenates it with the integrity hash to create an encrypted message.
93func (e RC4HMAC) EncryptMessage(key, message []byte, usage uint32) ([]byte, []byte, error) {
94 b, err := rfc4757.EncryptMessage(key, message, usage, false, e)
95 return []byte{}, b, err
96}
97
98// DecryptData decrypts the data provided.
99func (e RC4HMAC) DecryptData(key, data []byte) ([]byte, error) {
100 return rfc4757.DecryptData(key, data, e)
101}
102
103// DecryptMessage decrypts the message provided and verifies the integrity of the message.
104func (e RC4HMAC) DecryptMessage(key, ciphertext []byte, usage uint32) ([]byte, error) {
105 return rfc4757.DecryptMessage(key, ciphertext, usage, false, e)
106}
107
108// DeriveKey derives a key from the protocol key based on the usage value.
109func (e RC4HMAC) DeriveKey(protocolKey, usage []byte) ([]byte, error) {
110 return rfc4757.HMAC(protocolKey, usage), nil
111}
112
113// DeriveRandom generates data needed for key generation.
114func (e RC4HMAC) DeriveRandom(protocolKey, usage []byte) ([]byte, error) {
115 return rfc3961.DeriveRandom(protocolKey, usage, e)
116}
117
118// VerifyIntegrity checks the integrity of the plaintext message.
119func (e RC4HMAC) VerifyIntegrity(protocolKey, ct, pt []byte, usage uint32) bool {
120 return rfc4757.VerifyIntegrity(protocolKey, pt, ct, e)
121}
122
123// GetChecksumHash returns a keyed checksum hash of the bytes provided.
124func (e RC4HMAC) GetChecksumHash(protocolKey, data []byte, usage uint32) ([]byte, error) {
125 return rfc4757.Checksum(protocolKey, usage, data)
126}
127
128// VerifyChecksum compares the checksum of the message bytes is the same as the checksum provided.
129func (e RC4HMAC) VerifyChecksum(protocolKey, data, chksum []byte, usage uint32) bool {
130 checksum, err := rfc4757.Checksum(protocolKey, usage, data)
131 if err != nil {
132 return false
133 }
134 return hmac.Equal(checksum, chksum)
135}