wpa_ft.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499
  1. /*
  2. * hostapd - IEEE 802.11r - Fast BSS Transition
  3. * Copyright (c) 2004-2007, 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 "includes.h"
  15. #include "common.h"
  16. #include "config.h"
  17. #include "wpa.h"
  18. #include "aes_wrap.h"
  19. #include "ieee802_11.h"
  20. #include "defs.h"
  21. #include "wpa_auth_i.h"
  22. #include "wpa_auth_ie.h"
  23. #ifdef CONFIG_IEEE80211R
  24. static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
  25. const u8 *data, size_t data_len)
  26. {
  27. if (wpa_auth->cb.send_ether == NULL)
  28. return -1;
  29. return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB,
  30. data, data_len);
  31. }
  32. static int wpa_ft_action_send(struct wpa_authenticator *wpa_auth,
  33. const u8 *dst, const u8 *data, size_t data_len)
  34. {
  35. if (wpa_auth->cb.send_ft_action == NULL)
  36. return -1;
  37. return wpa_auth->cb.send_ft_action(wpa_auth->cb.ctx, dst,
  38. data, data_len);
  39. }
  40. static struct wpa_state_machine *
  41. wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
  42. {
  43. if (wpa_auth->cb.add_sta == NULL)
  44. return NULL;
  45. return wpa_auth->cb.add_sta(wpa_auth->cb.ctx, sta_addr);
  46. }
  47. int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len)
  48. {
  49. u8 *pos = buf;
  50. u8 capab;
  51. if (len < 2 + sizeof(struct rsn_mdie))
  52. return -1;
  53. *pos++ = WLAN_EID_MOBILITY_DOMAIN;
  54. *pos++ = MOBILITY_DOMAIN_ID_LEN + 1;
  55. os_memcpy(pos, conf->mobility_domain, MOBILITY_DOMAIN_ID_LEN);
  56. pos += MOBILITY_DOMAIN_ID_LEN;
  57. capab = RSN_FT_CAPAB_FT_OVER_DS;
  58. *pos++ = capab;
  59. return pos - buf;
  60. }
  61. static int wpa_write_ftie(struct wpa_auth_config *conf, const u8 *r0kh_id,
  62. size_t r0kh_id_len,
  63. const u8 *anonce, const u8 *snonce,
  64. u8 *buf, size_t len, const u8 *subelem,
  65. size_t subelem_len)
  66. {
  67. u8 *pos = buf, *ielen;
  68. struct rsn_ftie *hdr;
  69. if (len < 2 + sizeof(*hdr) + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
  70. subelem_len)
  71. return -1;
  72. *pos++ = WLAN_EID_FAST_BSS_TRANSITION;
  73. ielen = pos++;
  74. hdr = (struct rsn_ftie *) pos;
  75. os_memset(hdr, 0, sizeof(*hdr));
  76. pos += sizeof(*hdr);
  77. WPA_PUT_LE16(hdr->mic_control, 0);
  78. if (anonce)
  79. os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
  80. if (snonce)
  81. os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
  82. /* Optional Parameters */
  83. *pos++ = FTIE_SUBELEM_R1KH_ID;
  84. *pos++ = FT_R1KH_ID_LEN;
  85. os_memcpy(pos, conf->r1_key_holder, FT_R1KH_ID_LEN);
  86. pos += FT_R1KH_ID_LEN;
  87. if (r0kh_id) {
  88. *pos++ = FTIE_SUBELEM_R0KH_ID;
  89. *pos++ = r0kh_id_len;
  90. os_memcpy(pos, r0kh_id, r0kh_id_len);
  91. pos += r0kh_id_len;
  92. }
  93. if (subelem) {
  94. os_memcpy(pos, subelem, subelem_len);
  95. pos += subelem_len;
  96. }
  97. *ielen = pos - buf - 2;
  98. return pos - buf;
  99. }
  100. struct wpa_ft_pmk_r0_sa {
  101. struct wpa_ft_pmk_r0_sa *next;
  102. u8 pmk_r0[PMK_LEN];
  103. u8 pmk_r0_name[WPA_PMK_NAME_LEN];
  104. u8 spa[ETH_ALEN];
  105. /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
  106. int pmk_r1_pushed;
  107. };
  108. struct wpa_ft_pmk_r1_sa {
  109. struct wpa_ft_pmk_r1_sa *next;
  110. u8 pmk_r1[PMK_LEN];
  111. u8 pmk_r1_name[WPA_PMK_NAME_LEN];
  112. u8 spa[ETH_ALEN];
  113. /* TODO: expiration, identity, radius_class, EAP type, VLAN ID */
  114. };
  115. struct wpa_ft_pmk_cache {
  116. struct wpa_ft_pmk_r0_sa *pmk_r0;
  117. struct wpa_ft_pmk_r1_sa *pmk_r1;
  118. };
  119. struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void)
  120. {
  121. struct wpa_ft_pmk_cache *cache;
  122. cache = os_zalloc(sizeof(*cache));
  123. return cache;
  124. }
  125. void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache)
  126. {
  127. struct wpa_ft_pmk_r0_sa *r0, *r0prev;
  128. struct wpa_ft_pmk_r1_sa *r1, *r1prev;
  129. r0 = cache->pmk_r0;
  130. while (r0) {
  131. r0prev = r0;
  132. r0 = r0->next;
  133. os_memset(r0prev->pmk_r0, 0, PMK_LEN);
  134. os_free(r0prev);
  135. }
  136. r1 = cache->pmk_r1;
  137. while (r1) {
  138. r1prev = r1;
  139. r1 = r1->next;
  140. os_memset(r1prev->pmk_r1, 0, PMK_LEN);
  141. os_free(r1prev);
  142. }
  143. os_free(cache);
  144. }
  145. static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth,
  146. const u8 *spa, const u8 *pmk_r0,
  147. const u8 *pmk_r0_name)
  148. {
  149. struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
  150. struct wpa_ft_pmk_r0_sa *r0;
  151. /* TODO: add expiration and limit on number of entries in cache */
  152. r0 = os_zalloc(sizeof(*r0));
  153. if (r0 == NULL)
  154. return -1;
  155. os_memcpy(r0->pmk_r0, pmk_r0, PMK_LEN);
  156. os_memcpy(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
  157. os_memcpy(r0->spa, spa, ETH_ALEN);
  158. r0->next = cache->pmk_r0;
  159. cache->pmk_r0 = r0;
  160. return 0;
  161. }
  162. static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth,
  163. const u8 *spa, const u8 *pmk_r0_name,
  164. u8 *pmk_r0)
  165. {
  166. struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
  167. struct wpa_ft_pmk_r0_sa *r0;
  168. r0 = cache->pmk_r0;
  169. while (r0) {
  170. if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 &&
  171. os_memcmp(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN)
  172. == 0) {
  173. os_memcpy(pmk_r0, r0->pmk_r0, PMK_LEN);
  174. return 0;
  175. }
  176. r0 = r0->next;
  177. }
  178. return -1;
  179. }
  180. static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth,
  181. const u8 *spa, const u8 *pmk_r1,
  182. const u8 *pmk_r1_name)
  183. {
  184. struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
  185. struct wpa_ft_pmk_r1_sa *r1;
  186. /* TODO: add expiration and limit on number of entries in cache */
  187. r1 = os_zalloc(sizeof(*r1));
  188. if (r1 == NULL)
  189. return -1;
  190. os_memcpy(r1->pmk_r1, pmk_r1, PMK_LEN);
  191. os_memcpy(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
  192. os_memcpy(r1->spa, spa, ETH_ALEN);
  193. r1->next = cache->pmk_r1;
  194. cache->pmk_r1 = r1;
  195. return 0;
  196. }
  197. static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
  198. const u8 *spa, const u8 *pmk_r1_name,
  199. u8 *pmk_r1)
  200. {
  201. struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
  202. struct wpa_ft_pmk_r1_sa *r1;
  203. r1 = cache->pmk_r1;
  204. while (r1) {
  205. if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 &&
  206. os_memcmp(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN)
  207. == 0) {
  208. os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN);
  209. return 0;
  210. }
  211. r1 = r1->next;
  212. }
  213. return -1;
  214. }
  215. static int wpa_ft_pull_pmk_r1(struct wpa_authenticator *wpa_auth,
  216. const u8 *s1kh_id, const u8 *r0kh_id,
  217. size_t r0kh_id_len, const u8 *pmk_r0_name)
  218. {
  219. struct ft_remote_r0kh *r0kh;
  220. struct ft_r0kh_r1kh_pull_frame frame, f;
  221. r0kh = wpa_auth->conf.r0kh_list;
  222. while (r0kh) {
  223. if (r0kh->id_len == r0kh_id_len &&
  224. os_memcmp(r0kh->id, r0kh_id, r0kh_id_len) == 0)
  225. break;
  226. r0kh = r0kh->next;
  227. }
  228. if (r0kh == NULL)
  229. return -1;
  230. wpa_printf(MSG_DEBUG, "FT: Send PMK-R1 pull request to remote R0KH "
  231. "address " MACSTR, MAC2STR(r0kh->addr));
  232. os_memset(&frame, 0, sizeof(frame));
  233. frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
  234. frame.packet_type = FT_PACKET_R0KH_R1KH_PULL;
  235. frame.data_length = host_to_le16(FT_R0KH_R1KH_PULL_DATA_LEN);
  236. os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);
  237. /* aes_wrap() does not support inplace encryption, so use a temporary
  238. * buffer for the data. */
  239. if (os_get_random(f.nonce, sizeof(f.nonce))) {
  240. wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
  241. "nonce");
  242. return -1;
  243. }
  244. os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN);
  245. os_memcpy(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN);
  246. os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
  247. if (aes_wrap(r0kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
  248. f.nonce, frame.nonce) < 0)
  249. return -1;
  250. wpa_ft_rrb_send(wpa_auth, r0kh->addr, (u8 *) &frame, sizeof(frame));
  251. return 0;
  252. }
  253. int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
  254. struct wpa_ptk *ptk)
  255. {
  256. u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
  257. u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
  258. u8 ptk_name[WPA_PMK_NAME_LEN];
  259. const u8 *mdid = sm->wpa_auth->conf.mobility_domain;
  260. const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder;
  261. size_t r0kh_len = sm->wpa_auth->conf.r0_key_holder_len;
  262. const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder;
  263. const u8 *ssid = sm->wpa_auth->conf.ssid;
  264. size_t ssid_len = sm->wpa_auth->conf.ssid_len;
  265. if (sm->xxkey_len == 0) {
  266. wpa_printf(MSG_DEBUG, "FT: XXKey not available for key "
  267. "derivation");
  268. return -1;
  269. }
  270. wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, ssid, ssid_len, mdid,
  271. r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name);
  272. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN);
  273. wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN);
  274. wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name);
  275. wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr,
  276. pmk_r1, pmk_r1_name);
  277. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN);
  278. wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
  279. wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_name);
  280. wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
  281. sm->wpa_auth->addr, pmk_r1_name,
  282. (u8 *) ptk, sizeof(*ptk), ptk_name);
  283. wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, sizeof(*ptk));
  284. wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
  285. return 0;
  286. }
  287. static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
  288. const u8 *addr, int idx, u8 *seq)
  289. {
  290. if (wpa_auth->cb.get_seqnum == NULL)
  291. return -1;
  292. return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
  293. }
  294. #ifdef CONFIG_IEEE80211W
  295. static inline int wpa_auth_get_seqnum_igtk(struct wpa_authenticator *wpa_auth,
  296. const u8 *addr, int idx, u8 *seq)
  297. {
  298. if (wpa_auth->cb.get_seqnum_igtk == NULL)
  299. return -1;
  300. return wpa_auth->cb.get_seqnum_igtk(wpa_auth->cb.ctx, addr, idx, seq);
  301. }
  302. #endif /* CONFIG_IEEE80211W */
  303. static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
  304. {
  305. u8 *subelem;
  306. struct wpa_group *gsm = sm->group;
  307. size_t subelem_len, pad_len;
  308. const u8 *key;
  309. size_t key_len;
  310. u8 keybuf[32];
  311. key_len = gsm->GTK_len;
  312. if (key_len > sizeof(keybuf))
  313. return NULL;
  314. /*
  315. * Pad key for AES Key Wrap if it is not multiple of 8 bytes or is less
  316. * than 16 bytes.
  317. */
  318. pad_len = key_len % 8;
  319. if (pad_len)
  320. pad_len = 8 - pad_len;
  321. if (key_len + pad_len < 16)
  322. pad_len += 8;
  323. if (pad_len) {
  324. os_memcpy(keybuf, gsm->GTK[gsm->GN - 1], key_len);
  325. os_memset(keybuf + key_len, 0, pad_len);
  326. keybuf[key_len] = 0xdd;
  327. key_len += pad_len;
  328. key = keybuf;
  329. } else
  330. key = gsm->GTK[gsm->GN - 1];
  331. /*
  332. * Sub-elem ID[1] | Length[1] | Key Info[1] | Key Length[1] | RSC[8] |
  333. * Key[5..32].
  334. */
  335. subelem_len = 12 + key_len + 8;
  336. subelem = os_zalloc(subelem_len);
  337. if (subelem == NULL)
  338. return NULL;
  339. subelem[0] = FTIE_SUBELEM_GTK;
  340. subelem[1] = 10 + key_len + 8;
  341. subelem[2] = gsm->GN & 0x03; /* Key ID in B0-B1 of Key Info */
  342. subelem[3] = gsm->GTK_len;
  343. wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 4);
  344. if (aes_wrap(sm->PTK.kek, key_len / 8, key, subelem + 12)) {
  345. os_free(subelem);
  346. return NULL;
  347. }
  348. *len = subelem_len;
  349. return subelem;
  350. }
  351. #ifdef CONFIG_IEEE80211W
  352. static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
  353. {
  354. u8 *subelem, *pos;
  355. struct wpa_group *gsm = sm->group;
  356. size_t subelem_len;
  357. /* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
  358. * Key[16+8] */
  359. subelem_len = 1 + 1 + 2 + 6 + 1 + WPA_IGTK_LEN + 8;
  360. subelem = os_zalloc(subelem_len);
  361. if (subelem == NULL)
  362. return NULL;
  363. pos = subelem;
  364. *pos++ = FTIE_SUBELEM_IGTK;
  365. *pos++ = subelem_len - 2;
  366. WPA_PUT_LE16(pos, gsm->GN_igtk);
  367. pos += 2;
  368. wpa_auth_get_seqnum_igtk(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
  369. pos += 6;
  370. *pos++ = WPA_IGTK_LEN;
  371. if (aes_wrap(sm->PTK.kek, WPA_IGTK_LEN / 8,
  372. gsm->IGTK[gsm->GN_igtk - 4], pos)) {
  373. os_free(subelem);
  374. return NULL;
  375. }
  376. *len = subelem_len;
  377. return subelem;
  378. }
  379. #endif /* CONFIG_IEEE80211W */
  380. u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
  381. size_t max_len, int auth_alg)
  382. {
  383. u8 *end, *mdie, *ftie, *rsnie, *r0kh_id, *subelem = NULL;
  384. size_t mdie_len, ftie_len, rsnie_len, r0kh_id_len, subelem_len = 0;
  385. int res;
  386. struct wpa_auth_config *conf;
  387. struct rsn_ftie *_ftie;
  388. if (sm == NULL)
  389. return pos;
  390. conf = &sm->wpa_auth->conf;
  391. if (sm->wpa_key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X &&
  392. sm->wpa_key_mgmt != WPA_KEY_MGMT_FT_PSK)
  393. return pos;
  394. end = pos + max_len;
  395. /* RSN */
  396. res = wpa_write_rsn_ie(conf, pos, end - pos, sm->pmk_r1_name);
  397. if (res < 0)
  398. return pos;
  399. rsnie = pos;
  400. rsnie_len = res;
  401. pos += res;
  402. /* Mobility Domain Information */
  403. res = wpa_write_mdie(conf, pos, end - pos);
  404. if (res < 0)
  405. return pos;
  406. mdie = pos;
  407. mdie_len = res;
  408. pos += res;
  409. /* Fast BSS Transition Information */
  410. if (auth_alg == WLAN_AUTH_FT) {
  411. subelem = wpa_ft_gtk_subelem(sm, &subelem_len);
  412. r0kh_id = sm->r0kh_id;
  413. r0kh_id_len = sm->r0kh_id_len;
  414. #ifdef CONFIG_IEEE80211W
  415. if (sm->mgmt_frame_prot) {
  416. u8 *igtk;
  417. size_t igtk_len;
  418. u8 *nbuf;
  419. igtk = wpa_ft_igtk_subelem(sm, &igtk_len);
  420. if (igtk == NULL) {
  421. os_free(subelem);
  422. return pos;
  423. }
  424. nbuf = os_realloc(subelem, subelem_len + igtk_len);
  425. if (nbuf == NULL) {
  426. os_free(subelem);
  427. os_free(igtk);
  428. return pos;
  429. }
  430. subelem = nbuf;
  431. os_memcpy(subelem + subelem_len, igtk, igtk_len);
  432. subelem_len += igtk_len;
  433. os_free(igtk);
  434. }
  435. #endif /* CONFIG_IEEE80211W */
  436. } else {
  437. r0kh_id = conf->r0_key_holder;
  438. r0kh_id_len = conf->r0_key_holder_len;
  439. }
  440. res = wpa_write_ftie(conf, r0kh_id, r0kh_id_len, NULL, NULL, pos,
  441. end - pos, subelem, subelem_len);
  442. os_free(subelem);
  443. if (res < 0)
  444. return pos;
  445. ftie = pos;
  446. ftie_len = res;
  447. pos += res;
  448. _ftie = (struct rsn_ftie *) (ftie + 2);
  449. _ftie->mic_control[1] = 3; /* Information element count */
  450. if (wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 6,
  451. mdie, mdie_len, ftie, ftie_len,
  452. rsnie, rsnie_len, NULL, 0, _ftie->mic) < 0)
  453. wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
  454. return pos;
  455. }
  456. struct wpa_ft_ies {
  457. const u8 *mdie;
  458. size_t mdie_len;
  459. const u8 *ftie;
  460. size_t ftie_len;
  461. const u8 *r1kh_id;
  462. const u8 *gtk;
  463. size_t gtk_len;
  464. const u8 *r0kh_id;
  465. size_t r0kh_id_len;
  466. const u8 *rsn;
  467. size_t rsn_len;
  468. const u8 *rsn_pmkid;
  469. };
  470. static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
  471. struct wpa_ft_ies *parse)
  472. {
  473. const u8 *end, *pos;
  474. parse->ftie = ie;
  475. parse->ftie_len = ie_len;
  476. pos = ie + sizeof(struct rsn_ftie);
  477. end = ie + ie_len;
  478. while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
  479. switch (pos[0]) {
  480. case FTIE_SUBELEM_R1KH_ID:
  481. if (pos[1] != FT_R1KH_ID_LEN) {
  482. wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
  483. "length in FTIE: %d", pos[1]);
  484. return -1;
  485. }
  486. parse->r1kh_id = pos + 2;
  487. break;
  488. case FTIE_SUBELEM_GTK:
  489. parse->gtk = pos + 2;
  490. parse->gtk_len = pos[1];
  491. break;
  492. case FTIE_SUBELEM_R0KH_ID:
  493. if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
  494. wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
  495. "length in FTIE: %d", pos[1]);
  496. return -1;
  497. }
  498. parse->r0kh_id = pos + 2;
  499. parse->r0kh_id_len = pos[1];
  500. break;
  501. }
  502. pos += 2 + pos[1];
  503. }
  504. return 0;
  505. }
  506. static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
  507. struct wpa_ft_ies *parse)
  508. {
  509. const u8 *end, *pos;
  510. struct wpa_ie_data data;
  511. int ret;
  512. os_memset(parse, 0, sizeof(*parse));
  513. if (ies == NULL)
  514. return 0;
  515. pos = ies;
  516. end = ies + ies_len;
  517. while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
  518. switch (pos[0]) {
  519. case WLAN_EID_RSN:
  520. parse->rsn = pos + 2;
  521. parse->rsn_len = pos[1];
  522. ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
  523. parse->rsn_len + 2,
  524. &data);
  525. if (ret < 0) {
  526. wpa_printf(MSG_DEBUG, "FT: Failed to parse "
  527. "RSN IE: %d", ret);
  528. return -1;
  529. }
  530. if (data.num_pmkid == 1 && data.pmkid)
  531. parse->rsn_pmkid = data.pmkid;
  532. break;
  533. case WLAN_EID_MOBILITY_DOMAIN:
  534. parse->mdie = pos + 2;
  535. parse->mdie_len = pos[1];
  536. break;
  537. case WLAN_EID_FAST_BSS_TRANSITION:
  538. if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
  539. return -1;
  540. break;
  541. }
  542. pos += 2 + pos[1];
  543. }
  544. return 0;
  545. }
  546. static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
  547. int vlan_id,
  548. const char *alg, const u8 *addr, int idx,
  549. u8 *key, size_t key_len)
  550. {
  551. if (wpa_auth->cb.set_key == NULL)
  552. return -1;
  553. return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
  554. key, key_len);
  555. }
  556. static void wpa_ft_install_ptk(struct wpa_state_machine *sm)
  557. {
  558. char *alg;
  559. int klen;
  560. /* MLME-SETKEYS.request(PTK) */
  561. if (sm->pairwise == WPA_CIPHER_TKIP) {
  562. alg = "TKIP";
  563. klen = 32;
  564. } else if (sm->pairwise == WPA_CIPHER_CCMP) {
  565. alg = "CCMP";
  566. klen = 16;
  567. } else
  568. return;
  569. /* FIX: add STA entry to kernel/driver here? The set_key will fail
  570. * most likely without this.. At the moment, STA entry is added only
  571. * after association has been completed. Alternatively, could
  572. * re-configure PTK at that point(?).
  573. */
  574. if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
  575. sm->PTK.tk1, klen))
  576. return;
  577. /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
  578. sm->pairwise_set = TRUE;
  579. }
  580. static u16 wpa_ft_process_auth_req(struct wpa_state_machine *sm,
  581. const u8 *ies, size_t ies_len,
  582. u8 **resp_ies, size_t *resp_ies_len)
  583. {
  584. struct rsn_mdie *mdie;
  585. struct rsn_ftie *ftie;
  586. u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
  587. u8 ptk_name[WPA_PMK_NAME_LEN];
  588. struct wpa_auth_config *conf;
  589. struct wpa_ft_ies parse;
  590. size_t buflen;
  591. int ret;
  592. u8 *pos, *end;
  593. *resp_ies = NULL;
  594. *resp_ies_len = 0;
  595. sm->pmk_r1_name_valid = 0;
  596. conf = &sm->wpa_auth->conf;
  597. wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
  598. ies, ies_len);
  599. if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
  600. wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
  601. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  602. }
  603. mdie = (struct rsn_mdie *) parse.mdie;
  604. if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
  605. os_memcmp(mdie->mobility_domain,
  606. sm->wpa_auth->conf.mobility_domain,
  607. MOBILITY_DOMAIN_ID_LEN) != 0) {
  608. wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
  609. return WLAN_STATUS_INVALID_MDIE;
  610. }
  611. ftie = (struct rsn_ftie *) parse.ftie;
  612. if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
  613. wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
  614. return WLAN_STATUS_INVALID_FTIE;
  615. }
  616. os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN);
  617. if (parse.r0kh_id == NULL) {
  618. wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID");
  619. return WLAN_STATUS_INVALID_FTIE;
  620. }
  621. wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID",
  622. parse.r0kh_id, parse.r0kh_id_len);
  623. os_memcpy(sm->r0kh_id, parse.r0kh_id, parse.r0kh_id_len);
  624. sm->r0kh_id_len = parse.r0kh_id_len;
  625. if (parse.rsn_pmkid == NULL) {
  626. wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
  627. return WLAN_STATUS_INVALID_PMKID;
  628. }
  629. wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name",
  630. parse.rsn_pmkid, WPA_PMK_NAME_LEN);
  631. wpa_derive_pmk_r1_name(parse.rsn_pmkid,
  632. sm->wpa_auth->conf.r1_key_holder, sm->addr,
  633. pmk_r1_name);
  634. wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
  635. pmk_r1_name, WPA_PMK_NAME_LEN);
  636. if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, pmk_r1) <
  637. 0) {
  638. if (wpa_ft_pull_pmk_r1(sm->wpa_auth, sm->addr, sm->r0kh_id,
  639. sm->r0kh_id_len, parse.rsn_pmkid) < 0) {
  640. wpa_printf(MSG_DEBUG, "FT: Did not have matching "
  641. "PMK-R1 and unknown R0KH-ID");
  642. return WLAN_STATUS_INVALID_PMKID;
  643. }
  644. /*
  645. * TODO: Should return "status pending" (and the caller should
  646. * not send out response now). The real response will be sent
  647. * once the response from R0KH is received.
  648. */
  649. return WLAN_STATUS_INVALID_PMKID;
  650. }
  651. wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN);
  652. sm->pmk_r1_name_valid = 1;
  653. os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN);
  654. if (os_get_random(sm->ANonce, WPA_NONCE_LEN)) {
  655. wpa_printf(MSG_DEBUG, "FT: Failed to get random data for "
  656. "ANonce");
  657. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  658. }
  659. wpa_hexdump(MSG_DEBUG, "FT: Received SNonce",
  660. sm->SNonce, WPA_NONCE_LEN);
  661. wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
  662. sm->ANonce, WPA_NONCE_LEN);
  663. wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
  664. sm->wpa_auth->addr, pmk_r1_name,
  665. (u8 *) &sm->PTK, sizeof(sm->PTK), ptk_name);
  666. wpa_hexdump_key(MSG_DEBUG, "FT: PTK",
  667. (u8 *) &sm->PTK, sizeof(sm->PTK));
  668. wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
  669. wpa_ft_install_ptk(sm);
  670. buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
  671. 2 + FT_R1KH_ID_LEN + 200;
  672. *resp_ies = os_zalloc(buflen);
  673. if (*resp_ies == NULL) {
  674. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  675. }
  676. pos = *resp_ies;
  677. end = *resp_ies + buflen;
  678. ret = wpa_write_rsn_ie(conf, pos, end - pos, parse.rsn_pmkid);
  679. if (ret < 0) {
  680. os_free(*resp_ies);
  681. *resp_ies = NULL;
  682. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  683. }
  684. pos += ret;
  685. ret = wpa_write_mdie(conf, pos, end - pos);
  686. if (ret < 0) {
  687. os_free(*resp_ies);
  688. *resp_ies = NULL;
  689. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  690. }
  691. pos += ret;
  692. ret = wpa_write_ftie(conf, parse.r0kh_id, parse.r0kh_id_len,
  693. sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0);
  694. if (ret < 0) {
  695. os_free(*resp_ies);
  696. *resp_ies = NULL;
  697. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  698. }
  699. pos += ret;
  700. *resp_ies_len = pos - *resp_ies;
  701. return WLAN_STATUS_SUCCESS;
  702. }
  703. void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
  704. u16 auth_transaction, const u8 *ies, size_t ies_len,
  705. void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
  706. u16 auth_transaction, u16 status,
  707. const u8 *ies, size_t ies_len),
  708. void *ctx)
  709. {
  710. u16 status;
  711. u8 *resp_ies;
  712. size_t resp_ies_len;
  713. if (sm == NULL) {
  714. wpa_printf(MSG_DEBUG, "FT: Received authentication frame, but "
  715. "WPA SM not available");
  716. return;
  717. }
  718. wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
  719. " BSSID=" MACSTR " transaction=%d",
  720. MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
  721. status = wpa_ft_process_auth_req(sm, ies, ies_len, &resp_ies,
  722. &resp_ies_len);
  723. wpa_printf(MSG_DEBUG, "FT: FT authentication response: dst=" MACSTR
  724. " auth_transaction=%d status=%d",
  725. MAC2STR(sm->addr), auth_transaction + 1, status);
  726. wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
  727. cb(ctx, sm->addr, bssid, auth_transaction + 1, status,
  728. resp_ies, resp_ies_len);
  729. os_free(resp_ies);
  730. }
  731. u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
  732. size_t ies_len)
  733. {
  734. struct wpa_ft_ies parse;
  735. struct rsn_mdie *mdie;
  736. struct rsn_ftie *ftie;
  737. u8 mic[16];
  738. if (sm == NULL)
  739. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  740. wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
  741. if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
  742. wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
  743. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  744. }
  745. if (parse.rsn == NULL) {
  746. wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req");
  747. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  748. }
  749. if (parse.rsn_pmkid == NULL) {
  750. wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE");
  751. return WLAN_STATUS_INVALID_PMKID;
  752. }
  753. if (os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
  754. {
  755. wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match "
  756. "with the PMKR1Name derived from auth request");
  757. return WLAN_STATUS_INVALID_PMKID;
  758. }
  759. mdie = (struct rsn_mdie *) parse.mdie;
  760. if (mdie == NULL || parse.mdie_len < sizeof(*mdie) ||
  761. os_memcmp(mdie->mobility_domain,
  762. sm->wpa_auth->conf.mobility_domain,
  763. MOBILITY_DOMAIN_ID_LEN) != 0) {
  764. wpa_printf(MSG_DEBUG, "FT: Invalid MDIE");
  765. return WLAN_STATUS_INVALID_MDIE;
  766. }
  767. ftie = (struct rsn_ftie *) parse.ftie;
  768. if (ftie == NULL || parse.ftie_len < sizeof(*ftie)) {
  769. wpa_printf(MSG_DEBUG, "FT: Invalid FTIE");
  770. return WLAN_STATUS_INVALID_FTIE;
  771. }
  772. /*
  773. * Assume that MDIE, FTIE, and RSN IE are protected and that there is
  774. * no RIC, so total of 3 protected IEs.
  775. */
  776. if (ftie->mic_control[1] != 3) {
  777. wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in FTIE (%d)",
  778. ftie->mic_control[1]);
  779. return WLAN_STATUS_INVALID_FTIE;
  780. }
  781. if (wpa_ft_mic(sm->PTK.kck, sm->addr, sm->wpa_auth->addr, 5,
  782. parse.mdie - 2, parse.mdie_len + 2,
  783. parse.ftie - 2, parse.ftie_len + 2,
  784. parse.rsn - 2, parse.rsn_len + 2, NULL, 0,
  785. mic) < 0) {
  786. wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC");
  787. return WLAN_STATUS_UNSPECIFIED_FAILURE;
  788. }
  789. if (os_memcmp(mic, ftie->mic, 16) != 0) {
  790. wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
  791. wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
  792. wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
  793. return WLAN_STATUS_INVALID_FTIE;
  794. }
  795. return WLAN_STATUS_SUCCESS;
  796. }
  797. int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
  798. {
  799. const u8 *sta_addr, *target_ap;
  800. const u8 *ies;
  801. size_t ies_len;
  802. u8 action;
  803. struct ft_rrb_frame *frame;
  804. if (sm == NULL)
  805. return -1;
  806. /*
  807. * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
  808. * FT Request action frame body[variable]
  809. */
  810. if (len < 14) {
  811. wpa_printf(MSG_DEBUG, "FT: Too short FT Action frame "
  812. "(len=%lu)", (unsigned long) len);
  813. return -1;
  814. }
  815. action = data[1];
  816. sta_addr = data + 2;
  817. target_ap = data + 8;
  818. ies = data + 14;
  819. ies_len = len - 14;
  820. wpa_printf(MSG_DEBUG, "FT: Received FT Action frame (STA=" MACSTR
  821. " Target AP=" MACSTR " Action=%d)",
  822. MAC2STR(sta_addr), MAC2STR(target_ap), action);
  823. if (os_memcmp(sta_addr, sm->addr, ETH_ALEN) != 0) {
  824. wpa_printf(MSG_DEBUG, "FT: Mismatch in FT Action STA address: "
  825. "STA=" MACSTR " STA-Address=" MACSTR,
  826. MAC2STR(sm->addr), MAC2STR(sta_addr));
  827. return -1;
  828. }
  829. /*
  830. * Do some sanity checking on the target AP address (not own and not
  831. * broadcast. This could be extended to filter based on a list of known
  832. * APs in the MD (if such a list were configured).
  833. */
  834. if ((target_ap[0] & 0x01) ||
  835. os_memcmp(target_ap, sm->wpa_auth->addr, ETH_ALEN) == 0) {
  836. wpa_printf(MSG_DEBUG, "FT: Invalid Target AP in FT Action "
  837. "frame");
  838. return -1;
  839. }
  840. wpa_hexdump(MSG_MSGDUMP, "FT: Action frame body", ies, ies_len);
  841. /* RRB - Forward action frame to the target AP */
  842. frame = os_malloc(sizeof(*frame) + len);
  843. frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
  844. frame->packet_type = FT_PACKET_REQUEST;
  845. frame->action_length = host_to_le16(len);
  846. os_memcpy(frame->ap_address, sm->wpa_auth->addr, ETH_ALEN);
  847. os_memcpy(frame + 1, data, len);
  848. wpa_ft_rrb_send(sm->wpa_auth, target_ap, (u8 *) frame,
  849. sizeof(*frame) + len);
  850. os_free(frame);
  851. return 0;
  852. }
  853. static int wpa_ft_rrb_rx_request(struct wpa_authenticator *wpa_auth,
  854. const u8 *current_ap, const u8 *sta_addr,
  855. const u8 *body, size_t len)
  856. {
  857. struct wpa_state_machine *sm;
  858. u16 status;
  859. u8 *resp_ies, *pos;
  860. size_t resp_ies_len, rlen;
  861. struct ft_rrb_frame *frame;
  862. sm = wpa_ft_add_sta(wpa_auth, sta_addr);
  863. if (sm == NULL) {
  864. wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
  865. "RRB Request");
  866. return -1;
  867. }
  868. wpa_hexdump(MSG_MSGDUMP, "FT: RRB Request Frame body", body, len);
  869. status = wpa_ft_process_auth_req(sm, body, len, &resp_ies,
  870. &resp_ies_len);
  871. wpa_printf(MSG_DEBUG, "FT: RRB authentication response: STA=" MACSTR
  872. " CurrentAP=" MACSTR " status=%d",
  873. MAC2STR(sm->addr), MAC2STR(current_ap), status);
  874. wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
  875. /* RRB - Forward action frame response to the Current AP */
  876. /*
  877. * data: Category[1] Action[1] STA_Address[6] Target_AP_Address[6]
  878. * Status_Code[2] FT Request action frame body[variable]
  879. */
  880. rlen = 2 + 2 * ETH_ALEN + 2 + resp_ies_len;
  881. frame = os_malloc(sizeof(*frame) + rlen);
  882. frame->frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
  883. frame->packet_type = FT_PACKET_RESPONSE;
  884. frame->action_length = host_to_le16(rlen);
  885. os_memcpy(frame->ap_address, wpa_auth->addr, ETH_ALEN);
  886. pos = (u8 *) (frame + 1);
  887. *pos++ = WLAN_ACTION_FT;
  888. *pos++ = 2; /* Action: Response */
  889. os_memcpy(pos, sta_addr, ETH_ALEN);
  890. pos += ETH_ALEN;
  891. os_memcpy(pos, wpa_auth->addr, ETH_ALEN);
  892. pos += ETH_ALEN;
  893. WPA_PUT_LE16(pos, status);
  894. pos += 2;
  895. if (resp_ies) {
  896. os_memcpy(pos, resp_ies, resp_ies_len);
  897. os_free(resp_ies);
  898. }
  899. wpa_ft_rrb_send(wpa_auth, current_ap, (u8 *) frame,
  900. sizeof(*frame) + rlen);
  901. os_free(frame);
  902. return 0;
  903. }
  904. static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth,
  905. const u8 *src_addr,
  906. const u8 *data, size_t data_len)
  907. {
  908. struct ft_r0kh_r1kh_pull_frame *frame, f;
  909. struct ft_remote_r1kh *r1kh;
  910. struct ft_r0kh_r1kh_resp_frame resp, r;
  911. u8 pmk_r0[PMK_LEN];
  912. wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull");
  913. if (data_len < sizeof(*frame))
  914. return -1;
  915. r1kh = wpa_auth->conf.r1kh_list;
  916. while (r1kh) {
  917. if (os_memcmp(r1kh->addr, src_addr, ETH_ALEN) == 0)
  918. break;
  919. r1kh = r1kh->next;
  920. }
  921. if (r1kh == NULL) {
  922. wpa_printf(MSG_DEBUG, "FT: No matching R1KH address found for "
  923. "PMK-R1 pull source address " MACSTR,
  924. MAC2STR(src_addr));
  925. return -1;
  926. }
  927. frame = (struct ft_r0kh_r1kh_pull_frame *) data;
  928. /* aes_unwrap() does not support inplace decryption, so use a temporary
  929. * buffer for the data. */
  930. if (aes_unwrap(r1kh->key, (FT_R0KH_R1KH_PULL_DATA_LEN + 7) / 8,
  931. frame->nonce, f.nonce) < 0) {
  932. wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
  933. "request from " MACSTR, MAC2STR(src_addr));
  934. return -1;
  935. }
  936. wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
  937. f.nonce, sizeof(f.nonce));
  938. wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name",
  939. f.pmk_r0_name, WPA_PMK_NAME_LEN);
  940. wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR "S1KH-ID="
  941. MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
  942. os_memset(&resp, 0, sizeof(resp));
  943. resp.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
  944. resp.packet_type = FT_PACKET_R0KH_R1KH_RESP;
  945. resp.data_length = host_to_le16(FT_R0KH_R1KH_RESP_DATA_LEN);
  946. os_memcpy(resp.ap_address, wpa_auth->addr, ETH_ALEN);
  947. /* aes_wrap() does not support inplace encryption, so use a temporary
  948. * buffer for the data. */
  949. os_memcpy(r.nonce, f.nonce, sizeof(f.nonce));
  950. os_memcpy(r.r1kh_id, f.r1kh_id, FT_R1KH_ID_LEN);
  951. os_memcpy(r.s1kh_id, f.s1kh_id, ETH_ALEN);
  952. if (wpa_ft_fetch_pmk_r0(wpa_auth, f.s1kh_id, f.pmk_r0_name, pmk_r0) <
  953. 0) {
  954. wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name found for "
  955. "PMK-R1 pull");
  956. return -1;
  957. }
  958. wpa_derive_pmk_r1(pmk_r0, f.pmk_r0_name, f.r1kh_id, f.s1kh_id,
  959. r.pmk_r1, r.pmk_r1_name);
  960. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN);
  961. wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name,
  962. WPA_PMK_NAME_LEN);
  963. if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
  964. r.nonce, resp.nonce) < 0) {
  965. os_memset(pmk_r0, 0, PMK_LEN);
  966. return -1;
  967. }
  968. os_memset(pmk_r0, 0, PMK_LEN);
  969. wpa_ft_rrb_send(wpa_auth, src_addr, (u8 *) &resp, sizeof(resp));
  970. return 0;
  971. }
  972. static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth,
  973. const u8 *src_addr,
  974. const u8 *data, size_t data_len)
  975. {
  976. struct ft_r0kh_r1kh_resp_frame *frame, f;
  977. struct ft_remote_r0kh *r0kh;
  978. wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response");
  979. if (data_len < sizeof(*frame))
  980. return -1;
  981. r0kh = wpa_auth->conf.r0kh_list;
  982. while (r0kh) {
  983. if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
  984. break;
  985. r0kh = r0kh->next;
  986. }
  987. if (r0kh == NULL) {
  988. wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
  989. "PMK-R0 pull response source address " MACSTR,
  990. MAC2STR(src_addr));
  991. return -1;
  992. }
  993. frame = (struct ft_r0kh_r1kh_resp_frame *) data;
  994. /* aes_unwrap() does not support inplace decryption, so use a temporary
  995. * buffer for the data. */
  996. if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
  997. frame->nonce, f.nonce) < 0) {
  998. wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 pull "
  999. "response from " MACSTR, MAC2STR(src_addr));
  1000. return -1;
  1001. }
  1002. if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN)
  1003. != 0) {
  1004. wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a "
  1005. "matching R1KH-ID");
  1006. return -1;
  1007. }
  1008. /* TODO: verify that <nonce,s1kh_id> matches with a pending request
  1009. * and call this requests callback function to finish request
  1010. * processing */
  1011. wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce",
  1012. f.nonce, sizeof(f.nonce));
  1013. wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull - R1KH-ID=" MACSTR "S1KH-ID="
  1014. MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
  1015. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 pull - PMK-R1",
  1016. f.pmk_r1, PMK_LEN);
  1017. wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR1Name",
  1018. f.pmk_r1_name, WPA_PMK_NAME_LEN);
  1019. wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name);
  1020. os_memset(f.pmk_r1, 0, PMK_LEN);
  1021. return 0;
  1022. }
  1023. static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth,
  1024. const u8 *src_addr,
  1025. const u8 *data, size_t data_len)
  1026. {
  1027. struct ft_r0kh_r1kh_push_frame *frame, f;
  1028. struct ft_remote_r0kh *r0kh;
  1029. struct os_time now;
  1030. os_time_t tsend;
  1031. wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 push");
  1032. if (data_len < sizeof(*frame))
  1033. return -1;
  1034. r0kh = wpa_auth->conf.r0kh_list;
  1035. while (r0kh) {
  1036. if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0)
  1037. break;
  1038. r0kh = r0kh->next;
  1039. }
  1040. if (r0kh == NULL) {
  1041. wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for "
  1042. "PMK-R0 push source address " MACSTR,
  1043. MAC2STR(src_addr));
  1044. return -1;
  1045. }
  1046. frame = (struct ft_r0kh_r1kh_push_frame *) data;
  1047. /* aes_unwrap() does not support inplace decryption, so use a temporary
  1048. * buffer for the data. */
  1049. if (aes_unwrap(r0kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
  1050. frame->timestamp, f.timestamp) < 0) {
  1051. wpa_printf(MSG_DEBUG, "FT: Failed to decrypt PMK-R1 push from "
  1052. MACSTR, MAC2STR(src_addr));
  1053. return -1;
  1054. }
  1055. os_get_time(&now);
  1056. tsend = WPA_GET_LE32(f.timestamp);
  1057. if ((now.sec > tsend && now.sec - tsend > 60) ||
  1058. (now.sec < tsend && tsend - now.sec > 60)) {
  1059. wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not have a valid "
  1060. "timestamp: sender time %d own time %d\n",
  1061. (int) tsend, (int) now.sec);
  1062. return -1;
  1063. }
  1064. if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN)
  1065. != 0) {
  1066. wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching "
  1067. "R1KH-ID (received " MACSTR " own " MACSTR ")",
  1068. MAC2STR(f.r1kh_id),
  1069. MAC2STR(wpa_auth->conf.r1_key_holder));
  1070. return -1;
  1071. }
  1072. wpa_printf(MSG_DEBUG, "FT: PMK-R1 push - R1KH-ID=" MACSTR " S1KH-ID="
  1073. MACSTR, MAC2STR(f.r1kh_id), MAC2STR(f.s1kh_id));
  1074. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 push - PMK-R1",
  1075. f.pmk_r1, PMK_LEN);
  1076. wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 push - PMKR1Name",
  1077. f.pmk_r1_name, WPA_PMK_NAME_LEN);
  1078. wpa_ft_store_pmk_r1(wpa_auth, f.s1kh_id, f.pmk_r1, f.pmk_r1_name);
  1079. os_memset(f.pmk_r1, 0, PMK_LEN);
  1080. return 0;
  1081. }
  1082. int wpa_ft_rrb_rx(struct wpa_authenticator *wpa_auth, const u8 *src_addr,
  1083. const u8 *data, size_t data_len)
  1084. {
  1085. struct ft_rrb_frame *frame;
  1086. u16 alen;
  1087. const u8 *pos, *end, *start;
  1088. u8 action;
  1089. const u8 *sta_addr, *target_ap_addr;
  1090. wpa_printf(MSG_DEBUG, "FT: RRB received frame from remote AP " MACSTR,
  1091. MAC2STR(src_addr));
  1092. if (data_len < sizeof(*frame)) {
  1093. wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (data_len=%lu)",
  1094. (unsigned long) data_len);
  1095. return -1;
  1096. }
  1097. pos = data;
  1098. frame = (struct ft_rrb_frame *) pos;
  1099. pos += sizeof(*frame);
  1100. alen = le_to_host16(frame->action_length);
  1101. wpa_printf(MSG_DEBUG, "FT: RRB frame - frame_type=%d packet_type=%d "
  1102. "action_length=%d ap_address=" MACSTR,
  1103. frame->frame_type, frame->packet_type, alen,
  1104. MAC2STR(frame->ap_address));
  1105. if (frame->frame_type != RSN_REMOTE_FRAME_TYPE_FT_RRB) {
  1106. /* Discard frame per IEEE Std 802.11r-2008, 11A.10.3 */
  1107. wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with "
  1108. "unrecognized type %d", frame->frame_type);
  1109. return -1;
  1110. }
  1111. if (alen > data_len - sizeof(*frame)) {
  1112. wpa_printf(MSG_DEBUG, "FT: RRB frame too short for action "
  1113. "frame");
  1114. return -1;
  1115. }
  1116. if (frame->packet_type == FT_PACKET_R0KH_R1KH_PULL)
  1117. return wpa_ft_rrb_rx_pull(wpa_auth, src_addr, data, data_len);
  1118. if (frame->packet_type == FT_PACKET_R0KH_R1KH_RESP)
  1119. return wpa_ft_rrb_rx_resp(wpa_auth, src_addr, data, data_len);
  1120. if (frame->packet_type == FT_PACKET_R0KH_R1KH_PUSH)
  1121. return wpa_ft_rrb_rx_push(wpa_auth, src_addr, data, data_len);
  1122. wpa_hexdump(MSG_MSGDUMP, "FT: RRB - FT Action frame", pos, alen);
  1123. if (alen < 1 + 1 + 2 * ETH_ALEN) {
  1124. wpa_printf(MSG_DEBUG, "FT: Too short RRB frame (not enough "
  1125. "room for Action Frame body); alen=%lu",
  1126. (unsigned long) alen);
  1127. return -1;
  1128. }
  1129. start = pos;
  1130. end = pos + alen;
  1131. if (*pos != WLAN_ACTION_FT) {
  1132. wpa_printf(MSG_DEBUG, "FT: Unexpected Action frame category "
  1133. "%d", *pos);
  1134. return -1;
  1135. }
  1136. pos++;
  1137. action = *pos++;
  1138. sta_addr = pos;
  1139. pos += ETH_ALEN;
  1140. target_ap_addr = pos;
  1141. pos += ETH_ALEN;
  1142. wpa_printf(MSG_DEBUG, "FT: RRB Action Frame: action=%d sta_addr="
  1143. MACSTR " target_ap_addr=" MACSTR,
  1144. action, MAC2STR(sta_addr), MAC2STR(target_ap_addr));
  1145. if (frame->packet_type == FT_PACKET_REQUEST) {
  1146. wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Request");
  1147. if (action != 1) {
  1148. wpa_printf(MSG_DEBUG, "FT: Unexpected Action %d in "
  1149. "RRB Request", action);
  1150. return -1;
  1151. }
  1152. if (os_memcmp(target_ap_addr, wpa_auth->addr, ETH_ALEN) != 0) {
  1153. wpa_printf(MSG_DEBUG, "FT: Target AP address in the "
  1154. "RRB Request does not match with own "
  1155. "address");
  1156. return -1;
  1157. }
  1158. if (wpa_ft_rrb_rx_request(wpa_auth, frame->ap_address,
  1159. sta_addr, pos, end - pos) < 0)
  1160. return -1;
  1161. } else if (frame->packet_type == FT_PACKET_RESPONSE) {
  1162. u16 status_code;
  1163. if (end - pos < 2) {
  1164. wpa_printf(MSG_DEBUG, "FT: Not enough room for status "
  1165. "code in RRB Response");
  1166. return -1;
  1167. }
  1168. status_code = WPA_GET_LE16(pos);
  1169. pos += 2;
  1170. wpa_printf(MSG_DEBUG, "FT: FT Packet Type - Response "
  1171. "(status_code=%d)", status_code);
  1172. if (wpa_ft_action_send(wpa_auth, sta_addr, start, alen) < 0)
  1173. return -1;
  1174. } else {
  1175. wpa_printf(MSG_DEBUG, "FT: RRB discarded frame with unknown "
  1176. "packet_type %d", frame->packet_type);
  1177. return -1;
  1178. }
  1179. return 0;
  1180. }
  1181. static void wpa_ft_generate_pmk_r1(struct wpa_authenticator *wpa_auth,
  1182. struct wpa_ft_pmk_r0_sa *pmk_r0,
  1183. struct ft_remote_r1kh *r1kh,
  1184. const u8 *s1kh_id)
  1185. {
  1186. struct ft_r0kh_r1kh_push_frame frame, f;
  1187. struct os_time now;
  1188. os_memset(&frame, 0, sizeof(frame));
  1189. frame.frame_type = RSN_REMOTE_FRAME_TYPE_FT_RRB;
  1190. frame.packet_type = FT_PACKET_R0KH_R1KH_PUSH;
  1191. frame.data_length = host_to_le16(FT_R0KH_R1KH_PUSH_DATA_LEN);
  1192. os_memcpy(frame.ap_address, wpa_auth->addr, ETH_ALEN);
  1193. /* aes_wrap() does not support inplace encryption, so use a temporary
  1194. * buffer for the data. */
  1195. os_memcpy(f.r1kh_id, r1kh->id, FT_R1KH_ID_LEN);
  1196. os_memcpy(f.s1kh_id, s1kh_id, ETH_ALEN);
  1197. os_memcpy(f.pmk_r0_name, pmk_r0->pmk_r0_name, WPA_PMK_NAME_LEN);
  1198. wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh->id,
  1199. s1kh_id, f.pmk_r1, f.pmk_r1_name);
  1200. wpa_printf(MSG_DEBUG, "FT: R1KH-ID " MACSTR, MAC2STR(r1kh->id));
  1201. wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", f.pmk_r1, PMK_LEN);
  1202. wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", f.pmk_r1_name,
  1203. WPA_PMK_NAME_LEN);
  1204. os_get_time(&now);
  1205. WPA_PUT_LE32(f.timestamp, now.sec);
  1206. if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
  1207. f.timestamp, frame.timestamp) < 0)
  1208. return;
  1209. wpa_ft_rrb_send(wpa_auth, r1kh->addr, (u8 *) &frame, sizeof(frame));
  1210. }
  1211. void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr)
  1212. {
  1213. struct wpa_ft_pmk_r0_sa *r0;
  1214. struct ft_remote_r1kh *r1kh;
  1215. if (!wpa_auth->conf.pmk_r1_push)
  1216. return;
  1217. r0 = wpa_auth->ft_pmk_cache->pmk_r0;
  1218. while (r0) {
  1219. if (os_memcmp(r0->spa, addr, ETH_ALEN) == 0)
  1220. break;
  1221. r0 = r0->next;
  1222. }
  1223. if (r0 == NULL || r0->pmk_r1_pushed)
  1224. return;
  1225. r0->pmk_r1_pushed = 1;
  1226. wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs "
  1227. "for STA " MACSTR, MAC2STR(addr));
  1228. r1kh = wpa_auth->conf.r1kh_list;
  1229. while (r1kh) {
  1230. wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr);
  1231. r1kh = r1kh->next;
  1232. }
  1233. }
  1234. #endif /* CONFIG_IEEE80211R */