rx_tdls.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * Received Data frame processing for TDLS packets
  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/sha256.h"
  17. #include "crypto/crypto.h"
  18. #include "crypto/aes_wrap.h"
  19. #include "common/ieee802_11_defs.h"
  20. #include "common/ieee802_11_common.h"
  21. #include "wlantest.h"
  22. static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid)
  23. {
  24. struct wlantest_bss *bss;
  25. struct wlantest_sta *init, *resp;
  26. struct wlantest_tdls *tdls;
  27. bss = bss_find(wt, linkid);
  28. if (bss == NULL)
  29. return NULL;
  30. init = sta_find(bss, linkid + ETH_ALEN);
  31. if (init == NULL)
  32. return NULL;
  33. resp = sta_find(bss, linkid + 2 * ETH_ALEN);
  34. if (resp == NULL)
  35. return NULL;
  36. dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
  37. if (tdls->init == init && tdls->resp == resp)
  38. return tdls;
  39. }
  40. tdls = os_zalloc(sizeof(*tdls));
  41. if (tdls == NULL)
  42. return NULL;
  43. tdls->init = init;
  44. tdls->resp = resp;
  45. dl_list_add(&bss->tdls, &tdls->list);
  46. return tdls;
  47. }
  48. static int tdls_derive_tpk(struct wlantest_tdls *tdls, const u8 *bssid,
  49. const u8 *ftie, u8 ftie_len)
  50. {
  51. const struct rsn_ftie *f;
  52. u8 key_input[SHA256_MAC_LEN];
  53. const u8 *nonce[2];
  54. size_t len[2];
  55. u8 data[3 * ETH_ALEN];
  56. if (ftie == NULL || ftie_len < sizeof(struct rsn_ftie))
  57. return 0;
  58. f = (const struct rsn_ftie *) ftie;
  59. wpa_hexdump(MSG_DEBUG, "TDLS ANonce", f->anonce, WPA_NONCE_LEN);
  60. wpa_hexdump(MSG_DEBUG, "TDLS SNonce", f->snonce, WPA_NONCE_LEN);
  61. /*
  62. * IEEE Std 802.11z-2010 8.5.9.1:
  63. * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce))
  64. */
  65. len[0] = WPA_NONCE_LEN;
  66. len[1] = WPA_NONCE_LEN;
  67. if (os_memcmp(f->anonce, f->snonce, WPA_NONCE_LEN) < 0) {
  68. nonce[0] = f->anonce;
  69. nonce[1] = f->snonce;
  70. } else {
  71. nonce[0] = f->snonce;
  72. nonce[1] = f->anonce;
  73. }
  74. sha256_vector(2, nonce, len, key_input);
  75. wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input",
  76. key_input, SHA256_MAC_LEN);
  77. /*
  78. * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK",
  79. * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY)
  80. * TODO: is N_KEY really included in KDF Context and if so, in which
  81. * presentation format (little endian 16-bit?) is it used? It gets
  82. * added by the KDF anyway..
  83. */
  84. if (os_memcmp(tdls->init->addr, tdls->resp->addr, ETH_ALEN) < 0) {
  85. os_memcpy(data, tdls->init->addr, ETH_ALEN);
  86. os_memcpy(data + ETH_ALEN, tdls->resp->addr, ETH_ALEN);
  87. } else {
  88. os_memcpy(data, tdls->resp->addr, ETH_ALEN);
  89. os_memcpy(data + ETH_ALEN, tdls->init->addr, ETH_ALEN);
  90. }
  91. os_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN);
  92. wpa_hexdump(MSG_DEBUG, "TDLS: KDF Context", data, sizeof(data));
  93. sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data),
  94. (u8 *) &tdls->tpk, sizeof(tdls->tpk));
  95. wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK",
  96. tdls->tpk.kck, sizeof(tdls->tpk.kck));
  97. wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK",
  98. tdls->tpk.tk, sizeof(tdls->tpk.tk));
  99. return 1;
  100. }
  101. static int tdls_verify_mic(struct wlantest_tdls *tdls, u8 trans_seq,
  102. struct ieee802_11_elems *elems)
  103. {
  104. u8 *buf, *pos;
  105. int len;
  106. u8 mic[16];
  107. int ret;
  108. const struct rsn_ftie *rx_ftie;
  109. struct rsn_ftie *tmp_ftie;
  110. if (elems->link_id == NULL || elems->rsn_ie == NULL ||
  111. elems->timeout_int == NULL || elems->ftie == NULL)
  112. return -1;
  113. len = 2 * ETH_ALEN + 1 + 2 + 18 + 2 + elems->rsn_ie_len +
  114. 2 + elems->timeout_int_len + 2 + elems->ftie_len;
  115. buf = os_zalloc(len);
  116. if (buf == NULL)
  117. return -1;
  118. pos = buf;
  119. /* 1) TDLS initiator STA MAC address */
  120. os_memcpy(pos, elems->link_id + ETH_ALEN, ETH_ALEN);
  121. pos += ETH_ALEN;
  122. /* 2) TDLS responder STA MAC address */
  123. os_memcpy(pos, elems->link_id + 2 * ETH_ALEN, ETH_ALEN);
  124. pos += ETH_ALEN;
  125. /* 3) Transaction Sequence number */
  126. *pos++ = trans_seq;
  127. /* 4) Link Identifier IE */
  128. os_memcpy(pos, elems->link_id - 2, 2 + 18);
  129. pos += 2 + 18;
  130. /* 5) RSN IE */
  131. os_memcpy(pos, elems->rsn_ie - 2, 2 + elems->rsn_ie_len);
  132. pos += 2 + elems->rsn_ie_len;
  133. /* 6) Timeout Interval IE */
  134. os_memcpy(pos, elems->timeout_int - 2, 2 + elems->timeout_int_len);
  135. pos += 2 + elems->timeout_int_len;
  136. /* 7) FTIE, with the MIC field of the FTIE set to 0 */
  137. os_memcpy(pos, elems->ftie - 2, 2 + elems->ftie_len);
  138. pos += 2;
  139. tmp_ftie = (struct rsn_ftie *) pos;
  140. os_memset(tmp_ftie->mic, 0, 16);
  141. pos += elems->ftie_len;
  142. wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
  143. wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", tdls->tpk.kck, 16);
  144. ret = omac1_aes_128(tdls->tpk.kck, buf, pos - buf, mic);
  145. os_free(buf);
  146. if (ret)
  147. return -1;
  148. wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
  149. rx_ftie = (const struct rsn_ftie *) elems->ftie;
  150. if (os_memcmp(mic, rx_ftie->mic, 16) == 0) {
  151. wpa_printf(MSG_DEBUG, "TDLS: Valid MIC");
  152. return 0;
  153. }
  154. wpa_printf(MSG_DEBUG, "TDLS: Invalid MIC");
  155. return -1;
  156. }
  157. static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
  158. const u8 *sta_addr, const u8 *dst,
  159. const u8 *src,
  160. const u8 *data, size_t len)
  161. {
  162. struct ieee802_11_elems elems;
  163. struct wlantest_tdls *tdls;
  164. if (len < 3)
  165. return;
  166. wpa_printf(MSG_DEBUG, "TDLS Setup Request " MACSTR " -> "
  167. MACSTR, MAC2STR(src), MAC2STR(dst));
  168. if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
  169. ParseFailed || elems.link_id == NULL)
  170. return;
  171. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  172. " initiator STA " MACSTR " responder STA " MACSTR,
  173. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  174. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  175. tdls = get_tdls(wt, elems.link_id);
  176. if (tdls)
  177. tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
  178. }
  179. static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
  180. const u8 *sta_addr, const u8 *dst,
  181. const u8 *src,
  182. const u8 *data, size_t len)
  183. {
  184. u16 status;
  185. struct ieee802_11_elems elems;
  186. struct wlantest_tdls *tdls;
  187. if (len < 5)
  188. return;
  189. status = WPA_GET_LE16(data);
  190. wpa_printf(MSG_DEBUG, "TDLS Setup Response " MACSTR " -> "
  191. MACSTR " (status %d)",
  192. MAC2STR(src), MAC2STR(dst), status);
  193. if (status != WLAN_STATUS_SUCCESS)
  194. return;
  195. if (ieee802_11_parse_elems(data + 5, len - 5, &elems, 1) ==
  196. ParseFailed || elems.link_id == NULL)
  197. return;
  198. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  199. " initiator STA " MACSTR " responder STA " MACSTR,
  200. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  201. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  202. tdls = get_tdls(wt, elems.link_id);
  203. if (!tdls)
  204. return;
  205. if (status)
  206. tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++;
  207. else
  208. tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_OK]++;
  209. if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
  210. return;
  211. if (tdls_verify_mic(tdls, 2, &elems) == 0) {
  212. tdls->dialog_token = data[2];
  213. wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
  214. tdls->dialog_token);
  215. }
  216. }
  217. static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
  218. const u8 *sta_addr, const u8 *dst,
  219. const u8 *src,
  220. const u8 *data, size_t len)
  221. {
  222. u16 status;
  223. struct ieee802_11_elems elems;
  224. struct wlantest_tdls *tdls;
  225. if (len < 3)
  226. return;
  227. status = WPA_GET_LE16(data);
  228. wpa_printf(MSG_DEBUG, "TDLS Setup Confirm " MACSTR " -> "
  229. MACSTR " (status %d)",
  230. MAC2STR(src), MAC2STR(dst), status);
  231. if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
  232. ParseFailed || elems.link_id == NULL)
  233. return;
  234. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  235. " initiator STA " MACSTR " responder STA " MACSTR,
  236. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  237. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  238. tdls = get_tdls(wt, elems.link_id);
  239. if (tdls == NULL)
  240. return;
  241. if (status)
  242. tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL]++;
  243. else
  244. tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_CONF_OK]++;
  245. if (status != WLAN_STATUS_SUCCESS)
  246. return;
  247. tdls->link_up = 1;
  248. if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
  249. return;
  250. if (tdls_verify_mic(tdls, 3, &elems) == 0) {
  251. tdls->dialog_token = data[2];
  252. wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
  253. tdls->dialog_token);
  254. }
  255. }
  256. static int tdls_verify_mic_teardown(struct wlantest_tdls *tdls, u8 trans_seq,
  257. const u8 *reason_code,
  258. struct ieee802_11_elems *elems)
  259. {
  260. u8 *buf, *pos;
  261. int len;
  262. u8 mic[16];
  263. int ret;
  264. const struct rsn_ftie *rx_ftie;
  265. struct rsn_ftie *tmp_ftie;
  266. if (elems->link_id == NULL || elems->ftie == NULL)
  267. return -1;
  268. len = 2 + 18 + 2 + 1 + 1 + 2 + elems->ftie_len;
  269. buf = os_zalloc(len);
  270. if (buf == NULL)
  271. return -1;
  272. pos = buf;
  273. /* 1) Link Identifier IE */
  274. os_memcpy(pos, elems->link_id - 2, 2 + 18);
  275. pos += 2 + 18;
  276. /* 2) Reason Code */
  277. os_memcpy(pos, reason_code, 2);
  278. pos += 2;
  279. /* 3) Dialog token */
  280. *pos++ = tdls->dialog_token;
  281. /* 4) Transaction Sequence number */
  282. *pos++ = trans_seq;
  283. /* 5) FTIE, with the MIC field of the FTIE set to 0 */
  284. os_memcpy(pos, elems->ftie - 2, 2 + elems->ftie_len);
  285. pos += 2;
  286. tmp_ftie = (struct rsn_ftie *) pos;
  287. os_memset(tmp_ftie->mic, 0, 16);
  288. pos += elems->ftie_len;
  289. wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
  290. wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", tdls->tpk.kck, 16);
  291. ret = omac1_aes_128(tdls->tpk.kck, buf, pos - buf, mic);
  292. os_free(buf);
  293. if (ret)
  294. return -1;
  295. wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
  296. rx_ftie = (const struct rsn_ftie *) elems->ftie;
  297. if (os_memcmp(mic, rx_ftie->mic, 16) == 0) {
  298. wpa_printf(MSG_DEBUG, "TDLS: Valid MIC");
  299. return 0;
  300. }
  301. wpa_printf(MSG_DEBUG, "TDLS: Invalid MIC");
  302. return -1;
  303. }
  304. static void rx_data_tdls_teardown(struct wlantest *wt, const u8 *bssid,
  305. const u8 *sta_addr, const u8 *dst,
  306. const u8 *src,
  307. const u8 *data, size_t len)
  308. {
  309. u16 reason;
  310. struct ieee802_11_elems elems;
  311. struct wlantest_tdls *tdls;
  312. if (len < 2)
  313. return;
  314. reason = WPA_GET_LE16(data);
  315. wpa_printf(MSG_DEBUG, "TDLS Teardown " MACSTR " -> "
  316. MACSTR " (reason %d)",
  317. MAC2STR(src), MAC2STR(dst), reason);
  318. if (ieee802_11_parse_elems(data + 2, len - 2, &elems, 1) ==
  319. ParseFailed || elems.link_id == NULL)
  320. return;
  321. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  322. " initiator STA " MACSTR " responder STA " MACSTR,
  323. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  324. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  325. tdls = get_tdls(wt, elems.link_id);
  326. if (tdls) {
  327. tdls->link_up = 0;
  328. tdls_verify_mic_teardown(tdls, 4, data, &elems);
  329. }
  330. }
  331. static void rx_data_tdls(struct wlantest *wt, const u8 *bssid,
  332. const u8 *sta_addr, const u8 *dst, const u8 *src,
  333. const u8 *data, size_t len)
  334. {
  335. /* data contains the payload of a TDLS Action frame */
  336. if (len < 2 || data[0] != WLAN_ACTION_TDLS) {
  337. wpa_hexdump(MSG_DEBUG, "Unrecognized encapsulated TDLS frame",
  338. data, len);
  339. return;
  340. }
  341. switch (data[1]) {
  342. case WLAN_TDLS_SETUP_REQUEST:
  343. rx_data_tdls_setup_request(wt, bssid, sta_addr, dst, src,
  344. data + 2, len - 2);
  345. break;
  346. case WLAN_TDLS_SETUP_RESPONSE:
  347. rx_data_tdls_setup_response(wt, bssid, sta_addr, dst, src,
  348. data + 2, len - 2);
  349. break;
  350. case WLAN_TDLS_SETUP_CONFIRM:
  351. rx_data_tdls_setup_confirm(wt, bssid, sta_addr, dst, src,
  352. data + 2, len - 2);
  353. break;
  354. case WLAN_TDLS_TEARDOWN:
  355. rx_data_tdls_teardown(wt, bssid, sta_addr, dst, src, data + 2,
  356. len - 2);
  357. break;
  358. case WLAN_TDLS_DISCOVERY_REQUEST:
  359. wpa_printf(MSG_DEBUG, "TDLS Discovery Request " MACSTR " -> "
  360. MACSTR, MAC2STR(src), MAC2STR(dst));
  361. break;
  362. }
  363. }
  364. void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
  365. const u8 *sta_addr, const u8 *dst, const u8 *src,
  366. const u8 *data, size_t len)
  367. {
  368. wpa_hexdump(MSG_EXCESSIVE, "802.11 data encap frame", data, len);
  369. if (len < 1)
  370. return;
  371. if (data[0] == 0x02)
  372. rx_data_tdls(wt, bssid, sta_addr, dst, src, data + 1, len - 1);
  373. }