peerkey.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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. peerkey->use_sha256 = 1;
  202. #endif /* CONFIG_IEEE80211W */
  203. if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
  204. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  205. "WPA: Failed to get random data for PNonce");
  206. wpa_supplicant_peerkey_free(sm, peerkey);
  207. return -1;
  208. }
  209. hdr = (struct rsn_ie_hdr *) peerkey->rsnie_p;
  210. hdr->elem_id = WLAN_EID_RSN;
  211. WPA_PUT_LE16(hdr->version, RSN_VERSION);
  212. pos = (u8 *) (hdr + 1);
  213. /* Group Suite can be anything for SMK RSN IE; receiver will just
  214. * ignore it. */
  215. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  216. pos += RSN_SELECTOR_LEN;
  217. /* Include only the selected cipher in pairwise cipher suite */
  218. WPA_PUT_LE16(pos, 1);
  219. pos += 2;
  220. RSN_SELECTOR_PUT(pos, wpa_cipher_to_suite(WPA_PROTO_RSN, cipher));
  221. pos += RSN_SELECTOR_LEN;
  222. hdr->len = (pos - peerkey->rsnie_p) - 2;
  223. peerkey->rsnie_p_len = pos - peerkey->rsnie_p;
  224. wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
  225. peerkey->rsnie_p, peerkey->rsnie_p_len);
  226. wpa_supplicant_send_smk_m3(sm, src_addr, key, ver, peerkey);
  227. peerkey->next = sm->peerkey;
  228. sm->peerkey = peerkey;
  229. return 0;
  230. }
  231. /**
  232. * rsn_smkid - Derive SMK identifier
  233. * @smk: Station master key (32 bytes)
  234. * @pnonce: Peer Nonce
  235. * @mac_p: Peer MAC address
  236. * @inonce: Initiator Nonce
  237. * @mac_i: Initiator MAC address
  238. * @use_sha256: Whether to use SHA256-based KDF
  239. *
  240. * 8.5.1.4 Station to station (STK) key hierarchy
  241. * SMKID = HMAC-SHA1-128(SMK, "SMK Name" || PNonce || MAC_P || INonce || MAC_I)
  242. */
  243. static void rsn_smkid(const u8 *smk, const u8 *pnonce, const u8 *mac_p,
  244. const u8 *inonce, const u8 *mac_i, u8 *smkid,
  245. int use_sha256)
  246. {
  247. char *title = "SMK Name";
  248. const u8 *addr[5];
  249. const size_t len[5] = { 8, WPA_NONCE_LEN, ETH_ALEN, WPA_NONCE_LEN,
  250. ETH_ALEN };
  251. unsigned char hash[SHA256_MAC_LEN];
  252. addr[0] = (u8 *) title;
  253. addr[1] = pnonce;
  254. addr[2] = mac_p;
  255. addr[3] = inonce;
  256. addr[4] = mac_i;
  257. #ifdef CONFIG_IEEE80211W
  258. if (use_sha256)
  259. hmac_sha256_vector(smk, PMK_LEN, 5, addr, len, hash);
  260. else
  261. #endif /* CONFIG_IEEE80211W */
  262. hmac_sha1_vector(smk, PMK_LEN, 5, addr, len, hash);
  263. os_memcpy(smkid, hash, PMKID_LEN);
  264. }
  265. static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm,
  266. struct wpa_peerkey *peerkey)
  267. {
  268. size_t mlen;
  269. struct wpa_eapol_key *msg;
  270. u8 *mbuf;
  271. size_t kde_len;
  272. u16 key_info, ver;
  273. kde_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
  274. mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  275. sizeof(*msg) + kde_len, &mlen,
  276. (void *) &msg);
  277. if (mbuf == NULL)
  278. return;
  279. msg->type = EAPOL_KEY_TYPE_RSN;
  280. if (peerkey->cipher != WPA_CIPHER_TKIP)
  281. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  282. else
  283. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  284. key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK;
  285. WPA_PUT_BE16(msg->key_info, key_info);
  286. if (peerkey->cipher != WPA_CIPHER_TKIP)
  287. WPA_PUT_BE16(msg->key_length, 16);
  288. else
  289. WPA_PUT_BE16(msg->key_length, 32);
  290. os_memcpy(msg->replay_counter, peerkey->replay_counter,
  291. WPA_REPLAY_COUNTER_LEN);
  292. inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
  293. WPA_PUT_BE16(msg->key_data_length, kde_len);
  294. wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
  295. peerkey->smkid, PMKID_LEN);
  296. if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
  297. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  298. "RSN: Failed to get random data for INonce (STK)");
  299. os_free(mbuf);
  300. return;
  301. }
  302. wpa_hexdump(MSG_DEBUG, "RSN: INonce for STK 4-Way Handshake",
  303. peerkey->inonce, WPA_NONCE_LEN);
  304. os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  305. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR,
  306. MAC2STR(peerkey->addr));
  307. wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL,
  308. mbuf, mlen, NULL);
  309. }
  310. static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm,
  311. struct wpa_peerkey *peerkey)
  312. {
  313. size_t mlen;
  314. struct wpa_eapol_key *msg;
  315. u8 *mbuf, *pos;
  316. size_t kde_len;
  317. u16 key_info, ver;
  318. be32 lifetime;
  319. kde_len = peerkey->rsnie_i_len +
  320. 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
  321. mbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  322. sizeof(*msg) + kde_len, &mlen,
  323. (void *) &msg);
  324. if (mbuf == NULL)
  325. return;
  326. msg->type = EAPOL_KEY_TYPE_RSN;
  327. if (peerkey->cipher != WPA_CIPHER_TKIP)
  328. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  329. else
  330. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  331. key_info = ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_ACK |
  332. WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
  333. WPA_PUT_BE16(msg->key_info, key_info);
  334. if (peerkey->cipher != WPA_CIPHER_TKIP)
  335. WPA_PUT_BE16(msg->key_length, 16);
  336. else
  337. WPA_PUT_BE16(msg->key_length, 32);
  338. os_memcpy(msg->replay_counter, peerkey->replay_counter,
  339. WPA_REPLAY_COUNTER_LEN);
  340. inc_byte_array(peerkey->replay_counter, WPA_REPLAY_COUNTER_LEN);
  341. WPA_PUT_BE16(msg->key_data_length, kde_len);
  342. pos = (u8 *) (msg + 1);
  343. pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
  344. lifetime = host_to_be32(peerkey->lifetime);
  345. wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
  346. (u8 *) &lifetime, sizeof(lifetime));
  347. os_memcpy(msg->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  348. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR,
  349. MAC2STR(peerkey->addr));
  350. wpa_eapol_key_send(sm, peerkey->stk.kck, ver, peerkey->addr,
  351. ETH_P_EAPOL, mbuf, mlen, msg->key_mic);
  352. }
  353. static int wpa_supplicant_process_smk_m4(struct wpa_peerkey *peerkey,
  354. struct wpa_eapol_ie_parse *kde)
  355. {
  356. wpa_printf(MSG_DEBUG, "RSN: Received SMK M4 (Initiator " MACSTR ")",
  357. MAC2STR(kde->mac_addr));
  358. if (os_memcmp(kde->smk + PMK_LEN, peerkey->pnonce, WPA_NONCE_LEN) != 0)
  359. {
  360. wpa_printf(MSG_INFO, "RSN: PNonce in SMK KDE does not "
  361. "match with the one used in SMK M3");
  362. return -1;
  363. }
  364. if (os_memcmp(kde->nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
  365. wpa_printf(MSG_INFO, "RSN: INonce in SMK M4 did not "
  366. "match with the one received in SMK M2");
  367. return -1;
  368. }
  369. return 0;
  370. }
  371. static int wpa_supplicant_process_smk_m5(struct wpa_sm *sm,
  372. const unsigned char *src_addr,
  373. const struct wpa_eapol_key *key,
  374. int ver,
  375. struct wpa_peerkey *peerkey,
  376. struct wpa_eapol_ie_parse *kde)
  377. {
  378. int cipher;
  379. struct wpa_ie_data ie;
  380. wpa_printf(MSG_DEBUG, "RSN: Received SMK M5 (Peer " MACSTR ")",
  381. MAC2STR(kde->mac_addr));
  382. if (kde->rsn_ie == NULL || kde->rsn_ie_len > PEERKEY_MAX_IE_LEN ||
  383. wpa_parse_wpa_ie_rsn(kde->rsn_ie, kde->rsn_ie_len, &ie) < 0) {
  384. wpa_printf(MSG_INFO, "RSN: No RSN IE in SMK M5");
  385. /* TODO: abort negotiation */
  386. return -1;
  387. }
  388. if (os_memcmp(key->key_nonce, peerkey->inonce, WPA_NONCE_LEN) != 0) {
  389. wpa_printf(MSG_INFO, "RSN: Key Nonce in SMK M5 does "
  390. "not match with INonce used in SMK M1");
  391. return -1;
  392. }
  393. if (os_memcmp(kde->smk + PMK_LEN, peerkey->inonce, WPA_NONCE_LEN) != 0)
  394. {
  395. wpa_printf(MSG_INFO, "RSN: INonce in SMK KDE does not "
  396. "match with the one used in SMK M1");
  397. return -1;
  398. }
  399. os_memcpy(peerkey->rsnie_p, kde->rsn_ie, kde->rsn_ie_len);
  400. peerkey->rsnie_p_len = kde->rsn_ie_len;
  401. os_memcpy(peerkey->pnonce, kde->nonce, WPA_NONCE_LEN);
  402. cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
  403. sm->allowed_pairwise_cipher, 0);
  404. if (cipher < 0) {
  405. wpa_printf(MSG_INFO, "RSN: SMK Peer STA " MACSTR " selected "
  406. "unacceptable cipher", MAC2STR(kde->mac_addr));
  407. wpa_supplicant_send_smk_error(sm, src_addr, kde->mac_addr,
  408. STK_MUI_SMK, STK_ERR_CPHR_NS,
  409. ver);
  410. /* TODO: abort negotiation */
  411. return -1;
  412. }
  413. wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
  414. wpa_cipher_txt(cipher));
  415. peerkey->cipher = cipher;
  416. return 0;
  417. }
  418. static int wpa_supplicant_process_smk_m45(
  419. struct wpa_sm *sm, const unsigned char *src_addr,
  420. const struct wpa_eapol_key *key, size_t extra_len, int ver)
  421. {
  422. struct wpa_peerkey *peerkey;
  423. struct wpa_eapol_ie_parse kde;
  424. u32 lifetime;
  425. struct os_time now;
  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 expiration time */
  472. peerkey->lifetime = lifetime;
  473. os_get_time(&now);
  474. peerkey->expiration = now.sec + lifetime;
  475. eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
  476. sm, peerkey);
  477. if (peerkey->initiator) {
  478. rsn_smkid(peerkey->smk, peerkey->pnonce, peerkey->addr,
  479. peerkey->inonce, sm->own_addr, peerkey->smkid,
  480. peerkey->use_sha256);
  481. wpa_supplicant_send_stk_1_of_4(sm, peerkey);
  482. } else {
  483. rsn_smkid(peerkey->smk, peerkey->pnonce, sm->own_addr,
  484. peerkey->inonce, peerkey->addr, peerkey->smkid,
  485. peerkey->use_sha256);
  486. }
  487. wpa_hexdump(MSG_DEBUG, "RSN: SMKID", peerkey->smkid, PMKID_LEN);
  488. return 0;
  489. }
  490. static int wpa_supplicant_process_smk_error(
  491. struct wpa_sm *sm, const unsigned char *src_addr,
  492. const struct wpa_eapol_key *key, size_t extra_len)
  493. {
  494. struct wpa_eapol_ie_parse kde;
  495. struct rsn_error_kde error;
  496. u8 peer[ETH_ALEN];
  497. u16 error_type;
  498. wpa_printf(MSG_DEBUG, "RSN: Received SMK Error");
  499. if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
  500. wpa_printf(MSG_DEBUG, "RSN: SMK handshake not allowed for "
  501. "the current network");
  502. return -1;
  503. }
  504. if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
  505. 0) {
  506. wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
  507. return -1;
  508. }
  509. if (kde.error == NULL || kde.error_len < sizeof(error)) {
  510. wpa_printf(MSG_INFO, "RSN: No Error KDE in SMK Error");
  511. return -1;
  512. }
  513. if (kde.mac_addr && kde.mac_addr_len >= ETH_ALEN)
  514. os_memcpy(peer, kde.mac_addr, ETH_ALEN);
  515. else
  516. os_memset(peer, 0, ETH_ALEN);
  517. os_memcpy(&error, kde.error, sizeof(error));
  518. error_type = be_to_host16(error.error_type);
  519. wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
  520. "RSN: SMK Error KDE received: MUI %d error_type %d peer "
  521. MACSTR,
  522. be_to_host16(error.mui), error_type,
  523. MAC2STR(peer));
  524. if (kde.mac_addr &&
  525. (error_type == STK_ERR_STA_NR || error_type == STK_ERR_STA_NRSN ||
  526. error_type == STK_ERR_CPHR_NS)) {
  527. struct wpa_peerkey *peerkey;
  528. for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
  529. if (os_memcmp(peerkey->addr, kde.mac_addr, ETH_ALEN) ==
  530. 0)
  531. break;
  532. }
  533. if (peerkey == NULL) {
  534. wpa_printf(MSG_DEBUG, "RSN: No matching SMK handshake "
  535. "found for SMK Error");
  536. return -1;
  537. }
  538. /* TODO: abort SMK/STK handshake and remove all related keys */
  539. }
  540. return 0;
  541. }
  542. static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
  543. struct wpa_peerkey *peerkey,
  544. const struct wpa_eapol_key *key,
  545. u16 ver)
  546. {
  547. struct wpa_eapol_ie_parse ie;
  548. const u8 *kde;
  549. size_t len, kde_buf_len;
  550. struct wpa_ptk *stk;
  551. u8 buf[8], *kde_buf, *pos;
  552. be32 lifetime;
  553. wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from "
  554. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  555. os_memset(&ie, 0, sizeof(ie));
  556. /* RSN: msg 1/4 should contain SMKID for the selected SMK */
  557. kde = (const u8 *) (key + 1);
  558. len = WPA_GET_BE16(key->key_data_length);
  559. wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
  560. if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
  561. wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
  562. return;
  563. }
  564. if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
  565. wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
  566. ie.pmkid, PMKID_LEN);
  567. return;
  568. }
  569. if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) {
  570. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  571. "RSN: Failed to get random data for PNonce");
  572. return;
  573. }
  574. wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce",
  575. peerkey->pnonce, WPA_NONCE_LEN);
  576. /* Calculate STK which will be stored as a temporary STK until it has
  577. * been verified when processing message 3/4. */
  578. stk = &peerkey->tstk;
  579. wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
  580. sm->own_addr, peerkey->addr,
  581. peerkey->pnonce, key->key_nonce,
  582. (u8 *) stk, sizeof(*stk),
  583. peerkey->use_sha256);
  584. /* Supplicant: swap tx/rx Mic keys */
  585. os_memcpy(buf, stk->u.auth.tx_mic_key, 8);
  586. os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8);
  587. os_memcpy(stk->u.auth.rx_mic_key, buf, 8);
  588. peerkey->tstk_set = 1;
  589. kde_buf_len = peerkey->rsnie_p_len +
  590. 2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
  591. 2 + RSN_SELECTOR_LEN + PMKID_LEN;
  592. kde_buf = os_malloc(kde_buf_len);
  593. if (kde_buf == NULL)
  594. return;
  595. pos = kde_buf;
  596. pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
  597. lifetime = host_to_be32(peerkey->lifetime);
  598. pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
  599. (u8 *) &lifetime, sizeof(lifetime));
  600. wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);
  601. if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
  602. peerkey->pnonce, kde_buf, kde_buf_len,
  603. stk)) {
  604. os_free(kde_buf);
  605. return;
  606. }
  607. os_free(kde_buf);
  608. os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
  609. }
  610. static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
  611. struct wpa_peerkey *peerkey,
  612. struct wpa_eapol_ie_parse *kde)
  613. {
  614. u32 lifetime;
  615. struct os_time now;
  616. if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
  617. return;
  618. lifetime = WPA_GET_BE32(kde->lifetime);
  619. if (lifetime >= peerkey->lifetime) {
  620. wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
  621. "which is larger than or equal to own value %u "
  622. "seconds - ignored", lifetime, peerkey->lifetime);
  623. return;
  624. }
  625. wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
  626. "(own was %u seconds) - updated",
  627. lifetime, peerkey->lifetime);
  628. peerkey->lifetime = lifetime;
  629. os_get_time(&now);
  630. peerkey->expiration = now.sec + lifetime;
  631. eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
  632. eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
  633. sm, peerkey);
  634. }
  635. static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
  636. struct wpa_peerkey *peerkey,
  637. const struct wpa_eapol_key *key,
  638. u16 ver)
  639. {
  640. struct wpa_eapol_ie_parse kde;
  641. const u8 *keydata;
  642. size_t len;
  643. wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
  644. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  645. os_memset(&kde, 0, sizeof(kde));
  646. /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
  647. * from the peer. It may also include Lifetime KDE. */
  648. keydata = (const u8 *) (key + 1);
  649. len = WPA_GET_BE16(key->key_data_length);
  650. wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
  651. if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
  652. kde.pmkid == NULL || kde.rsn_ie == NULL) {
  653. wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
  654. return;
  655. }
  656. if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
  657. wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
  658. kde.pmkid, PMKID_LEN);
  659. return;
  660. }
  661. if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
  662. os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
  663. wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
  664. "handshakes did not match");
  665. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
  666. peerkey->rsnie_p, peerkey->rsnie_p_len);
  667. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
  668. kde.rsn_ie, kde.rsn_ie_len);
  669. return;
  670. }
  671. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  672. wpa_supplicant_send_stk_3_of_4(sm, peerkey);
  673. os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
  674. }
  675. static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
  676. struct wpa_peerkey *peerkey,
  677. const struct wpa_eapol_key *key,
  678. u16 ver)
  679. {
  680. struct wpa_eapol_ie_parse kde;
  681. const u8 *keydata;
  682. size_t len, key_len;
  683. const u8 *_key;
  684. u8 key_buf[32], rsc[6];
  685. wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
  686. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  687. os_memset(&kde, 0, sizeof(kde));
  688. /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
  689. * Lifetime KDE. */
  690. keydata = (const u8 *) (key + 1);
  691. len = WPA_GET_BE16(key->key_data_length);
  692. wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
  693. if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
  694. wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
  695. "STK 3/4");
  696. return;
  697. }
  698. if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
  699. os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
  700. wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
  701. "handshakes did not match");
  702. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
  703. "handshake",
  704. peerkey->rsnie_i, peerkey->rsnie_i_len);
  705. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
  706. "handshake",
  707. kde.rsn_ie, kde.rsn_ie_len);
  708. return;
  709. }
  710. if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
  711. wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
  712. "4-Way Handshake differs from 3 of STK 4-Way "
  713. "Handshake - drop packet (src=" MACSTR ")",
  714. MAC2STR(peerkey->addr));
  715. return;
  716. }
  717. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  718. if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
  719. WPA_GET_BE16(key->key_info),
  720. NULL, 0, &peerkey->stk))
  721. return;
  722. _key = (u8 *) peerkey->stk.tk1;
  723. if (peerkey->cipher == WPA_CIPHER_TKIP) {
  724. /* Swap Tx/Rx keys for Michael MIC */
  725. os_memcpy(key_buf, _key, 16);
  726. os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
  727. os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
  728. _key = key_buf;
  729. key_len = 32;
  730. } else
  731. key_len = 16;
  732. os_memset(rsc, 0, 6);
  733. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  734. rsc, sizeof(rsc), _key, key_len) < 0) {
  735. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  736. "driver.");
  737. return;
  738. }
  739. }
  740. static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
  741. struct wpa_peerkey *peerkey,
  742. const struct wpa_eapol_key *key,
  743. u16 ver)
  744. {
  745. u8 rsc[6];
  746. wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
  747. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  748. os_memset(rsc, 0, 6);
  749. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  750. rsc, sizeof(rsc), (u8 *) peerkey->stk.tk1,
  751. peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
  752. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  753. "driver.");
  754. return;
  755. }
  756. }
  757. /**
  758. * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
  759. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  760. * @peerkey: Pointer to the PeerKey data for the peer
  761. * @key: Pointer to the EAPOL-Key frame header
  762. * @ver: Version bits from EAPOL-Key Key Info
  763. * @buf: Pointer to the beginning of EAPOL-Key frame
  764. * @len: Length of the EAPOL-Key frame
  765. * Returns: 0 on success, -1 on failure
  766. */
  767. int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
  768. struct wpa_peerkey *peerkey,
  769. struct wpa_eapol_key *key, u16 ver,
  770. const u8 *buf, size_t len)
  771. {
  772. u8 mic[16];
  773. int ok = 0;
  774. if (peerkey->initiator && !peerkey->stk_set) {
  775. wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
  776. sm->own_addr, peerkey->addr,
  777. peerkey->inonce, key->key_nonce,
  778. (u8 *) &peerkey->stk, sizeof(peerkey->stk),
  779. peerkey->use_sha256);
  780. peerkey->stk_set = 1;
  781. }
  782. os_memcpy(mic, key->key_mic, 16);
  783. if (peerkey->tstk_set) {
  784. os_memset(key->key_mic, 0, 16);
  785. wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
  786. key->key_mic);
  787. if (os_memcmp(mic, key->key_mic, 16) != 0) {
  788. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  789. "when using TSTK - ignoring TSTK");
  790. } else {
  791. ok = 1;
  792. peerkey->tstk_set = 0;
  793. peerkey->stk_set = 1;
  794. os_memcpy(&peerkey->stk, &peerkey->tstk,
  795. sizeof(peerkey->stk));
  796. }
  797. }
  798. if (!ok && peerkey->stk_set) {
  799. os_memset(key->key_mic, 0, 16);
  800. wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
  801. key->key_mic);
  802. if (os_memcmp(mic, key->key_mic, 16) != 0) {
  803. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  804. "- dropping packet");
  805. return -1;
  806. }
  807. ok = 1;
  808. }
  809. if (!ok) {
  810. wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
  811. "- dropping packet");
  812. return -1;
  813. }
  814. os_memcpy(peerkey->replay_counter, key->replay_counter,
  815. WPA_REPLAY_COUNTER_LEN);
  816. peerkey->replay_counter_set = 1;
  817. return 0;
  818. }
  819. /**
  820. * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
  821. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  822. * @peer: MAC address of the peer STA
  823. * Returns: 0 on success, or -1 on failure
  824. *
  825. * Send an EAPOL-Key Request to the current authenticator to start STK
  826. * handshake with the peer.
  827. */
  828. int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
  829. {
  830. size_t rlen, kde_len;
  831. struct wpa_eapol_key *req;
  832. int key_info, ver;
  833. u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
  834. u16 count;
  835. struct rsn_ie_hdr *hdr;
  836. struct wpa_peerkey *peerkey;
  837. struct wpa_ie_data ie;
  838. if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
  839. return -1;
  840. if (sm->ap_rsn_ie &&
  841. wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
  842. !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
  843. wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
  844. return -1;
  845. }
  846. if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
  847. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  848. else
  849. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  850. if (wpa_sm_get_bssid(sm, bssid) < 0) {
  851. wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
  852. "SMK M1");
  853. return -1;
  854. }
  855. /* TODO: find existing entry and if found, use that instead of adding
  856. * a new one */
  857. peerkey = os_zalloc(sizeof(*peerkey));
  858. if (peerkey == NULL)
  859. return -1;
  860. peerkey->initiator = 1;
  861. os_memcpy(peerkey->addr, peer, ETH_ALEN);
  862. #ifdef CONFIG_IEEE80211W
  863. if (wpa_key_mgmt_sha256(sm->key_mgmt))
  864. peerkey->use_sha256 = 1;
  865. #endif /* CONFIG_IEEE80211W */
  866. /* SMK M1:
  867. * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
  868. * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
  869. */
  870. hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
  871. hdr->elem_id = WLAN_EID_RSN;
  872. WPA_PUT_LE16(hdr->version, RSN_VERSION);
  873. pos = (u8 *) (hdr + 1);
  874. /* Group Suite can be anything for SMK RSN IE; receiver will just
  875. * ignore it. */
  876. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  877. pos += RSN_SELECTOR_LEN;
  878. count_pos = pos;
  879. pos += 2;
  880. count = rsn_cipher_put_suites(pos, sm->allowed_pairwise_cipher);
  881. pos += count * RSN_SELECTOR_LEN;
  882. WPA_PUT_LE16(count_pos, count);
  883. hdr->len = (pos - peerkey->rsnie_i) - 2;
  884. peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
  885. wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
  886. peerkey->rsnie_i, peerkey->rsnie_i_len);
  887. kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
  888. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  889. sizeof(*req) + kde_len, &rlen,
  890. (void *) &req);
  891. if (rbuf == NULL) {
  892. wpa_supplicant_peerkey_free(sm, peerkey);
  893. return -1;
  894. }
  895. req->type = EAPOL_KEY_TYPE_RSN;
  896. key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  897. WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
  898. WPA_PUT_BE16(req->key_info, key_info);
  899. WPA_PUT_BE16(req->key_length, 0);
  900. os_memcpy(req->replay_counter, sm->request_counter,
  901. WPA_REPLAY_COUNTER_LEN);
  902. inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
  903. if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
  904. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  905. "WPA: Failed to get random data for INonce");
  906. os_free(rbuf);
  907. wpa_supplicant_peerkey_free(sm, peerkey);
  908. return -1;
  909. }
  910. os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  911. wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
  912. req->key_nonce, WPA_NONCE_LEN);
  913. WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
  914. pos = (u8 *) (req + 1);
  915. /* Initiator RSN IE */
  916. pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
  917. /* Peer MAC address KDE */
  918. wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
  919. wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
  920. MACSTR ")", MAC2STR(peer));
  921. wpa_eapol_key_send(sm, sm->ptk.kck, ver, bssid, ETH_P_EAPOL,
  922. rbuf, rlen, req->key_mic);
  923. peerkey->next = sm->peerkey;
  924. sm->peerkey = peerkey;
  925. return 0;
  926. }
  927. /**
  928. * peerkey_deinit - Free PeerKey values
  929. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  930. */
  931. void peerkey_deinit(struct wpa_sm *sm)
  932. {
  933. struct wpa_peerkey *prev, *peerkey = sm->peerkey;
  934. while (peerkey) {
  935. prev = peerkey;
  936. peerkey = peerkey->next;
  937. os_free(prev);
  938. }
  939. sm->peerkey = NULL;
  940. }
  941. void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
  942. struct wpa_eapol_key *key, u16 key_info, u16 ver)
  943. {
  944. if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
  945. (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
  946. /* 3/4 STK 4-Way Handshake */
  947. wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
  948. } else if (key_info & WPA_KEY_INFO_ACK) {
  949. /* 1/4 STK 4-Way Handshake */
  950. wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
  951. } else if (key_info & WPA_KEY_INFO_SECURE) {
  952. /* 4/4 STK 4-Way Handshake */
  953. wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
  954. } else {
  955. /* 2/4 STK 4-Way Handshake */
  956. wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
  957. }
  958. }
  959. void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
  960. struct wpa_eapol_key *key, size_t extra_len,
  961. u16 key_info, u16 ver)
  962. {
  963. if (key_info & WPA_KEY_INFO_ERROR) {
  964. /* SMK Error */
  965. wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
  966. } else if (key_info & WPA_KEY_INFO_ACK) {
  967. /* SMK M2 */
  968. wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
  969. ver);
  970. } else {
  971. /* SMK M4 or M5 */
  972. wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
  973. ver);
  974. }
  975. }
  976. #endif /* CONFIG_PEERKEY */