blob: 90b5df0807165e516ebccab5da21eca7e828df32 [file] [log] [blame]
Scott Baker8461e152019-10-01 14:44:30 -07001package crypto
2
3import (
4 "crypto/aes"
5 "crypto/hmac"
6 "crypto/sha1"
7 "hash"
8
9 "gopkg.in/jcmturner/gokrb5.v7/crypto/common"
10 "gopkg.in/jcmturner/gokrb5.v7/crypto/rfc3961"
11 "gopkg.in/jcmturner/gokrb5.v7/crypto/rfc3962"
12 "gopkg.in/jcmturner/gokrb5.v7/iana/chksumtype"
13 "gopkg.in/jcmturner/gokrb5.v7/iana/etypeID"
14)
15
16// RFC 3962
17//+--------------------------------------------------------------------+
18//| protocol key format 128- or 256-bit string |
19//| |
20//| string-to-key function PBKDF2+DK with variable |
21//| iteration count (see |
22//| above) |
23//| |
24//| default string-to-key parameters 00 00 10 00 |
25//| |
26//| key-generation seed length key size |
27//| |
28//| random-to-key function identity function |
29//| |
30//| hash function, H SHA-1 |
31//| |
32//| HMAC output size, h 12 octets (96 bits) |
33//| |
34//| message block size, m 1 octet |
35//| |
36//| encryption/decryption functions, AES in CBC-CTS mode |
37//| E and D (cipher block size 16 |
38//| octets), with next-to- |
39//| last block (last block |
40//| if only one) as CBC-style |
41//| ivec |
42//+--------------------------------------------------------------------+
43//
44//+--------------------------------------------------------------------+
45//| encryption types |
46//+--------------------------------------------------------------------+
47//| type name etype value key size |
48//+--------------------------------------------------------------------+
49//| aes128-cts-hmac-sha1-96 17 128 |
50//| aes256-cts-hmac-sha1-96 18 256 |
51//+--------------------------------------------------------------------+
52//
53//+--------------------------------------------------------------------+
54//| checksum types |
55//+--------------------------------------------------------------------+
56//| type name sumtype value length |
57//+--------------------------------------------------------------------+
58//| hmac-sha1-96-aes128 15 96 |
59//| hmac-sha1-96-aes256 16 96 |
60//+--------------------------------------------------------------------+
61
62// Aes128CtsHmacSha96 implements Kerberos encryption type aes128-cts-hmac-sha1-96
63type Aes128CtsHmacSha96 struct {
64}
65
66// GetETypeID returns the EType ID number.
67func (e Aes128CtsHmacSha96) GetETypeID() int32 {
68 return etypeID.AES128_CTS_HMAC_SHA1_96
69}
70
71// GetHashID returns the checksum type ID number.
72func (e Aes128CtsHmacSha96) GetHashID() int32 {
73 return chksumtype.HMAC_SHA1_96_AES128
74}
75
76// GetKeyByteSize returns the number of bytes for key of this etype.
77func (e Aes128CtsHmacSha96) GetKeyByteSize() int {
78 return 128 / 8
79}
80
81// GetKeySeedBitLength returns the number of bits for the seed for key generation.
82func (e Aes128CtsHmacSha96) GetKeySeedBitLength() int {
83 return e.GetKeyByteSize() * 8
84}
85
86// GetHashFunc returns the hash function for this etype.
87func (e Aes128CtsHmacSha96) GetHashFunc() func() hash.Hash {
88 return sha1.New
89}
90
91// GetMessageBlockByteSize returns the block size for the etype's messages.
92func (e Aes128CtsHmacSha96) GetMessageBlockByteSize() int {
93 return 1
94}
95
96// GetDefaultStringToKeyParams returns the default key derivation parameters in string form.
97func (e Aes128CtsHmacSha96) GetDefaultStringToKeyParams() string {
98 return "00001000"
99}
100
101// GetConfounderByteSize returns the byte count for confounder to be used during cryptographic operations.
102func (e Aes128CtsHmacSha96) GetConfounderByteSize() int {
103 return aes.BlockSize
104}
105
106// GetHMACBitLength returns the bit count size of the integrity hash.
107func (e Aes128CtsHmacSha96) GetHMACBitLength() int {
108 return 96
109}
110
111// GetCypherBlockBitLength returns the bit count size of the cypher block.
112func (e Aes128CtsHmacSha96) GetCypherBlockBitLength() int {
113 return aes.BlockSize * 8
114}
115
116// StringToKey returns a key derived from the string provided.
117func (e Aes128CtsHmacSha96) StringToKey(secret string, salt string, s2kparams string) ([]byte, error) {
118 return rfc3962.StringToKey(secret, salt, s2kparams, e)
119}
120
121// RandomToKey returns a key from the bytes provided.
122func (e Aes128CtsHmacSha96) RandomToKey(b []byte) []byte {
123 return rfc3961.RandomToKey(b)
124}
125
126// EncryptData encrypts the data provided.
127func (e Aes128CtsHmacSha96) EncryptData(key, data []byte) ([]byte, []byte, error) {
128 return rfc3962.EncryptData(key, data, e)
129}
130
131// EncryptMessage encrypts the message provided and concatenates it with the integrity hash to create an encrypted message.
132func (e Aes128CtsHmacSha96) EncryptMessage(key, message []byte, usage uint32) ([]byte, []byte, error) {
133 return rfc3962.EncryptMessage(key, message, usage, e)
134}
135
136// DecryptData decrypts the data provided.
137func (e Aes128CtsHmacSha96) DecryptData(key, data []byte) ([]byte, error) {
138 return rfc3962.DecryptData(key, data, e)
139}
140
141// DecryptMessage decrypts the message provided and verifies the integrity of the message.
142func (e Aes128CtsHmacSha96) DecryptMessage(key, ciphertext []byte, usage uint32) ([]byte, error) {
143 return rfc3962.DecryptMessage(key, ciphertext, usage, e)
144}
145
146// DeriveKey derives a key from the protocol key based on the usage value.
147func (e Aes128CtsHmacSha96) DeriveKey(protocolKey, usage []byte) ([]byte, error) {
148 return rfc3961.DeriveKey(protocolKey, usage, e)
149}
150
151// DeriveRandom generates data needed for key generation.
152func (e Aes128CtsHmacSha96) DeriveRandom(protocolKey, usage []byte) ([]byte, error) {
153 return rfc3961.DeriveRandom(protocolKey, usage, e)
154}
155
156// VerifyIntegrity checks the integrity of the plaintext message.
157func (e Aes128CtsHmacSha96) VerifyIntegrity(protocolKey, ct, pt []byte, usage uint32) bool {
158 return rfc3961.VerifyIntegrity(protocolKey, ct, pt, usage, e)
159}
160
161// GetChecksumHash returns a keyed checksum hash of the bytes provided.
162func (e Aes128CtsHmacSha96) GetChecksumHash(protocolKey, data []byte, usage uint32) ([]byte, error) {
163 return common.GetHash(data, protocolKey, common.GetUsageKc(usage), e)
164}
165
166// VerifyChecksum compares the checksum of the message bytes is the same as the checksum provided.
167func (e Aes128CtsHmacSha96) VerifyChecksum(protocolKey, data, chksum []byte, usage uint32) bool {
168 c, err := e.GetChecksumHash(protocolKey, data, usage)
169 if err != nil {
170 return false
171 }
172 return hmac.Equal(chksum, c)
173}