rx_eapol.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /*
  2. * Received Data frame processing for EAPOL messages
  3. * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "utils/includes.h"
  15. #include "utils/common.h"
  16. #include "crypto/aes_wrap.h"
  17. #include "crypto/crypto.h"
  18. #include "common/defs.h"
  19. #include "common/ieee802_11_defs.h"
  20. #include "common/eapol_common.h"
  21. #include "common/wpa_common.h"
  22. #include "rsn_supp/wpa_ie.h"
  23. #include "wlantest.h"
  24. static int is_zero(const u8 *buf, size_t len)
  25. {
  26. size_t i;
  27. for (i = 0; i < len; i++) {
  28. if (buf[i])
  29. return 0;
  30. }
  31. return 1;
  32. }
  33. static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
  34. {
  35. u8 *buf;
  36. int ret = -1;
  37. struct ieee802_1x_hdr *hdr;
  38. struct wpa_eapol_key *key;
  39. u8 rx_mic[16];
  40. buf = os_malloc(len);
  41. if (buf == NULL)
  42. return -1;
  43. os_memcpy(buf, data, len);
  44. hdr = (struct ieee802_1x_hdr *) buf;
  45. key = (struct wpa_eapol_key *) (hdr + 1);
  46. os_memcpy(rx_mic, key->key_mic, 16);
  47. os_memset(key->key_mic, 0, 16);
  48. if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
  49. os_memcmp(rx_mic, key->key_mic, 16) == 0)
  50. ret = 0;
  51. os_free(buf);
  52. return ret;
  53. }
  54. static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
  55. const u8 *src, const u8 *data, size_t len)
  56. {
  57. struct wlantest_bss *bss;
  58. struct wlantest_sta *sta;
  59. const struct ieee802_1x_hdr *eapol;
  60. const struct wpa_eapol_key *hdr;
  61. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
  62. MAC2STR(src), MAC2STR(dst));
  63. bss = bss_get(wt, src);
  64. if (bss == NULL)
  65. return;
  66. sta = sta_get(bss, dst);
  67. if (sta == NULL)
  68. return;
  69. eapol = (const struct ieee802_1x_hdr *) data;
  70. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  71. if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
  72. wpa_printf(MSG_INFO, "EAPOL-Key 1/4 from " MACSTR " used "
  73. "zero nonce", MAC2STR(src));
  74. }
  75. if (!is_zero(hdr->key_rsc, 8)) {
  76. wpa_printf(MSG_INFO, "EAPOL-Key 1/4 from " MACSTR " used "
  77. "non-zero Key RSC", MAC2STR(src));
  78. }
  79. os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
  80. }
  81. static int try_pmk(struct wlantest_bss *bss, struct wlantest_sta *sta,
  82. u16 ver, const u8 *data, size_t len,
  83. struct wlantest_pmk *pmk)
  84. {
  85. struct wpa_ptk ptk;
  86. size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48;
  87. wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
  88. "Pairwise key expansion",
  89. bss->bssid, sta->addr, sta->anonce, sta->snonce,
  90. (u8 *) &ptk, ptk_len,
  91. wpa_key_mgmt_sha256(sta->key_mgmt));
  92. if (check_mic(ptk.kck, ver, data, len) < 0)
  93. return -1;
  94. wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
  95. MAC2STR(sta->addr), MAC2STR(bss->bssid));
  96. sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
  97. if (sta->ptk_set) {
  98. /*
  99. * Rekeying - use new PTK for EAPOL-Key frames, but continue
  100. * using the old PTK for frame decryption.
  101. */
  102. os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
  103. wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16);
  104. wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16);
  105. wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16);
  106. if (ptk_len > 48)
  107. wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2,
  108. 16);
  109. sta->tptk_set = 1;
  110. return 0;
  111. }
  112. os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
  113. wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
  114. wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
  115. wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
  116. if (ptk_len > 48)
  117. wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16);
  118. sta->ptk_set = 1;
  119. os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
  120. os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
  121. return 0;
  122. }
  123. static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
  124. struct wlantest_sta *sta, u16 ver,
  125. const u8 *data, size_t len)
  126. {
  127. struct wlantest_pmk *pmk;
  128. wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR,
  129. MAC2STR(sta->addr));
  130. dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
  131. wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
  132. if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
  133. return;
  134. }
  135. dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
  136. wpa_printf(MSG_DEBUG, "Try global PMK");
  137. if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
  138. return;
  139. }
  140. wpa_printf(MSG_DEBUG, "No matching PMK found to derive PTK");
  141. }
  142. static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
  143. const u8 *src, const u8 *data, size_t len)
  144. {
  145. struct wlantest_bss *bss;
  146. struct wlantest_sta *sta;
  147. const struct ieee802_1x_hdr *eapol;
  148. const struct wpa_eapol_key *hdr;
  149. const u8 *key_data, *kck;
  150. u16 key_info, key_data_len;
  151. struct wpa_eapol_ie_parse ie;
  152. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
  153. MAC2STR(src), MAC2STR(dst));
  154. bss = bss_get(wt, dst);
  155. if (bss == NULL)
  156. return;
  157. sta = sta_get(bss, src);
  158. if (sta == NULL)
  159. return;
  160. eapol = (const struct ieee802_1x_hdr *) data;
  161. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  162. if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
  163. wpa_printf(MSG_INFO, "EAPOL-Key 2/4 from " MACSTR " used "
  164. "zero nonce", MAC2STR(src));
  165. }
  166. if (!is_zero(hdr->key_rsc, 8)) {
  167. wpa_printf(MSG_INFO, "EAPOL-Key 2/4 from " MACSTR " used "
  168. "non-zero Key RSC", MAC2STR(src));
  169. }
  170. os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
  171. key_info = WPA_GET_BE16(hdr->key_info);
  172. key_data_len = WPA_GET_BE16(hdr->key_data_length);
  173. derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
  174. if (!sta->ptk_set && !sta->tptk_set) {
  175. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/4");
  176. return;
  177. }
  178. kck = sta->ptk.kck;
  179. if (sta->tptk_set) {
  180. wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
  181. kck = sta->tptk.kck;
  182. }
  183. if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
  184. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
  185. return;
  186. }
  187. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
  188. key_data = (const u8 *) (hdr + 1);
  189. if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
  190. wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
  191. return;
  192. }
  193. if (ie.wpa_ie) {
  194. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
  195. ie.wpa_ie, ie.wpa_ie_len);
  196. if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
  197. wpa_printf(MSG_INFO, "Mismatch in WPA IE between "
  198. "EAPOL-Key 2/4 and (Re)Association "
  199. "Request from " MACSTR, MAC2STR(sta->addr));
  200. wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
  201. ie.wpa_ie, ie.wpa_ie_len);
  202. wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
  203. "Request",
  204. sta->rsnie,
  205. sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
  206. }
  207. }
  208. if (ie.rsn_ie) {
  209. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
  210. ie.rsn_ie, ie.rsn_ie_len);
  211. if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
  212. wpa_printf(MSG_INFO, "Mismatch in RSN IE between "
  213. "EAPOL-Key 2/4 and (Re)Association "
  214. "Request from " MACSTR, MAC2STR(sta->addr));
  215. wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
  216. ie.rsn_ie, ie.rsn_ie_len);
  217. wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
  218. "Request",
  219. sta->rsnie,
  220. sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
  221. }
  222. }
  223. }
  224. static u8 * decrypt_eapol_key_data_rc4(const u8 *kek,
  225. const struct wpa_eapol_key *hdr,
  226. size_t *len)
  227. {
  228. u8 ek[32], *buf;
  229. u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
  230. buf = os_malloc(keydatalen);
  231. if (buf == NULL)
  232. return NULL;
  233. os_memcpy(ek, hdr->key_iv, 16);
  234. os_memcpy(ek + 16, kek, 16);
  235. os_memcpy(buf, hdr + 1, keydatalen);
  236. if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
  237. wpa_printf(MSG_INFO, "RC4 failed");
  238. os_free(buf);
  239. return NULL;
  240. }
  241. *len = keydatalen;
  242. return buf;
  243. }
  244. static u8 * decrypt_eapol_key_data_aes(const u8 *kek,
  245. const struct wpa_eapol_key *hdr,
  246. size_t *len)
  247. {
  248. u8 *buf;
  249. u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
  250. if (keydatalen % 8) {
  251. wpa_printf(MSG_INFO, "Unsupported AES-WRAP len %d",
  252. keydatalen);
  253. return NULL;
  254. }
  255. keydatalen -= 8; /* AES-WRAP adds 8 bytes */
  256. buf = os_malloc(keydatalen);
  257. if (buf == NULL)
  258. return NULL;
  259. if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
  260. os_free(buf);
  261. wpa_printf(MSG_INFO, "AES unwrap failed - "
  262. "could not decrypt EAPOL-Key key data");
  263. return NULL;
  264. }
  265. *len = keydatalen;
  266. return buf;
  267. }
  268. static u8 * decrypt_eapol_key_data(const u8 *kek, u16 ver,
  269. const struct wpa_eapol_key *hdr,
  270. size_t *len)
  271. {
  272. switch (ver) {
  273. case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
  274. return decrypt_eapol_key_data_rc4(kek, hdr, len);
  275. case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
  276. case WPA_KEY_INFO_TYPE_AES_128_CMAC:
  277. return decrypt_eapol_key_data_aes(kek, hdr, len);
  278. default:
  279. wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
  280. "Version %u", ver);
  281. return NULL;
  282. }
  283. }
  284. static void learn_kde_keys(struct wlantest_bss *bss, struct wlantest_sta *sta,
  285. const u8 *buf, size_t len, const u8 *rsc)
  286. {
  287. struct wpa_eapol_ie_parse ie;
  288. if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
  289. wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
  290. return;
  291. }
  292. if (ie.wpa_ie) {
  293. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
  294. ie.wpa_ie, ie.wpa_ie_len);
  295. }
  296. if (ie.rsn_ie) {
  297. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
  298. ie.rsn_ie, ie.rsn_ie_len);
  299. }
  300. if (ie.gtk) {
  301. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
  302. ie.gtk, ie.gtk_len);
  303. if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
  304. int id;
  305. id = ie.gtk[0] & 0x03;
  306. wpa_printf(MSG_DEBUG, "GTK KeyID=%u tx=%u",
  307. id, !!(ie.gtk[0] & 0x04));
  308. if ((ie.gtk[0] & 0xf8) || ie.gtk[1])
  309. wpa_printf(MSG_INFO, "GTK KDE: Reserved field "
  310. "set: %02x %02x",
  311. ie.gtk[0], ie.gtk[1]);
  312. wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
  313. ie.gtk_len - 2);
  314. bss->gtk_len[id] = ie.gtk_len - 2;
  315. sta->gtk_len = ie.gtk_len - 2;
  316. os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
  317. os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
  318. bss->rsc[id][0] = rsc[5];
  319. bss->rsc[id][1] = rsc[4];
  320. bss->rsc[id][2] = rsc[3];
  321. bss->rsc[id][3] = rsc[2];
  322. bss->rsc[id][4] = rsc[1];
  323. bss->rsc[id][5] = rsc[0];
  324. bss->gtk_idx = id;
  325. sta->gtk_idx = id;
  326. wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
  327. } else {
  328. wpa_printf(MSG_INFO, "Invalid GTK KDE length %u",
  329. (unsigned) ie.gtk_len);
  330. }
  331. }
  332. if (ie.igtk) {
  333. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
  334. ie.igtk, ie.igtk_len);
  335. if (ie.igtk_len == 24) {
  336. u16 id;
  337. id = WPA_GET_LE16(ie.igtk);
  338. if (id > 5) {
  339. wpa_printf(MSG_INFO, "Unexpected IGTK KeyID "
  340. "%u", id);
  341. } else {
  342. const u8 *ipn;
  343. wpa_printf(MSG_DEBUG, "IGTK KeyID %u", id);
  344. wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
  345. wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
  346. 16);
  347. os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
  348. bss->igtk_set[id] = 1;
  349. ipn = ie.igtk + 2;
  350. bss->ipn[id][0] = ipn[5];
  351. bss->ipn[id][1] = ipn[4];
  352. bss->ipn[id][2] = ipn[3];
  353. bss->ipn[id][3] = ipn[2];
  354. bss->ipn[id][4] = ipn[1];
  355. bss->ipn[id][5] = ipn[0];
  356. bss->igtk_idx = id;
  357. }
  358. } else {
  359. wpa_printf(MSG_INFO, "Invalid IGTK KDE length %u",
  360. (unsigned) ie.igtk_len);
  361. }
  362. }
  363. }
  364. static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
  365. const u8 *src, const u8 *data, size_t len)
  366. {
  367. struct wlantest_bss *bss;
  368. struct wlantest_sta *sta;
  369. const struct ieee802_1x_hdr *eapol;
  370. const struct wpa_eapol_key *hdr;
  371. const u8 *key_data, *kck, *kek;
  372. int recalc = 0;
  373. u16 key_info, ver;
  374. u8 *decrypted_buf = NULL;
  375. const u8 *decrypted;
  376. size_t decrypted_len = 0;
  377. struct wpa_eapol_ie_parse ie;
  378. wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
  379. MAC2STR(src), MAC2STR(dst));
  380. bss = bss_get(wt, src);
  381. if (bss == NULL)
  382. return;
  383. sta = sta_get(bss, dst);
  384. if (sta == NULL)
  385. return;
  386. eapol = (const struct ieee802_1x_hdr *) data;
  387. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  388. key_info = WPA_GET_BE16(hdr->key_info);
  389. if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
  390. wpa_printf(MSG_INFO, "EAPOL-Key ANonce mismatch between 1/4 "
  391. "and 3/4");
  392. recalc = 1;
  393. }
  394. os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
  395. if (recalc) {
  396. derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
  397. data, len);
  398. }
  399. if (!sta->ptk_set && !sta->tptk_set) {
  400. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 3/4");
  401. return;
  402. }
  403. kek = sta->ptk.kek;
  404. kck = sta->ptk.kck;
  405. if (sta->tptk_set) {
  406. wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
  407. kck = sta->tptk.kck;
  408. kek = sta->tptk.kek;
  409. }
  410. if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
  411. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
  412. return;
  413. }
  414. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
  415. key_data = (const u8 *) (hdr + 1);
  416. if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
  417. if (sta->proto & WPA_PROTO_RSN)
  418. wpa_printf(MSG_INFO, "EAPOL-Key 3/4 without "
  419. "EncrKeyData bit");
  420. decrypted = key_data;
  421. decrypted_len = WPA_GET_BE16(hdr->key_data_length);
  422. } else {
  423. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  424. decrypted_buf = decrypt_eapol_key_data(kek, ver, hdr,
  425. &decrypted_len);
  426. if (decrypted_buf == NULL) {
  427. wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key "
  428. "Data");
  429. return;
  430. }
  431. decrypted = decrypted_buf;
  432. wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
  433. decrypted, decrypted_len);
  434. }
  435. if (wt->write_pcap_dumper && decrypted != key_data) {
  436. /* Fill in a dummy Data frame header */
  437. u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
  438. struct ieee80211_hdr *h;
  439. struct wpa_eapol_key *k;
  440. const u8 *p;
  441. u8 *pos;
  442. size_t plain_len;
  443. plain_len = decrypted_len;
  444. p = decrypted;
  445. while (p + 1 < decrypted + decrypted_len) {
  446. if (p[0] == 0xdd && p[1] == 0x00) {
  447. /* Remove padding */
  448. plain_len = p - decrypted;
  449. break;
  450. }
  451. p += 2 + p[1];
  452. }
  453. os_memset(buf, 0, sizeof(buf));
  454. h = (struct ieee80211_hdr *) buf;
  455. h->frame_control = host_to_le16(0x0208);
  456. os_memcpy(h->addr1, dst, ETH_ALEN);
  457. os_memcpy(h->addr2, src, ETH_ALEN);
  458. os_memcpy(h->addr3, src, ETH_ALEN);
  459. pos = (u8 *) (h + 1);
  460. os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
  461. pos += 8;
  462. os_memcpy(pos, eapol, sizeof(*eapol));
  463. pos += sizeof(*eapol);
  464. os_memcpy(pos, hdr, sizeof(*hdr));
  465. k = (struct wpa_eapol_key *) pos;
  466. WPA_PUT_BE16(k->key_info,
  467. key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
  468. WPA_PUT_BE16(k->key_data_length, plain_len);
  469. write_pcap_decrypted(wt, buf, sizeof(buf),
  470. decrypted, plain_len);
  471. }
  472. if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
  473. wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
  474. os_free(decrypted_buf);
  475. return;
  476. }
  477. if ((ie.wpa_ie &&
  478. os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
  479. (ie.wpa_ie == NULL && bss->wpaie[0])) {
  480. wpa_printf(MSG_INFO, "Mismatch in WPA IE between "
  481. "EAPOL-Key 3/4 and Beacon/Probe Response "
  482. "from " MACSTR, MAC2STR(bss->bssid));
  483. wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
  484. ie.wpa_ie, ie.wpa_ie_len);
  485. wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
  486. "Response",
  487. bss->wpaie,
  488. bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
  489. }
  490. if ((ie.rsn_ie &&
  491. os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
  492. (ie.rsn_ie == NULL && bss->rsnie[0])) {
  493. wpa_printf(MSG_INFO, "Mismatch in RSN IE between "
  494. "EAPOL-Key 3/4 and Beacon/Probe Response "
  495. "from " MACSTR, MAC2STR(bss->bssid));
  496. wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
  497. ie.rsn_ie, ie.rsn_ie_len);
  498. wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
  499. "Request",
  500. bss->rsnie,
  501. bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
  502. }
  503. learn_kde_keys(bss, sta, decrypted, decrypted_len, hdr->key_rsc);
  504. os_free(decrypted_buf);
  505. }
  506. static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
  507. const u8 *src, const u8 *data, size_t len)
  508. {
  509. struct wlantest_bss *bss;
  510. struct wlantest_sta *sta;
  511. const struct ieee802_1x_hdr *eapol;
  512. const struct wpa_eapol_key *hdr;
  513. u16 key_info;
  514. const u8 *kck;
  515. wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
  516. MAC2STR(src), MAC2STR(dst));
  517. bss = bss_get(wt, dst);
  518. if (bss == NULL)
  519. return;
  520. sta = sta_get(bss, src);
  521. if (sta == NULL)
  522. return;
  523. eapol = (const struct ieee802_1x_hdr *) data;
  524. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  525. if (!is_zero(hdr->key_rsc, 8)) {
  526. wpa_printf(MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
  527. "non-zero Key RSC", MAC2STR(src));
  528. }
  529. key_info = WPA_GET_BE16(hdr->key_info);
  530. if (!sta->ptk_set && !sta->tptk_set) {
  531. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 4/4");
  532. return;
  533. }
  534. kck = sta->ptk.kck;
  535. if (sta->tptk_set) {
  536. wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
  537. kck = sta->tptk.kck;
  538. }
  539. if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
  540. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
  541. return;
  542. }
  543. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
  544. if (sta->tptk_set) {
  545. wpa_printf(MSG_DEBUG, "Update PTK (rekeying)");
  546. os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
  547. sta->ptk_set = 1;
  548. sta->tptk_set = 0;
  549. os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
  550. os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
  551. }
  552. }
  553. static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
  554. const u8 *src, const u8 *data, size_t len)
  555. {
  556. struct wlantest_bss *bss;
  557. struct wlantest_sta *sta;
  558. const struct ieee802_1x_hdr *eapol;
  559. const struct wpa_eapol_key *hdr;
  560. const u8 *key_data;
  561. u16 key_info, ver;
  562. u8 *decrypted;
  563. size_t decrypted_len = 0;
  564. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
  565. MAC2STR(src), MAC2STR(dst));
  566. bss = bss_get(wt, src);
  567. if (bss == NULL)
  568. return;
  569. sta = sta_get(bss, dst);
  570. if (sta == NULL)
  571. return;
  572. eapol = (const struct ieee802_1x_hdr *) data;
  573. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  574. key_info = WPA_GET_BE16(hdr->key_info);
  575. if (!sta->ptk_set) {
  576. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 1/2");
  577. return;
  578. }
  579. if (sta->ptk_set &&
  580. check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
  581. data, len) < 0) {
  582. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
  583. return;
  584. }
  585. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
  586. key_data = (const u8 *) (hdr + 1);
  587. if (sta->proto & WPA_PROTO_RSN &&
  588. !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
  589. wpa_printf(MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
  590. return;
  591. }
  592. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  593. decrypted = decrypt_eapol_key_data(sta->ptk.kek, ver, hdr,
  594. &decrypted_len);
  595. if (decrypted == NULL) {
  596. wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
  597. return;
  598. }
  599. wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
  600. decrypted, decrypted_len);
  601. if (wt->write_pcap_dumper) {
  602. /* Fill in a dummy Data frame header */
  603. u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
  604. struct ieee80211_hdr *h;
  605. struct wpa_eapol_key *k;
  606. u8 *pos;
  607. size_t plain_len;
  608. plain_len = decrypted_len;
  609. pos = decrypted;
  610. while (pos + 1 < decrypted + decrypted_len) {
  611. if (pos[0] == 0xdd && pos[1] == 0x00) {
  612. /* Remove padding */
  613. plain_len = pos - decrypted;
  614. break;
  615. }
  616. pos += 2 + pos[1];
  617. }
  618. os_memset(buf, 0, sizeof(buf));
  619. h = (struct ieee80211_hdr *) buf;
  620. h->frame_control = host_to_le16(0x0208);
  621. os_memcpy(h->addr1, dst, ETH_ALEN);
  622. os_memcpy(h->addr2, src, ETH_ALEN);
  623. os_memcpy(h->addr3, src, ETH_ALEN);
  624. pos = (u8 *) (h + 1);
  625. os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
  626. pos += 8;
  627. os_memcpy(pos, eapol, sizeof(*eapol));
  628. pos += sizeof(*eapol);
  629. os_memcpy(pos, hdr, sizeof(*hdr));
  630. k = (struct wpa_eapol_key *) pos;
  631. WPA_PUT_BE16(k->key_info,
  632. key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
  633. WPA_PUT_BE16(k->key_data_length, plain_len);
  634. write_pcap_decrypted(wt, buf, sizeof(buf),
  635. decrypted, plain_len);
  636. }
  637. if (sta->proto & WPA_PROTO_RSN)
  638. learn_kde_keys(bss, sta, decrypted, decrypted_len,
  639. hdr->key_rsc);
  640. else {
  641. int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
  642. if (decrypted_len == klen) {
  643. const u8 *rsc = hdr->key_rsc;
  644. int id;
  645. id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
  646. WPA_KEY_INFO_KEY_INDEX_SHIFT;
  647. wpa_printf(MSG_DEBUG, "GTK key index %d", id);
  648. wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
  649. decrypted_len);
  650. bss->gtk_len[id] = decrypted_len;
  651. os_memcpy(bss->gtk[id], decrypted, decrypted_len);
  652. bss->rsc[id][0] = rsc[5];
  653. bss->rsc[id][1] = rsc[4];
  654. bss->rsc[id][2] = rsc[3];
  655. bss->rsc[id][3] = rsc[2];
  656. bss->rsc[id][4] = rsc[1];
  657. bss->rsc[id][5] = rsc[0];
  658. wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
  659. } else {
  660. wpa_printf(MSG_INFO, "Unexpected WPA Key Data length "
  661. "in Group Key msg 1/2 from " MACSTR,
  662. MAC2STR(src));
  663. }
  664. }
  665. os_free(decrypted);
  666. }
  667. static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
  668. const u8 *src, const u8 *data, size_t len)
  669. {
  670. struct wlantest_bss *bss;
  671. struct wlantest_sta *sta;
  672. const struct ieee802_1x_hdr *eapol;
  673. const struct wpa_eapol_key *hdr;
  674. u16 key_info;
  675. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
  676. MAC2STR(src), MAC2STR(dst));
  677. bss = bss_get(wt, dst);
  678. if (bss == NULL)
  679. return;
  680. sta = sta_get(bss, src);
  681. if (sta == NULL)
  682. return;
  683. eapol = (const struct ieee802_1x_hdr *) data;
  684. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  685. if (!is_zero(hdr->key_rsc, 8)) {
  686. wpa_printf(MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
  687. "non-zero Key RSC", MAC2STR(src));
  688. }
  689. key_info = WPA_GET_BE16(hdr->key_info);
  690. if (!sta->ptk_set) {
  691. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/2");
  692. return;
  693. }
  694. if (sta->ptk_set &&
  695. check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
  696. data, len) < 0) {
  697. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
  698. return;
  699. }
  700. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
  701. }
  702. static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
  703. const u8 *src, const u8 *data, size_t len,
  704. int prot)
  705. {
  706. const struct ieee802_1x_hdr *eapol;
  707. const struct wpa_eapol_key *hdr;
  708. const u8 *key_data;
  709. u16 key_info, key_length, ver, key_data_length;
  710. eapol = (const struct ieee802_1x_hdr *) data;
  711. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  712. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
  713. (const u8 *) hdr, len - sizeof(*eapol));
  714. if (len < sizeof(*hdr)) {
  715. wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
  716. MAC2STR(src));
  717. return;
  718. }
  719. if (hdr->type == EAPOL_KEY_TYPE_RC4) {
  720. /* TODO: EAPOL-Key RC4 for WEP */
  721. wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
  722. MACSTR, MAC2STR(src));
  723. return;
  724. }
  725. if (hdr->type != EAPOL_KEY_TYPE_RSN &&
  726. hdr->type != EAPOL_KEY_TYPE_WPA) {
  727. wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
  728. "%u from " MACSTR, hdr->type, MAC2STR(src));
  729. return;
  730. }
  731. key_info = WPA_GET_BE16(hdr->key_info);
  732. key_length = WPA_GET_BE16(hdr->key_length);
  733. key_data_length = WPA_GET_BE16(hdr->key_data_length);
  734. key_data = (const u8 *) (hdr + 1);
  735. if (key_data + key_data_length > data + len) {
  736. wpa_printf(MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
  737. MAC2STR(src));
  738. return;
  739. }
  740. if (key_data + key_data_length < data + len) {
  741. wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
  742. "field", key_data + key_data_length,
  743. data + len - key_data - key_data_length);
  744. }
  745. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  746. wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
  747. "datalen=%u",
  748. ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
  749. (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
  750. WPA_KEY_INFO_KEY_INDEX_SHIFT,
  751. (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
  752. (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
  753. (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
  754. (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
  755. (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
  756. (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
  757. (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
  758. (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
  759. key_data_length);
  760. if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
  761. ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
  762. ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
  763. wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
  764. "Version %u from " MACSTR, ver, MAC2STR(src));
  765. return;
  766. }
  767. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
  768. hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
  769. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
  770. hdr->key_nonce, WPA_NONCE_LEN);
  771. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
  772. hdr->key_iv, 16);
  773. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
  774. hdr->key_rsc, WPA_KEY_RSC_LEN);
  775. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
  776. hdr->key_mic, 16);
  777. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
  778. key_data, key_data_length);
  779. if (hdr->type == EAPOL_KEY_TYPE_RSN &&
  780. (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
  781. 0) {
  782. wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
  783. "Key Info bits 0x%x from " MACSTR,
  784. key_info, MAC2STR(src));
  785. }
  786. if (hdr->type == EAPOL_KEY_TYPE_WPA &&
  787. (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
  788. WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
  789. wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
  790. "Key Info bits 0x%x from " MACSTR,
  791. key_info, MAC2STR(src));
  792. }
  793. if (key_length > 32) {
  794. wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
  795. "from " MACSTR, key_length, MAC2STR(src));
  796. }
  797. if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
  798. !is_zero(hdr->key_iv, 16)) {
  799. wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
  800. "(reserved with ver=%d) field from " MACSTR,
  801. ver, MAC2STR(src));
  802. wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
  803. hdr->key_iv, 16);
  804. }
  805. if (!is_zero(hdr->key_id, 8)) {
  806. wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
  807. "(reserved) field from " MACSTR, MAC2STR(src));
  808. wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
  809. hdr->key_id, 8);
  810. }
  811. if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
  812. wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
  813. "(last two are unused)" MACSTR, MAC2STR(src));
  814. }
  815. if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
  816. return;
  817. if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
  818. return;
  819. if (key_info & WPA_KEY_INFO_KEY_TYPE) {
  820. /* 4-Way Handshake */
  821. switch (key_info & (WPA_KEY_INFO_SECURE |
  822. WPA_KEY_INFO_MIC |
  823. WPA_KEY_INFO_ACK |
  824. WPA_KEY_INFO_INSTALL)) {
  825. case WPA_KEY_INFO_ACK:
  826. rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
  827. break;
  828. case WPA_KEY_INFO_MIC:
  829. if (key_data_length == 0)
  830. rx_data_eapol_key_4_of_4(wt, dst, src, data,
  831. len);
  832. else
  833. rx_data_eapol_key_2_of_4(wt, dst, src, data,
  834. len);
  835. break;
  836. case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
  837. WPA_KEY_INFO_INSTALL:
  838. /* WPA does not include Secure bit in 3/4 */
  839. rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
  840. break;
  841. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  842. WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
  843. rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
  844. break;
  845. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  846. if (key_data_length == 0)
  847. rx_data_eapol_key_4_of_4(wt, dst, src, data,
  848. len);
  849. else
  850. rx_data_eapol_key_2_of_4(wt, dst, src, data,
  851. len);
  852. break;
  853. default:
  854. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  855. break;
  856. }
  857. } else {
  858. /* Group Key Handshake */
  859. switch (key_info & (WPA_KEY_INFO_SECURE |
  860. WPA_KEY_INFO_MIC |
  861. WPA_KEY_INFO_ACK)) {
  862. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  863. WPA_KEY_INFO_ACK:
  864. rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
  865. break;
  866. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  867. rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
  868. break;
  869. default:
  870. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  871. break;
  872. }
  873. }
  874. }
  875. void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
  876. const u8 *data, size_t len, int prot)
  877. {
  878. const struct ieee802_1x_hdr *hdr;
  879. u16 length;
  880. const u8 *p;
  881. wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
  882. if (len < sizeof(*hdr)) {
  883. wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
  884. MAC2STR(src));
  885. return;
  886. }
  887. hdr = (const struct ieee802_1x_hdr *) data;
  888. length = be_to_host16(hdr->length);
  889. wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
  890. "type=%u len=%u",
  891. MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
  892. hdr->version, hdr->type, length);
  893. if (hdr->version < 1 || hdr->version > 3) {
  894. wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
  895. MACSTR, hdr->version, MAC2STR(src));
  896. }
  897. if (sizeof(*hdr) + length > len) {
  898. wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
  899. MAC2STR(src));
  900. return;
  901. }
  902. if (sizeof(*hdr) + length < len) {
  903. wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
  904. (int) (len - sizeof(*hdr) - length));
  905. }
  906. p = (const u8 *) (hdr + 1);
  907. switch (hdr->type) {
  908. case IEEE802_1X_TYPE_EAP_PACKET:
  909. wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
  910. break;
  911. case IEEE802_1X_TYPE_EAPOL_START:
  912. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
  913. break;
  914. case IEEE802_1X_TYPE_EAPOL_LOGOFF:
  915. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
  916. break;
  917. case IEEE802_1X_TYPE_EAPOL_KEY:
  918. rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
  919. prot);
  920. break;
  921. case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
  922. wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
  923. p, length);
  924. break;
  925. default:
  926. wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
  927. break;
  928. }
  929. }