github.com/gopacket/gopacket@v1.1.0/layers/eapol.go (about) 1 // Copyright 2012 Google, Inc. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style license 4 // that can be found in the LICENSE file in the root of the source 5 // tree. 6 7 package layers 8 9 import ( 10 "encoding/binary" 11 "fmt" 12 13 "github.com/gopacket/gopacket" 14 ) 15 16 // EAPOL defines an EAP over LAN (802.1x) layer. 17 type EAPOL struct { 18 BaseLayer 19 Version uint8 20 Type EAPOLType 21 Length uint16 22 } 23 24 // LayerType returns LayerTypeEAPOL. 25 func (e *EAPOL) LayerType() gopacket.LayerType { return LayerTypeEAPOL } 26 27 // DecodeFromBytes decodes the given bytes into this layer. 28 func (e *EAPOL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 29 if len(data) < 4 { 30 df.SetTruncated() 31 return fmt.Errorf("EAPOL length %d too short", len(data)) 32 } 33 e.Version = data[0] 34 e.Type = EAPOLType(data[1]) 35 e.Length = binary.BigEndian.Uint16(data[2:4]) 36 e.BaseLayer = BaseLayer{data[:4], data[4:]} 37 return nil 38 } 39 40 // SerializeTo writes the serialized form of this layer into the 41 // SerializationBuffer, implementing gopacket.SerializableLayer 42 func (e *EAPOL) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 43 bytes, _ := b.PrependBytes(4) 44 bytes[0] = e.Version 45 bytes[1] = byte(e.Type) 46 binary.BigEndian.PutUint16(bytes[2:], e.Length) 47 return nil 48 } 49 50 // CanDecode returns the set of layer types that this DecodingLayer can decode. 51 func (e *EAPOL) CanDecode() gopacket.LayerClass { 52 return LayerTypeEAPOL 53 } 54 55 // NextLayerType returns the layer type contained by this DecodingLayer. 56 func (e *EAPOL) NextLayerType() gopacket.LayerType { 57 return e.Type.LayerType() 58 } 59 60 func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error { 61 e := &EAPOL{} 62 return decodingLayerDecoder(e, data, p) 63 } 64 65 // EAPOLKeyDescriptorType is an enumeration of key descriptor types 66 // as specified by 802.1x in the EAPOL-Key frame 67 type EAPOLKeyDescriptorType uint8 68 69 // Enumeration of EAPOLKeyDescriptorType 70 const ( 71 EAPOLKeyDescriptorTypeRC4 EAPOLKeyDescriptorType = 1 72 EAPOLKeyDescriptorTypeDot11 EAPOLKeyDescriptorType = 2 73 EAPOLKeyDescriptorTypeWPA EAPOLKeyDescriptorType = 254 74 ) 75 76 func (kdt EAPOLKeyDescriptorType) String() string { 77 switch kdt { 78 case EAPOLKeyDescriptorTypeRC4: 79 return "RC4" 80 case EAPOLKeyDescriptorTypeDot11: 81 return "802.11" 82 case EAPOLKeyDescriptorTypeWPA: 83 return "WPA" 84 default: 85 return fmt.Sprintf("unknown descriptor type %d", kdt) 86 } 87 } 88 89 // EAPOLKeyDescriptorVersion is an enumeration of versions specifying the 90 // encryption algorithm for the key data and the authentication for the 91 // message integrity code (MIC) 92 type EAPOLKeyDescriptorVersion uint8 93 94 // Enumeration of EAPOLKeyDescriptorVersion 95 const ( 96 EAPOLKeyDescriptorVersionOther EAPOLKeyDescriptorVersion = 0 97 EAPOLKeyDescriptorVersionRC4HMACMD5 EAPOLKeyDescriptorVersion = 1 98 EAPOLKeyDescriptorVersionAESHMACSHA1 EAPOLKeyDescriptorVersion = 2 99 EAPOLKeyDescriptorVersionAES128CMAC EAPOLKeyDescriptorVersion = 3 100 ) 101 102 func (v EAPOLKeyDescriptorVersion) String() string { 103 switch v { 104 case EAPOLKeyDescriptorVersionOther: 105 return "Other" 106 case EAPOLKeyDescriptorVersionRC4HMACMD5: 107 return "RC4-HMAC-MD5" 108 case EAPOLKeyDescriptorVersionAESHMACSHA1: 109 return "AES-HMAC-SHA1-128" 110 case EAPOLKeyDescriptorVersionAES128CMAC: 111 return "AES-128-CMAC" 112 default: 113 return fmt.Sprintf("unknown version %d", v) 114 } 115 } 116 117 // EAPOLKeyType is an enumeration of key derivation types describing 118 // the purpose of the keys being derived. 119 type EAPOLKeyType uint8 120 121 // Enumeration of EAPOLKeyType 122 const ( 123 EAPOLKeyTypeGroupSMK EAPOLKeyType = 0 124 EAPOLKeyTypePairwise EAPOLKeyType = 1 125 ) 126 127 func (kt EAPOLKeyType) String() string { 128 switch kt { 129 case EAPOLKeyTypeGroupSMK: 130 return "Group/SMK" 131 case EAPOLKeyTypePairwise: 132 return "Pairwise" 133 default: 134 return fmt.Sprintf("unknown key type %d", kt) 135 } 136 } 137 138 // EAPOLKey defines an EAPOL-Key frame for 802.1x authentication 139 type EAPOLKey struct { 140 BaseLayer 141 KeyDescriptorType EAPOLKeyDescriptorType 142 KeyDescriptorVersion EAPOLKeyDescriptorVersion 143 KeyType EAPOLKeyType 144 KeyIndex uint8 145 Install bool 146 KeyACK bool 147 KeyMIC bool 148 Secure bool 149 MICError bool 150 Request bool 151 HasEncryptedKeyData bool 152 SMKMessage bool 153 KeyLength uint16 154 ReplayCounter uint64 155 Nonce []byte 156 IV []byte 157 RSC uint64 158 ID uint64 159 MIC []byte 160 KeyDataLength uint16 161 EncryptedKeyData []byte 162 } 163 164 // LayerType returns LayerTypeEAPOLKey. 165 func (ek *EAPOLKey) LayerType() gopacket.LayerType { 166 return LayerTypeEAPOLKey 167 } 168 169 // CanDecode returns the set of layer types that this DecodingLayer can decode. 170 func (ek *EAPOLKey) CanDecode() gopacket.LayerType { 171 return LayerTypeEAPOLKey 172 } 173 174 // NextLayerType returns layers.LayerTypeDot11InformationElement if the key 175 // data exists and is unencrypted, otherwise it does not expect a next layer. 176 func (ek *EAPOLKey) NextLayerType() gopacket.LayerType { 177 if !ek.HasEncryptedKeyData && ek.KeyDataLength > 0 { 178 return LayerTypeDot11InformationElement 179 } 180 return gopacket.LayerTypePayload 181 } 182 183 const eapolKeyFrameLen = 95 184 185 // DecodeFromBytes decodes the given bytes into this layer. 186 func (ek *EAPOLKey) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 187 if len(data) < eapolKeyFrameLen { 188 df.SetTruncated() 189 return fmt.Errorf("EAPOLKey length %v too short, %v required", 190 len(data), eapolKeyFrameLen) 191 } 192 193 ek.KeyDescriptorType = EAPOLKeyDescriptorType(data[0]) 194 195 info := binary.BigEndian.Uint16(data[1:3]) 196 ek.KeyDescriptorVersion = EAPOLKeyDescriptorVersion(info & 0x0007) 197 ek.KeyType = EAPOLKeyType((info & 0x0008) >> 3) 198 ek.KeyIndex = uint8((info & 0x0030) >> 4) 199 ek.Install = (info & 0x0040) != 0 200 ek.KeyACK = (info & 0x0080) != 0 201 ek.KeyMIC = (info & 0x0100) != 0 202 ek.Secure = (info & 0x0200) != 0 203 ek.MICError = (info & 0x0400) != 0 204 ek.Request = (info & 0x0800) != 0 205 ek.HasEncryptedKeyData = (info & 0x1000) != 0 206 ek.SMKMessage = (info & 0x2000) != 0 207 208 ek.KeyLength = binary.BigEndian.Uint16(data[3:5]) 209 ek.ReplayCounter = binary.BigEndian.Uint64(data[5:13]) 210 211 ek.Nonce = data[13:45] 212 ek.IV = data[45:61] 213 ek.RSC = binary.BigEndian.Uint64(data[61:69]) 214 ek.ID = binary.BigEndian.Uint64(data[69:77]) 215 ek.MIC = data[77:93] 216 217 ek.KeyDataLength = binary.BigEndian.Uint16(data[93:95]) 218 219 totalLength := eapolKeyFrameLen + int(ek.KeyDataLength) 220 if len(data) < totalLength { 221 df.SetTruncated() 222 return fmt.Errorf("EAPOLKey data length %d too short, %d required", 223 len(data)-eapolKeyFrameLen, ek.KeyDataLength) 224 } 225 226 if ek.HasEncryptedKeyData { 227 ek.EncryptedKeyData = data[eapolKeyFrameLen:totalLength] 228 ek.BaseLayer = BaseLayer{ 229 Contents: data[:totalLength], 230 Payload: data[totalLength:], 231 } 232 } else { 233 ek.BaseLayer = BaseLayer{ 234 Contents: data[:eapolKeyFrameLen], 235 Payload: data[eapolKeyFrameLen:], 236 } 237 } 238 239 return nil 240 } 241 242 // SerializeTo writes the serialized form of this layer into the 243 // SerializationBuffer, implementing gopacket.SerializableLayer. 244 // See the docs for gopacket.SerializableLayer for more info. 245 func (ek *EAPOLKey) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 246 buf, err := b.PrependBytes(eapolKeyFrameLen + len(ek.EncryptedKeyData)) 247 if err != nil { 248 return err 249 } 250 251 buf[0] = byte(ek.KeyDescriptorType) 252 253 var info uint16 254 info |= uint16(ek.KeyDescriptorVersion) 255 info |= uint16(ek.KeyType) << 3 256 info |= uint16(ek.KeyIndex) << 4 257 if ek.Install { 258 info |= 0x0040 259 } 260 if ek.KeyACK { 261 info |= 0x0080 262 } 263 if ek.KeyMIC { 264 info |= 0x0100 265 } 266 if ek.Secure { 267 info |= 0x0200 268 } 269 if ek.MICError { 270 info |= 0x0400 271 } 272 if ek.Request { 273 info |= 0x0800 274 } 275 if ek.HasEncryptedKeyData { 276 info |= 0x1000 277 } 278 if ek.SMKMessage { 279 info |= 0x2000 280 } 281 binary.BigEndian.PutUint16(buf[1:3], info) 282 283 binary.BigEndian.PutUint16(buf[3:5], ek.KeyLength) 284 binary.BigEndian.PutUint64(buf[5:13], ek.ReplayCounter) 285 286 copy(buf[13:45], ek.Nonce) 287 copy(buf[45:61], ek.IV) 288 binary.BigEndian.PutUint64(buf[61:69], ek.RSC) 289 binary.BigEndian.PutUint64(buf[69:77], ek.ID) 290 copy(buf[77:93], ek.MIC) 291 292 binary.BigEndian.PutUint16(buf[93:95], ek.KeyDataLength) 293 if len(ek.EncryptedKeyData) > 0 { 294 copy(buf[95:95+len(ek.EncryptedKeyData)], ek.EncryptedKeyData) 295 } 296 297 return nil 298 } 299 300 func decodeEAPOLKey(data []byte, p gopacket.PacketBuilder) error { 301 ek := &EAPOLKey{} 302 return decodingLayerDecoder(ek, data, p) 303 }