rx_eapol.c 31 KB

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