rx_eapol.c 29 KB

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