peerkey.c 33 KB

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