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