forked from jcmturner/gokrb5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
des3-cbc-sha1-kd.go
174 lines (138 loc) · 5.64 KB
/
des3-cbc-sha1-kd.go
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package crypto
import (
"crypto/des"
"crypto/hmac"
"crypto/sha1"
"errors"
"hash"
"gopkg.in/jcmturner/gokrb5.v6/crypto/common"
"gopkg.in/jcmturner/gokrb5.v6/crypto/rfc3961"
"gopkg.in/jcmturner/gokrb5.v6/iana/chksumtype"
"gopkg.in/jcmturner/gokrb5.v6/iana/etypeID"
)
//RFC: 3961 Section 6.3
/*
des3-cbc-hmac-sha1-kd, hmac-sha1-des3-kd
------------------------------------------------
protocol key format 24 bytes, parity in low
bit of each
key-generation seed 21 bytes
length
hash function SHA-1
HMAC output size 160 bits
message block size 8 bytes
default string-to-key empty string
params
encryption and triple-DES encrypt and
decryption functions decrypt, in outer-CBC
mode (cipher block size
8 octets)
key generation functions:
random-to-key DES3random-to-key (see
below)
string-to-key DES3string-to-key (see
below)
The des3-cbc-hmac-sha1-kd encryption type is assigned the value
sixteen (16). The hmac-sha1-des3-kd checksum algorithm is assigned a
checksum type number of twelve (12)*/
// Des3CbcSha1Kd implements Kerberos encryption type des3-cbc-hmac-sha1-kd
type Des3CbcSha1Kd struct {
}
// GetETypeID returns the EType ID number.
func (e Des3CbcSha1Kd) GetETypeID() int32 {
return etypeID.DES3_CBC_SHA1_KD
}
// GetHashID returns the checksum type ID number.
func (e Des3CbcSha1Kd) GetHashID() int32 {
return chksumtype.HMAC_SHA1_DES3_KD
}
// GetKeyByteSize returns the number of bytes for key of this etype.
func (e Des3CbcSha1Kd) GetKeyByteSize() int {
return 24
}
// GetKeySeedBitLength returns the number of bits for the seed for key generation.
func (e Des3CbcSha1Kd) GetKeySeedBitLength() int {
return 21 * 8
}
// GetHashFunc returns the hash function for this etype.
func (e Des3CbcSha1Kd) GetHashFunc() func() hash.Hash {
return sha1.New
}
// GetMessageBlockByteSize returns the block size for the etype's messages.
func (e Des3CbcSha1Kd) GetMessageBlockByteSize() int {
//For traditional CBC mode with padding, it would be the underlying cipher's block size
return des.BlockSize
}
// GetDefaultStringToKeyParams returns the default key derivation parameters in string form.
func (e Des3CbcSha1Kd) GetDefaultStringToKeyParams() string {
var s string
return s
}
// GetConfounderByteSize returns the byte count for confounder to be used during cryptographic operations.
func (e Des3CbcSha1Kd) GetConfounderByteSize() int {
return des.BlockSize
}
// GetHMACBitLength returns the bit count size of the integrity hash.
func (e Des3CbcSha1Kd) GetHMACBitLength() int {
return e.GetHashFunc()().Size() * 8
}
// GetCypherBlockBitLength returns the bit count size of the cypher block.
func (e Des3CbcSha1Kd) GetCypherBlockBitLength() int {
return des.BlockSize * 8
}
// StringToKey returns a key derived from the string provided.
func (e Des3CbcSha1Kd) StringToKey(secret string, salt string, s2kparams string) ([]byte, error) {
if s2kparams != "" {
return []byte{}, errors.New("s2kparams must be an empty string")
}
return rfc3961.DES3StringToKey(secret, salt, e)
}
// RandomToKey returns a key from the bytes provided.
func (e Des3CbcSha1Kd) RandomToKey(b []byte) []byte {
return rfc3961.DES3RandomToKey(b)
}
// DeriveRandom generates data needed for key generation.
func (e Des3CbcSha1Kd) DeriveRandom(protocolKey, usage []byte) ([]byte, error) {
r, err := rfc3961.DeriveRandom(protocolKey, usage, e)
return r, err
}
// DeriveKey derives a key from the protocol key based on the usage value.
func (e Des3CbcSha1Kd) DeriveKey(protocolKey, usage []byte) ([]byte, error) {
r, err := e.DeriveRandom(protocolKey, usage)
if err != nil {
return nil, err
}
return e.RandomToKey(r), nil
}
// EncryptData encrypts the data provided.
func (e Des3CbcSha1Kd) EncryptData(key, data []byte) ([]byte, []byte, error) {
return rfc3961.DES3EncryptData(key, data, e)
}
// EncryptMessage encrypts the message provided and concatenates it with the integrity hash to create an encrypted message.
func (e Des3CbcSha1Kd) EncryptMessage(key, message []byte, usage uint32) ([]byte, []byte, error) {
return rfc3961.DES3EncryptMessage(key, message, usage, e)
}
// DecryptData decrypts the data provided.
func (e Des3CbcSha1Kd) DecryptData(key, data []byte) ([]byte, error) {
return rfc3961.DES3DecryptData(key, data, e)
}
// DecryptMessage decrypts the message provided and verifies the integrity of the message.
func (e Des3CbcSha1Kd) DecryptMessage(key, ciphertext []byte, usage uint32) ([]byte, error) {
return rfc3961.DES3DecryptMessage(key, ciphertext, usage, e)
}
// VerifyIntegrity checks the integrity of the plaintext message.
func (e Des3CbcSha1Kd) VerifyIntegrity(protocolKey, ct, pt []byte, usage uint32) bool {
return rfc3961.VerifyIntegrity(protocolKey, ct, pt, usage, e)
}
// GetChecksumHash returns a keyed checksum hash of the bytes provided.
func (e Des3CbcSha1Kd) GetChecksumHash(protocolKey, data []byte, usage uint32) ([]byte, error) {
return common.GetHash(data, protocolKey, common.GetUsageKc(usage), e)
}
// VerifyChecksum compares the checksum of the message bytes is the same as the checksum provided.
func (e Des3CbcSha1Kd) VerifyChecksum(protocolKey, data, chksum []byte, usage uint32) bool {
c, err := e.GetChecksumHash(protocolKey, data, usage)
if err != nil {
return false
}
return hmac.Equal(chksum, c)
}