1package crypto 2 3import ( 4 "crypto/des" 5 "crypto/hmac" 6 "crypto/sha1" 7 "errors" 8 "hash" 9 10 "github.com/jcmturner/gokrb5/v8/crypto/common" 11 "github.com/jcmturner/gokrb5/v8/crypto/rfc3961" 12 "github.com/jcmturner/gokrb5/v8/iana/chksumtype" 13 "github.com/jcmturner/gokrb5/v8/iana/etypeID" 14) 15 16//RFC: 3961 Section 6.3 17 18/* 19 des3-cbc-hmac-sha1-kd, hmac-sha1-des3-kd 20 ------------------------------------------------ 21 protocol key format 24 bytes, parity in low 22 bit of each 23 24 key-generation seed 21 bytes 25 length 26 27 hash function SHA-1 28 29 HMAC output size 160 bits 30 31 message block size 8 bytes 32 33 default string-to-key empty string 34 params 35 36 encryption and triple-DES encrypt and 37 decryption functions decrypt, in outer-CBC 38 mode (cipher block size 39 8 octets) 40 41 key generation functions: 42 43 random-to-key DES3random-to-key (see 44 below) 45 46 string-to-key DES3string-to-key (see 47 below) 48 49 The des3-cbc-hmac-sha1-kd encryption type is assigned the value 50 sixteen (16). The hmac-sha1-des3-kd checksum algorithm is assigned a 51 checksum type number of twelve (12)*/ 52 53// Des3CbcSha1Kd implements Kerberos encryption type des3-cbc-hmac-sha1-kd 54type Des3CbcSha1Kd struct { 55} 56 57// GetETypeID returns the EType ID number. 58func (e Des3CbcSha1Kd) GetETypeID() int32 { 59 return etypeID.DES3_CBC_SHA1_KD 60} 61 62// GetHashID returns the checksum type ID number. 63func (e Des3CbcSha1Kd) GetHashID() int32 { 64 return chksumtype.HMAC_SHA1_DES3_KD 65} 66 67// GetKeyByteSize returns the number of bytes for key of this etype. 68func (e Des3CbcSha1Kd) GetKeyByteSize() int { 69 return 24 70} 71 72// GetKeySeedBitLength returns the number of bits for the seed for key generation. 73func (e Des3CbcSha1Kd) GetKeySeedBitLength() int { 74 return 21 * 8 75} 76 77// GetHashFunc returns the hash function for this etype. 78func (e Des3CbcSha1Kd) GetHashFunc() func() hash.Hash { 79 return sha1.New 80} 81 82// GetMessageBlockByteSize returns the block size for the etype's messages. 83func (e Des3CbcSha1Kd) GetMessageBlockByteSize() int { 84 //For traditional CBC mode with padding, it would be the underlying cipher's block size 85 return des.BlockSize 86} 87 88// GetDefaultStringToKeyParams returns the default key derivation parameters in string form. 89func (e Des3CbcSha1Kd) GetDefaultStringToKeyParams() string { 90 var s string 91 return s 92} 93 94// GetConfounderByteSize returns the byte count for confounder to be used during cryptographic operations. 95func (e Des3CbcSha1Kd) GetConfounderByteSize() int { 96 return des.BlockSize 97} 98 99// GetHMACBitLength returns the bit count size of the integrity hash. 100func (e Des3CbcSha1Kd) GetHMACBitLength() int { 101 return e.GetHashFunc()().Size() * 8 102} 103 104// GetCypherBlockBitLength returns the bit count size of the cypher block. 105func (e Des3CbcSha1Kd) GetCypherBlockBitLength() int { 106 return des.BlockSize * 8 107} 108 109// StringToKey returns a key derived from the string provided. 110func (e Des3CbcSha1Kd) StringToKey(secret string, salt string, s2kparams string) ([]byte, error) { 111 if s2kparams != "" { 112 return []byte{}, errors.New("s2kparams must be an empty string") 113 } 114 return rfc3961.DES3StringToKey(secret, salt, e) 115} 116 117// RandomToKey returns a key from the bytes provided. 118func (e Des3CbcSha1Kd) RandomToKey(b []byte) []byte { 119 return rfc3961.DES3RandomToKey(b) 120} 121 122// DeriveRandom generates data needed for key generation. 123func (e Des3CbcSha1Kd) DeriveRandom(protocolKey, usage []byte) ([]byte, error) { 124 r, err := rfc3961.DeriveRandom(protocolKey, usage, e) 125 return r, err 126} 127 128// DeriveKey derives a key from the protocol key based on the usage value. 129func (e Des3CbcSha1Kd) DeriveKey(protocolKey, usage []byte) ([]byte, error) { 130 r, err := e.DeriveRandom(protocolKey, usage) 131 if err != nil { 132 return nil, err 133 } 134 return e.RandomToKey(r), nil 135} 136 137// EncryptData encrypts the data provided. 138func (e Des3CbcSha1Kd) EncryptData(key, data []byte) ([]byte, []byte, error) { 139 return rfc3961.DES3EncryptData(key, data, e) 140} 141 142// EncryptMessage encrypts the message provided and concatenates it with the integrity hash to create an encrypted message. 143func (e Des3CbcSha1Kd) EncryptMessage(key, message []byte, usage uint32) ([]byte, []byte, error) { 144 return rfc3961.DES3EncryptMessage(key, message, usage, e) 145} 146 147// DecryptData decrypts the data provided. 148func (e Des3CbcSha1Kd) DecryptData(key, data []byte) ([]byte, error) { 149 return rfc3961.DES3DecryptData(key, data, e) 150} 151 152// DecryptMessage decrypts the message provided and verifies the integrity of the message. 153func (e Des3CbcSha1Kd) DecryptMessage(key, ciphertext []byte, usage uint32) ([]byte, error) { 154 return rfc3961.DES3DecryptMessage(key, ciphertext, usage, e) 155} 156 157// VerifyIntegrity checks the integrity of the plaintext message. 158func (e Des3CbcSha1Kd) VerifyIntegrity(protocolKey, ct, pt []byte, usage uint32) bool { 159 return rfc3961.VerifyIntegrity(protocolKey, ct, pt, usage, e) 160} 161 162// GetChecksumHash returns a keyed checksum hash of the bytes provided. 163func (e Des3CbcSha1Kd) GetChecksumHash(protocolKey, data []byte, usage uint32) ([]byte, error) { 164 return common.GetHash(data, protocolKey, common.GetUsageKc(usage), e) 165} 166 167// VerifyChecksum compares the checksum of the message bytes is the same as the checksum provided. 168func (e Des3CbcSha1Kd) VerifyChecksum(protocolKey, data, chksum []byte, usage uint32) bool { 169 c, err := e.GetChecksumHash(protocolKey, data, usage) 170 if err != nil { 171 return false 172 } 173 return hmac.Equal(chksum, c) 174} 175