peerkey.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. /*
  2. * WPA Supplicant - PeerKey for Direct Link Setup (DLS)
  3. * Copyright (c) 2006-2008, 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. #ifdef CONFIG_PEERKEY
  16. #include "common.h"
  17. #include "eloop.h"
  18. #include "crypto/sha1.h"
  19. #include "crypto/sha256.h"
  20. #include "crypto/random.h"
  21. #include "common/ieee802_11_defs.h"
  22. #include "wpa.h"
  23. #include "wpa_i.h"
  24. #include "wpa_ie.h"
  25. #include "peerkey.h"
  26. static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
  27. {
  28. os_memcpy(pos, ie, ie_len);
  29. return pos + ie_len;
  30. }
  31. static u8 * wpa_add_kde(u8 *pos, u32 kde, const u8 *data, size_t data_len)
  32. {
  33. *pos++ = WLAN_EID_VENDOR_SPECIFIC;
  34. *pos++ = RSN_SELECTOR_LEN + data_len;
  35. RSN_SELECTOR_PUT(pos, kde);
  36. pos += RSN_SELECTOR_LEN;
  37. os_memcpy(pos, data, data_len);
  38. pos += data_len;
  39. return pos;
  40. }
  41. static void wpa_supplicant_smk_timeout(void *eloop_ctx, void *timeout_ctx)
  42. {
  43. #if 0
  44. struct wpa_sm *sm = eloop_ctx;
  45. struct wpa_peerkey *peerkey = timeout_ctx;
  46. #endif
  47. /* TODO: time out SMK and any STK that was generated using this SMK */
  48. }
  49. static void wpa_supplicant_peerkey_free(struct wpa_sm *sm,
  50. struct wpa_peerkey *peerkey)
  51. {
  52. eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
  53. os_free(peerkey);
  54. }
  55. static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
  56. const u8 *peer,
  57. u16 mui, u16 error_type, int ver)
  58. {
  59. size_t rlen;
  60. struct wpa_eapol_key *err;
  61. struct rsn_error_kde error;
  62. u8 *rbuf, *pos;
  63. size_t kde_len;
  64. u16 key_info;
  65. kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
  66. if (peer)
  67. kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
  68. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
  69. NULL, sizeof(*err) + kde_len, &rlen,
  70. (void *) &err);
  71. if (rbuf == NULL)
  72. return -1;
  73. err->type = EAPOL_KEY_TYPE_RSN;
  74. key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  75. WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
  76. WPA_KEY_INFO_REQUEST;
  77. WPA_PUT_BE16(err->key_info, key_info);
  78. WPA_PUT_BE16(err->key_length, 0);
  79. os_memcpy(err->replay_counter, sm->request_counter,
  80. WPA_REPLAY_COUNTER_LEN);
  81. inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
  82. WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
  83. pos = (u8 *) (err + 1);
  84. if (peer) {
  85. /* Peer MAC Address KDE */
  86. pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
  87. }
  88. /* Error KDE */
  89. error.mui = host_to_be16(mui);
  90. error.error_type = host_to_be16(error_type);
  91. wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));
  92. if (peer) {
  93. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
  94. MACSTR " mui %d error_type %d)",
  95. MAC2STR(peer), mui, error_type);
  96. } else {
  97. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
  98. "(mui %d error_type %d)", mui, error_type);
  99. }
  100. wpa_eapol_key_send(sm, sm->ptk.kck, ver, dst, ETH_P_EAPOL,
  101. rbuf, rlen, err->key_mic);
  102. return 0;
  103. }
  104. static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
  105. const unsigned char *src_addr,
  106. const struct wpa_eapol_key *key,
  107. int ver, struct wpa_peerkey *peerkey)
  108. {
  109. size_t rlen;
  110. struct wpa_eapol_key *reply;
  111. u8 *rbuf, *pos;
  112. size_t kde_len;
  113. u16 key_info;
  114. /* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */
  115. kde_len = peerkey->rsnie_p_len +
  116. 2 + RSN_SELECTOR_LEN + ETH_ALEN +
  117. 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;
  118. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
  119. NULL, sizeof(*reply) + kde_len, &rlen,
  120. (void *) &reply);
  121. if (rbuf == NULL)
  122. return -1;
  123. reply->type = EAPOL_KEY_TYPE_RSN;
  124. key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  125. WPA_KEY_INFO_SECURE;
  126. WPA_PUT_BE16(reply->key_info, key_info);
  127. WPA_PUT_BE16(reply->key_length, 0);
  128. os_memcpy(reply->replay_counter, key->replay_counter,
  129. WPA_REPLAY_COUNTER_LEN);
  130. os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);
  131. WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
  132. pos = (u8 *) (reply + 1);
  133. /* Peer RSN IE */
  134. pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
  135. /* Initiator MAC Address KDE */
  136. pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
  137. /* Initiator Nonce */
  138. wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
  139. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
  140. wpa_eapol_key_send(sm, sm->ptk.kck, ver, src_addr, ETH_P_EAPOL,
  141. rbuf, rlen, reply->key_mic);
  142. return 0;
  143. }
  144. static int wpa_supplicant_process_smk_m2(
  145. struct wpa_sm *sm, const unsigned char *src_addr,
  146. const struct wpa_eapol_key *key, size_t extra_len, int ver)
  147. {
  148. struct wpa_peerkey *peerkey;
  149. struct wpa_eapol_ie_parse kde;
  150. struct wpa_ie_data ie;
  151. int cipher;
  152. struct rsn_ie_hdr *hdr;
  153. u8 *pos;
  154. wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");
  155. if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
  156. wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
  157. "the current network");
  158. return -1;
  159. }
  160. if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
  161. 0) {
  162. wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
  163. return -1;
  164. }
  165. if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
  166. kde.mac_addr_len < ETH_ALEN) {
  167. wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
  168. "SMK M2");
  169. return -1;
  170. }
  171. wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
  172. MAC2STR(kde.mac_addr));
  173. if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
  174. wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
  175. "M2");
  176. return -1;
  177. }
  178. if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
  179. wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
  180. return -1;
  181. }
  182. cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
  183. if (cipher & WPA_CIPHER_CCMP) {
  184. wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
  185. cipher = WPA_CIPHER_CCMP;
  186. } else if (cipher & WPA_CIPHER_TKIP) {
  187. wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
  188. cipher = WPA_CIPHER_TKIP;
  189. } else {
  190. wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
  191. wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
  192. STK_MUI_SMK, STK_ERR_CPHR_NS,
  193. ver);
  194. return -1;
  195. }
  196. /* TODO: find existing entry and if found, use that instead of adding
  197. * a new one; how to handle the case where both ends initiate at the
  198. * same time? */
  199. peerkey = os_zalloc(sizeof(*peerkey));
  200. if (peerkey == NULL)
  201. return -1;
  202. os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
  203. os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
  204. os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
  205. peerkey->rsnie_i_len = kde.rsn_ie_len;
  206. peerkey->cipher = cipher;
  207. #ifdef CONFIG_IEEE80211W
  208. if (ie.key_mgmt & (WPA_KEY_MGMT_IEEE8021X_SHA256 |
  209. WPA_KEY_MGMT_PSK_SHA256))
  210. peerkey->use_sha256 = 1;
  211. #endif /* CONFIG_IEEE80211W */
  212. if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
  213. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  214. "WPA: Failed to get random data for PNonce");
  215. wpa_supplicant_peerkey_free(sm, peerkey);
  216. return -1;
  217. }
  218. hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
  219. hdr->elem_id = WLAN_EID_RSN;
  220. WPA_PUT_LE16(hdr->version, RSN_VERSION);
  221. pos = (u8 *) (hdr + 1);
  222. /* Group Suite can be anything for SMK RSN IE; receiver will just
  223. * ignore it. */
  224. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  225. pos += RSN_SELECTOR_LEN;
  226. /* Include only the selected cipher in pairwise cipher suite */
  227. WPA_PUT_LE16(pos, 1);
  228. pos += 2;
  229. if (cipher == WPA_CIPHER_CCMP)
  230. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  231. else if (cipher == WPA_CIPHER_TKIP)
  232. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
  233. pos += RSN_SELECTOR_LEN;
  234. hdr->len = (pos - peerkey->rsnie_p) - 2;
  235. peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
  236. wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
  237. peerkey->rsnie_p, peerkey->rsnie_p_len);
  238. wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);
  239. peerkey->next = sm->peerkey;
  240. sm->peerkey = peerkey;
  241. return 0;
  242. }
  243. /**
  244. * rsn_smkid - Derive SMK identifier
  245. * @smk: Station master key (32 bytes)
  246. * @pnonce: Peer Nonce
  247. * @mac_p: Peer MAC address
  248. * @inonce: Initiator Nonce
  249. * @mac_i: Initiator MAC address
  250. * @use_sha256: Whether to use SHA256-based KDF
  251. *
  252. * 8.5.1.4 Station to station (STK) key hierarchy
  253. * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
  254. */
  255. static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
  256. const u8 *inonce, const u8 *mac_i, u8 *smkid,
  257. int use_sha256)
  258. {
  259. char *title = "SMK Name";
  260. const u8 *addr[5];
  261. const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
  262. ETH_ALEN };
  263. unsigned char hash[SHA256_MAC_LEN];
  264. addr[0] = (u8 *) title;
  265. addr[1] = pnonce;
  266. addr[2] = mac_p;
  267. addr[3] = inonce;
  268. addr[4] = mac_i;
  269. #ifdef CONFIG_IEEE80211W
  270. if (use_sha256)
  271. hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
  272. else
  273. #endif /* CONFIG_IEEE80211W */
  274. hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
  275. os_memcpy(smkid, hash, PMKID_LEN);
  276. }
  277. static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
  278. struct wpa_peerkey *peerkey)
  279. {
  280. size_t mlen;
  281. struct wpa_eapol_key *msg;
  282. u8 *mbuf;
  283. size_t kde_len;
  284. u16 key_info, ver;
  285. kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
  286. mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  287. sizeof(*msg) + kde_len, &mlen,
  288. (void *) &msg);
  289. if (mbuf == NULL)
  290. return;
  291. msg->type = EAPOL_KEY_TYPE_RSN;
  292. if (peerkey->cipher == WPA_CIPHER_CCMP)
  293. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  294. else
  295. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  296. key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
  297. WPA_PUT_BE16(msg->key_info, key_info);
  298. if (peerkey->cipher == WPA_CIPHER_CCMP)
  299. WPA_PUT_BE16(msg->key_length, 16);
  300. else
  301. WPA_PUT_BE16(msg->key_length, 32);
  302. os_memcpy(msg->replay_counter, peerkey->replay_counter,
  303. WPA_REPLAY_COUNTER_LEN);
  304. inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
  305. WPA_PUT_BE16(msg->key_data_length, kde_len);
  306. wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
  307. peerkey->smkid, PMKID_LEN);
  308. if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
  309. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  310. "RSN: Failed to get random data for INonce (STK)");
  311. os_free(mbuf);
  312. return;
  313. }
  314. wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
  315. peerkey->inonce, WPA_NONCE_LEN);
  316. os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  317. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
  318. MAC2STR(peerkey->addr));
  319. wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
  320. mbuf, mlen, NULL);
  321. }
  322. static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
  323. struct wpa_peerkey *peerkey)
  324. {
  325. size_t mlen;
  326. struct wpa_eapol_key *msg;
  327. u8 *mbuf, *pos;
  328. size_t kde_len;
  329. u16 key_info, ver;
  330. be32 lifetime;
  331. kde_len = peerkey->rsnie_i_len +
  332. 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
  333. mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  334. sizeof(*msg) + kde_len, &mlen,
  335. (void *) &msg);
  336. if (mbuf == NULL)
  337. return;
  338. msg->type = EAPOL_KEY_TYPE_RSN;
  339. if (peerkey->cipher == WPA_CIPHER_CCMP)
  340. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  341. else
  342. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  343. key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
  344. WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
  345. WPA_PUT_BE16(msg->key_info, key_info);
  346. if (peerkey->cipher == WPA_CIPHER_CCMP)
  347. WPA_PUT_BE16(msg->key_length, 16);
  348. else
  349. WPA_PUT_BE16(msg->key_length, 32);
  350. os_memcpy(msg->replay_counter, peerkey->replay_counter,
  351. WPA_REPLAY_COUNTER_LEN);
  352. inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
  353. WPA_PUT_BE16(msg->key_data_length, kde_len);
  354. pos = (u8 *) (msg + 1);
  355. pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
  356. lifetime = host_to_be32(peerkey->lifetime);
  357. wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
  358. (u8 *) &lifetime, sizeof(lifetime));
  359. os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  360. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
  361. MAC2STR(peerkey->addr));
  362. wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
  363. ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
  364. }
  365. static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
  366. struct wpa_eapol_ie_parse *kde)
  367. {
  368. wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
  369. MAC2STR(kde->mac_addr));
  370. if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
  371. {
  372. wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
  373. "match with the one used in SMK M3");
  374. return -1;
  375. }
  376. if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
  377. wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
  378. "match with the one received in SMK M2");
  379. return -1;
  380. }
  381. return 0;
  382. }
  383. static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
  384. const unsigned char *src_addr,
  385. const struct wpa_eapol_key *key,
  386. int ver,
  387. struct wpa_peerkey *peerkey,
  388. struct wpa_eapol_ie_parse *kde)
  389. {
  390. int cipher;
  391. struct wpa_ie_data ie;
  392. wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
  393. MAC2STR(kde->mac_addr));
  394. if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
  395. wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
  396. wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
  397. /* TODO: abort negotiation */
  398. return -1;
  399. }
  400. if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
  401. wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
  402. "not match with INonce used in SMK M1");
  403. return -1;
  404. }
  405. if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
  406. {
  407. wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
  408. "match with the one used in SMK M1");
  409. return -1;
  410. }
  411. os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
  412. peerkey->rsnie_p_len = kde->rsn_ie_len;
  413. os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
  414. cipher = ie.pairwise_cipher & sm->allowed_pairwise_cipher;
  415. if (cipher & WPA_CIPHER_CCMP) {
  416. wpa_printf(MSG_DEBUG, "RSN: Using CCMP for PeerKey");
  417. peerkey->cipher = WPA_CIPHER_CCMP;
  418. } else if (cipher & WPA_CIPHER_TKIP) {
  419. wpa_printf(MSG_DEBUG, "RSN: Using TKIP for PeerKey");
  420. peerkey->cipher = WPA_CIPHER_TKIP;
  421. } else {
  422. wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
  423. "unacceptable cipher", MAC2STR(kde->mac_addr));
  424. wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
  425. STK_MUI_SMK, STK_ERR_CPHR_NS,
  426. ver);
  427. /* TODO: abort negotiation */
  428. return -1;
  429. }
  430. return 0;
  431. }
  432. static int wpa_supplicant_process_smk_m45(
  433. struct wpa_sm *sm, const unsigned char *src_addr,
  434. const struct wpa_eapol_key *key, size_t extra_len, int ver)
  435. {
  436. struct wpa_peerkey *peerkey;
  437. struct wpa_eapol_ie_parse kde;
  438. u32 lifetime;
  439. struct os_time now;
  440. if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
  441. wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
  442. "the current network");
  443. return -1;
  444. }
  445. if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
  446. 0) {
  447. wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M4/M5");
  448. return -1;
  449. }
  450. if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
  451. kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN ||
  452. kde.smk == NULL || kde.smk_len < PMK_LEN + WPA_NONCE_LEN ||
  453. kde.lifetime == NULL || kde.lifetime_len < 4) {
  454. wpa_printf(MSG_INFO, "RSN: No MAC Address, Nonce, SMK, or "
  455. "Lifetime KDE in SMK M4/M5");
  456. return -1;
  457. }
  458. for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
  459. if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) == 0 &&
  460. os_memcmp(peerkey->initiator ? peerkey->inonce :
  461. peerkey->pnonce,
  462. key->key_nonce, WPA_NONCE_LEN) == 0)
  463. break;
  464. }
  465. if (peerkey == NULL) {
  466. wpa_printf(MSG_INFO, "RSN: No matching SMK handshake found "
  467. "for SMK M4/M5: peer " MACSTR,
  468. MAC2STR(kde.mac_addr));
  469. return -1;
  470. }
  471. if (peerkey->initiator) {
  472. if (wpa_supplicant_process_smk_m5(sm, src_addr, key, ver,
  473. peerkey, &kde) < 0)
  474. return -1;
  475. } else {
  476. if (wpa_supplicant_process_smk_m4(peerkey, &kde) < 0)
  477. return -1;
  478. }
  479. os_memcpy(peerkey->smk, kde.smk, PMK_LEN);
  480. peerkey->smk_complete = 1;
  481. wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", peerkey->smk, PMK_LEN);
  482. lifetime = WPA_GET_BE32(kde.lifetime);
  483. wpa_printf(MSG_DEBUG, "RSN: SMK lifetime %u seconds", lifetime);
  484. if (lifetime > 1000000000)
  485. lifetime = 1000000000; /* avoid overflowing expiration time */
  486. peerkey->lifetime = lifetime;
  487. os_get_time(&now);
  488. peerkey->expiration = now.sec + lifetime;
  489. eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
  490. sm, peerkey);
  491. if (peerkey->initiator) {
  492. rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
  493. peerkey->inonce, sm->own_addr, peerkey->smkid,
  494. peerkey->use_sha256);
  495. wpa_supplicant_send_stk_1_of_4(sm, peerkey);
  496. } else {
  497. rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
  498. peerkey->inonce, peerkey->addr, peerkey->smkid,
  499. peerkey->use_sha256);
  500. }
  501. wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
  502. return 0;
  503. }
  504. static int wpa_supplicant_process_smk_error(
  505. struct wpa_sm *sm, const unsigned char *src_addr,
  506. const struct wpa_eapol_key *key, size_t extra_len)
  507. {
  508. struct wpa_eapol_ie_parse kde;
  509. struct rsn_error_kde error;
  510. u8 peer[ETH_ALEN];
  511. u16 error_type;
  512. wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");
  513. if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
  514. wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
  515. "the current network");
  516. return -1;
  517. }
  518. if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
  519. 0) {
  520. wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
  521. return -1;
  522. }
  523. if (kde.error == NULL || kde.error_len < sizeof(error)) {
  524. wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
  525. return -1;
  526. }
  527. if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
  528. os_memcpy(peer, kde.mac_addr, ETH_ALEN);
  529. else
  530. os_memset(peer, 0, ETH_ALEN);
  531. os_memcpy(&error, kde.error, sizeof(error));
  532. error_type = be_to_host16(error.error_type);
  533. wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
  534. "RSN: SMK Error KDE received: MUI %d error_type %d peer "
  535. MACSTR,
  536. be_to_host16(error.mui), error_type,
  537. MAC2STR(peer));
  538. if (kde.mac_addr &&
  539. (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||
  540. error_type == STK_ERR_CPHR_NS)) {
  541. struct wpa_peerkey *peerkey;
  542. for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
  543. if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==
  544. 0)
  545. break;
  546. }
  547. if (peerkey == NULL) {
  548. wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "
  549. "found for SMK Error");
  550. return -1;
  551. }
  552. /* TODO: abort SMK/STK handshake and remove all related keys */
  553. }
  554. return 0;
  555. }
  556. static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
  557. struct wpa_peerkey *peerkey,
  558. const struct wpa_eapol_key *key,
  559. u16 ver)
  560. {
  561. struct wpa_eapol_ie_parse ie;
  562. const u8 *kde;
  563. size_t len, kde_buf_len;
  564. struct wpa_ptk *stk;
  565. u8 buf[8], *kde_buf, *pos;
  566. be32 lifetime;
  567. wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "
  568. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  569. os_memset(&ie, 0, sizeof(ie));
  570. /* RSN: msg 1/4 should contain SMKID for the selected SMK */
  571. kde = (const u8 *) (key + 1);
  572. len = WPA_GET_BE16(key->key_data_length);
  573. wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
  574. if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
  575. wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
  576. return;
  577. }
  578. if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
  579. wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
  580. ie.pmkid, PMKID_LEN);
  581. return;
  582. }
  583. if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
  584. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  585. "RSN: Failed to get random data for PNonce");
  586. return;
  587. }
  588. wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",
  589. peerkey->pnonce, WPA_NONCE_LEN);
  590. /* Calculate STK which will be stored as a temporary STK until it has
  591. * been verified when processing message 3/4. */
  592. stk = &peerkey->tstk;
  593. wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
  594. sm->own_addr, peerkey->addr,
  595. peerkey->pnonce, key->key_nonce,
  596. (u8 *) stk, sizeof(*stk),
  597. peerkey->use_sha256);
  598. /* Supplicant: swap tx/rx Mic keys */
  599. os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
  600. os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
  601. os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
  602. peerkey->tstk_set = 1;
  603. kde_buf_len = peerkey->rsnie_p_len +
  604. 2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
  605. 2 + RSN_SELECTOR_LEN + PMKID_LEN;
  606. kde_buf = os_malloc(kde_buf_len);
  607. if (kde_buf == NULL)
  608. return;
  609. pos = kde_buf;
  610. pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
  611. lifetime = host_to_be32(peerkey->lifetime);
  612. pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
  613. (u8 *) &lifetime, sizeof(lifetime));
  614. wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);
  615. if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
  616. peerkey->pnonce, kde_buf, kde_buf_len,
  617. stk)) {
  618. os_free(kde_buf);
  619. return;
  620. }
  621. os_free(kde_buf);
  622. os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
  623. }
  624. static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
  625. struct wpa_peerkey *peerkey,
  626. struct wpa_eapol_ie_parse *kde)
  627. {
  628. u32 lifetime;
  629. struct os_time now;
  630. if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
  631. return;
  632. lifetime = WPA_GET_BE32(kde->lifetime);
  633. if (lifetime >= peerkey->lifetime) {
  634. wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
  635. "which is larger than or equal to own value %u "
  636. "seconds - ignored", lifetime, peerkey->lifetime);
  637. return;
  638. }
  639. wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
  640. "(own was %u seconds) - updated",
  641. lifetime, peerkey->lifetime);
  642. peerkey->lifetime = lifetime;
  643. os_get_time(&now);
  644. peerkey->expiration = now.sec + lifetime;
  645. eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
  646. eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
  647. sm, peerkey);
  648. }
  649. static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
  650. struct wpa_peerkey *peerkey,
  651. const struct wpa_eapol_key *key,
  652. u16 ver)
  653. {
  654. struct wpa_eapol_ie_parse kde;
  655. const u8 *keydata;
  656. size_t len;
  657. wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
  658. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  659. os_memset(&kde, 0, sizeof(kde));
  660. /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
  661. * from the peer. It may also include Lifetime KDE. */
  662. keydata = (const u8 *) (key + 1);
  663. len = WPA_GET_BE16(key->key_data_length);
  664. wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
  665. if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
  666. kde.pmkid == NULL || kde.rsn_ie == NULL) {
  667. wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
  668. return;
  669. }
  670. if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
  671. wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
  672. kde.pmkid, PMKID_LEN);
  673. return;
  674. }
  675. if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
  676. os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
  677. wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
  678. "handshakes did not match");
  679. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
  680. peerkey->rsnie_p, peerkey->rsnie_p_len);
  681. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
  682. kde.rsn_ie, kde.rsn_ie_len);
  683. return;
  684. }
  685. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  686. wpa_supplicant_send_stk_3_of_4(sm, peerkey);
  687. os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
  688. }
  689. static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
  690. struct wpa_peerkey *peerkey,
  691. const struct wpa_eapol_key *key,
  692. u16 ver)
  693. {
  694. struct wpa_eapol_ie_parse kde;
  695. const u8 *keydata;
  696. size_t len, key_len;
  697. const u8 *_key;
  698. u8 key_buf[32], rsc[6];
  699. wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
  700. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  701. os_memset(&kde, 0, sizeof(kde));
  702. /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
  703. * Lifetime KDE. */
  704. keydata = (const u8 *) (key + 1);
  705. len = WPA_GET_BE16(key->key_data_length);
  706. wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
  707. if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
  708. wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
  709. "STK 3/4");
  710. return;
  711. }
  712. if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
  713. os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
  714. wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
  715. "handshakes did not match");
  716. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
  717. "handshake",
  718. peerkey->rsnie_i, peerkey->rsnie_i_len);
  719. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
  720. "handshake",
  721. kde.rsn_ie, kde.rsn_ie_len);
  722. return;
  723. }
  724. if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
  725. wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
  726. "4-Way Handshake differs from 3 of STK 4-Way "
  727. "Handshake - drop packet (src=" MACSTR ")",
  728. MAC2STR(peerkey->addr));
  729. return;
  730. }
  731. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  732. if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
  733. WPA_GET_BE16(key->key_info),
  734. NULL, 0, &peerkey->stk))
  735. return;
  736. _key = (u8 *) peerkey->stk.tk1;
  737. if (peerkey->cipher == WPA_CIPHER_TKIP) {
  738. /* Swap Tx/Rx keys for Michael MIC */
  739. os_memcpy(key_buf, _key, 16);
  740. os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
  741. os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
  742. _key = key_buf;
  743. key_len = 32;
  744. } else
  745. key_len = 16;
  746. os_memset(rsc, 0, 6);
  747. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  748. rsc, sizeof(rsc), _key, key_len) < 0) {
  749. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  750. "driver.");
  751. return;
  752. }
  753. }
  754. static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
  755. struct wpa_peerkey *peerkey,
  756. const struct wpa_eapol_key *key,
  757. u16 ver)
  758. {
  759. u8 rsc[6];
  760. wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
  761. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  762. os_memset(rsc, 0, 6);
  763. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  764. rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
  765. peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
  766. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  767. "driver.");
  768. return;
  769. }
  770. }
  771. /**
  772. * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
  773. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  774. * @peerkey: Pointer to the PeerKey data for the peer
  775. * @key: Pointer to the EAPOL-Key frame header
  776. * @ver: Version bits from EAPOL-Key Key Info
  777. * @buf: Pointer to the beginning of EAPOL-Key frame
  778. * @len: Length of the EAPOL-Key frame
  779. * Returns: 0 on success, -1 on failure
  780. */
  781. int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
  782. struct wpa_peerkey *peerkey,
  783. struct wpa_eapol_key *key, u16 ver,
  784. const u8 *buf, size_t len)
  785. {
  786. u8 mic[16];
  787. int ok = 0;
  788. if (peerkey->initiator && !peerkey->stk_set) {
  789. wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
  790. sm->own_addr, peerkey->addr,
  791. peerkey->inonce, key->key_nonce,
  792. (u8 *) &peerkey->stk, sizeof(peerkey->stk),
  793. peerkey->use_sha256);
  794. peerkey->stk_set = 1;
  795. }
  796. os_memcpy(mic, key->key_mic, 16);
  797. if (peerkey->tstk_set) {
  798. os_memset(key->key_mic, 0, 16);
  799. wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
  800. key->key_mic);
  801. if (os_memcmp(mic, key->key_mic, 16) != 0) {
  802. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  803. "when using TSTK - ignoring TSTK");
  804. } else {
  805. ok = 1;
  806. peerkey->tstk_set = 0;
  807. peerkey->stk_set = 1;
  808. os_memcpy(&peerkey->stk, &peerkey->tstk,
  809. sizeof(peerkey->stk));
  810. }
  811. }
  812. if (!ok && peerkey->stk_set) {
  813. os_memset(key->key_mic, 0, 16);
  814. wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
  815. key->key_mic);
  816. if (os_memcmp(mic, key->key_mic, 16) != 0) {
  817. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  818. "- dropping packet");
  819. return -1;
  820. }
  821. ok = 1;
  822. }
  823. if (!ok) {
  824. wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
  825. "- dropping packet");
  826. return -1;
  827. }
  828. os_memcpy(peerkey->replay_counter, key->replay_counter,
  829. WPA_REPLAY_COUNTER_LEN);
  830. peerkey->replay_counter_set = 1;
  831. return 0;
  832. }
  833. /**
  834. * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
  835. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  836. * @peer: MAC address of the peer STA
  837. * Returns: 0 on success, or -1 on failure
  838. *
  839. * Send an EAPOL-Key Request to the current authenticator to start STK
  840. * handshake with the peer.
  841. */
  842. int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
  843. {
  844. size_t rlen, kde_len;
  845. struct wpa_eapol_key *req;
  846. int key_info, ver;
  847. u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
  848. u16 count;
  849. struct rsn_ie_hdr *hdr;
  850. struct wpa_peerkey *peerkey;
  851. struct wpa_ie_data ie;
  852. if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
  853. return -1;
  854. if (sm->ap_rsn_ie &&
  855. wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
  856. !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
  857. wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
  858. return -1;
  859. }
  860. if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
  861. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  862. else
  863. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  864. if (wpa_sm_get_bssid(sm, bssid) < 0) {
  865. wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
  866. "SMK M1");
  867. return -1;
  868. }
  869. /* TODO: find existing entry and if found, use that instead of adding
  870. * a new one */
  871. peerkey = os_zalloc(sizeof(*peerkey));
  872. if (peerkey == NULL)
  873. return -1;
  874. peerkey->initiator = 1;
  875. os_memcpy(peerkey->addr, peer, ETH_ALEN);
  876. #ifdef CONFIG_IEEE80211W
  877. if (wpa_key_mgmt_sha256(sm->key_mgmt))
  878. peerkey->use_sha256 = 1;
  879. #endif /* CONFIG_IEEE80211W */
  880. /* SMK M1:
  881. * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
  882. * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
  883. */
  884. hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
  885. hdr->elem_id = WLAN_EID_RSN;
  886. WPA_PUT_LE16(hdr->version, RSN_VERSION);
  887. pos = (u8 *) (hdr + 1);
  888. /* Group Suite can be anything for SMK RSN IE; receiver will just
  889. * ignore it. */
  890. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  891. pos += RSN_SELECTOR_LEN;
  892. count_pos = pos;
  893. pos += 2;
  894. count = 0;
  895. if (sm->allowed_pairwise_cipher & WPA_CIPHER_CCMP) {
  896. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  897. pos += RSN_SELECTOR_LEN;
  898. count++;
  899. }
  900. if (sm->allowed_pairwise_cipher & WPA_CIPHER_TKIP) {
  901. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP);
  902. pos += RSN_SELECTOR_LEN;
  903. count++;
  904. }
  905. WPA_PUT_LE16(count_pos, count);
  906. hdr->len = (pos - peerkey->rsnie_i) - 2;
  907. peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
  908. wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
  909. peerkey->rsnie_i, peerkey->rsnie_i_len);
  910. kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
  911. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  912. sizeof(*req) + kde_len, &rlen,
  913. (void *) &req);
  914. if (rbuf == NULL) {
  915. wpa_supplicant_peerkey_free(sm, peerkey);
  916. return -1;
  917. }
  918. req->type = EAPOL_KEY_TYPE_RSN;
  919. key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  920. WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
  921. WPA_PUT_BE16(req->key_info, key_info);
  922. WPA_PUT_BE16(req->key_length, 0);
  923. os_memcpy(req->replay_counter, sm->request_counter,
  924. WPA_REPLAY_COUNTER_LEN);
  925. inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
  926. if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
  927. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  928. "WPA: Failed to get random data for INonce");
  929. os_free(rbuf);
  930. wpa_supplicant_peerkey_free(sm, peerkey);
  931. return -1;
  932. }
  933. os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  934. wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
  935. req->key_nonce, WPA_NONCE_LEN);
  936. WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
  937. pos = (u8 *) (req + 1);
  938. /* Initiator RSN IE */
  939. pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
  940. /* Peer MAC address KDE */
  941. wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
  942. wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
  943. MACSTR ")", MAC2STR(peer));
  944. wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
  945. rbuf, rlen, req->key_mic);
  946. peerkey->next = sm->peerkey;
  947. sm->peerkey = peerkey;
  948. return 0;
  949. }
  950. /**
  951. * peerkey_deinit - Free PeerKey values
  952. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  953. */
  954. void peerkey_deinit(struct wpa_sm *sm)
  955. {
  956. struct wpa_peerkey *prev, *peerkey = sm->peerkey;
  957. while (peerkey) {
  958. prev = peerkey;
  959. peerkey = peerkey->next;
  960. os_free(prev);
  961. }
  962. sm->peerkey = NULL;
  963. }
  964. void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
  965. struct wpa_eapol_key *key, u16 key_info, u16 ver)
  966. {
  967. if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
  968. (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
  969. /* 3/4 STK 4-Way Handshake */
  970. wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
  971. } else if (key_info & WPA_KEY_INFO_ACK) {
  972. /* 1/4 STK 4-Way Handshake */
  973. wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
  974. } else if (key_info & WPA_KEY_INFO_SECURE) {
  975. /* 4/4 STK 4-Way Handshake */
  976. wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
  977. } else {
  978. /* 2/4 STK 4-Way Handshake */
  979. wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
  980. }
  981. }
  982. void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
  983. struct wpa_eapol_key *key, size_t extra_len,
  984. u16 key_info, u16 ver)
  985. {
  986. if (key_info & WPA_KEY_INFO_ERROR) {
  987. /* SMK Error */
  988. wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
  989. } else if (key_info & WPA_KEY_INFO_ACK) {
  990. /* SMK M2 */
  991. wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
  992. ver);
  993. } else {
  994. /* SMK M4 or M5 */
  995. wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
  996. ver);
  997. }
  998. }
  999. #endif /* CONFIG_PEERKEY */