eapol.go 8.2 KB

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