rx_tdls.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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. if (len < 3)
  164. return;
  165. wpa_printf(MSG_DEBUG, "TDLS Setup Request " MACSTR " -> "
  166. MACSTR, MAC2STR(src), MAC2STR(dst));
  167. if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
  168. ParseFailed || elems.link_id == NULL)
  169. return;
  170. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  171. " initiator STA " MACSTR " responder STA " MACSTR,
  172. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  173. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  174. get_tdls(wt, elems.link_id);
  175. }
  176. static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
  177. const u8 *sta_addr, const u8 *dst,
  178. const u8 *src,
  179. const u8 *data, size_t len)
  180. {
  181. u16 status;
  182. struct ieee802_11_elems elems;
  183. struct wlantest_tdls *tdls;
  184. if (len < 5)
  185. return;
  186. status = WPA_GET_LE16(data);
  187. wpa_printf(MSG_DEBUG, "TDLS Setup Response " MACSTR " -> "
  188. MACSTR " (status %d)",
  189. MAC2STR(src), MAC2STR(dst), status);
  190. if (status != WLAN_STATUS_SUCCESS)
  191. return;
  192. if (ieee802_11_parse_elems(data + 5, len - 5, &elems, 1) ==
  193. ParseFailed || elems.link_id == NULL)
  194. return;
  195. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  196. " initiator STA " MACSTR " responder STA " MACSTR,
  197. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  198. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  199. tdls = get_tdls(wt, elems.link_id);
  200. if (!tdls)
  201. return;
  202. if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
  203. return;
  204. if (tdls_verify_mic(tdls, 2, &elems) == 0) {
  205. tdls->dialog_token = data[2];
  206. wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
  207. tdls->dialog_token);
  208. }
  209. }
  210. static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
  211. const u8 *sta_addr, const u8 *dst,
  212. const u8 *src,
  213. const u8 *data, size_t len)
  214. {
  215. u16 status;
  216. struct ieee802_11_elems elems;
  217. struct wlantest_tdls *tdls;
  218. if (len < 3)
  219. return;
  220. status = WPA_GET_LE16(data);
  221. wpa_printf(MSG_DEBUG, "TDLS Setup Confirm " MACSTR " -> "
  222. MACSTR " (status %d)",
  223. MAC2STR(src), MAC2STR(dst), status);
  224. if (status != WLAN_STATUS_SUCCESS)
  225. return;
  226. if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
  227. ParseFailed || elems.link_id == NULL)
  228. return;
  229. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  230. " initiator STA " MACSTR " responder STA " MACSTR,
  231. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  232. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  233. tdls = get_tdls(wt, elems.link_id);
  234. if (tdls == NULL)
  235. return;
  236. tdls->link_up = 1;
  237. if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
  238. return;
  239. if (tdls_verify_mic(tdls, 3, &elems) == 0) {
  240. tdls->dialog_token = data[2];
  241. wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
  242. tdls->dialog_token);
  243. }
  244. }
  245. static int tdls_verify_mic_teardown(struct wlantest_tdls *tdls, u8 trans_seq,
  246. const u8 *reason_code,
  247. struct ieee802_11_elems *elems)
  248. {
  249. u8 *buf, *pos;
  250. int len;
  251. u8 mic[16];
  252. int ret;
  253. const struct rsn_ftie *rx_ftie;
  254. struct rsn_ftie *tmp_ftie;
  255. if (elems->link_id == NULL || elems->ftie == NULL)
  256. return -1;
  257. len = 2 + 18 + 2 + 1 + 1 + 2 + elems->ftie_len;
  258. buf = os_zalloc(len);
  259. if (buf == NULL)
  260. return -1;
  261. pos = buf;
  262. /* 1) Link Identifier IE */
  263. os_memcpy(pos, elems->link_id - 2, 2 + 18);
  264. pos += 2 + 18;
  265. /* 2) Reason Code */
  266. os_memcpy(pos, reason_code, 2);
  267. pos += 2;
  268. /* 3) Dialog token */
  269. *pos++ = tdls->dialog_token;
  270. /* 4) Transaction Sequence number */
  271. *pos++ = trans_seq;
  272. /* 5) FTIE, with the MIC field of the FTIE set to 0 */
  273. os_memcpy(pos, elems->ftie - 2, 2 + elems->ftie_len);
  274. pos += 2;
  275. tmp_ftie = (struct rsn_ftie *) pos;
  276. os_memset(tmp_ftie->mic, 0, 16);
  277. pos += elems->ftie_len;
  278. wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
  279. wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", tdls->tpk.kck, 16);
  280. ret = omac1_aes_128(tdls->tpk.kck, buf, pos - buf, mic);
  281. os_free(buf);
  282. if (ret)
  283. return -1;
  284. wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
  285. rx_ftie = (const struct rsn_ftie *) elems->ftie;
  286. if (os_memcmp(mic, rx_ftie->mic, 16) == 0) {
  287. wpa_printf(MSG_DEBUG, "TDLS: Valid MIC");
  288. return 0;
  289. }
  290. wpa_printf(MSG_DEBUG, "TDLS: Invalid MIC");
  291. return -1;
  292. }
  293. static void rx_data_tdls_teardown(struct wlantest *wt, const u8 *bssid,
  294. const u8 *sta_addr, const u8 *dst,
  295. const u8 *src,
  296. const u8 *data, size_t len)
  297. {
  298. u16 reason;
  299. struct ieee802_11_elems elems;
  300. struct wlantest_tdls *tdls;
  301. if (len < 2)
  302. return;
  303. reason = WPA_GET_LE16(data);
  304. wpa_printf(MSG_DEBUG, "TDLS Teardown " MACSTR " -> "
  305. MACSTR " (reason %d)",
  306. MAC2STR(src), MAC2STR(dst), reason);
  307. if (ieee802_11_parse_elems(data + 2, len - 2, &elems, 1) ==
  308. ParseFailed || elems.link_id == NULL)
  309. return;
  310. wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
  311. " initiator STA " MACSTR " responder STA " MACSTR,
  312. MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
  313. MAC2STR(elems.link_id + 2 * ETH_ALEN));
  314. tdls = get_tdls(wt, elems.link_id);
  315. if (tdls) {
  316. tdls->link_up = 0;
  317. tdls_verify_mic_teardown(tdls, 4, data, &elems);
  318. }
  319. }
  320. static void rx_data_tdls(struct wlantest *wt, const u8 *bssid,
  321. const u8 *sta_addr, const u8 *dst, const u8 *src,
  322. const u8 *data, size_t len)
  323. {
  324. /* data contains the payload of a TDLS Action frame */
  325. if (len < 2 || data[0] != WLAN_ACTION_TDLS) {
  326. wpa_hexdump(MSG_DEBUG, "Unrecognized encapsulated TDLS frame",
  327. data, len);
  328. return;
  329. }
  330. switch (data[1]) {
  331. case WLAN_TDLS_SETUP_REQUEST:
  332. rx_data_tdls_setup_request(wt, bssid, sta_addr, dst, src,
  333. data + 2, len - 2);
  334. break;
  335. case WLAN_TDLS_SETUP_RESPONSE:
  336. rx_data_tdls_setup_response(wt, bssid, sta_addr, dst, src,
  337. data + 2, len - 2);
  338. break;
  339. case WLAN_TDLS_SETUP_CONFIRM:
  340. rx_data_tdls_setup_confirm(wt, bssid, sta_addr, dst, src,
  341. data + 2, len - 2);
  342. break;
  343. case WLAN_TDLS_TEARDOWN:
  344. rx_data_tdls_teardown(wt, bssid, sta_addr, dst, src, data + 2,
  345. len - 2);
  346. break;
  347. case WLAN_TDLS_DISCOVERY_REQUEST:
  348. wpa_printf(MSG_DEBUG, "TDLS Discovery Request " MACSTR " -> "
  349. MACSTR, MAC2STR(src), MAC2STR(dst));
  350. break;
  351. }
  352. }
  353. void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
  354. const u8 *sta_addr, const u8 *dst, const u8 *src,
  355. const u8 *data, size_t len)
  356. {
  357. wpa_hexdump(MSG_EXCESSIVE, "802.11 data encap frame", data, len);
  358. if (len < 1)
  359. return;
  360. if (data[0] == 0x02)
  361. rx_data_tdls(wt, bssid, sta_addr, dst, src, data + 1, len - 1);
  362. }