peerkey.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. /*
  2. * WPA Supplicant - PeerKey for Direct Link Setup (DLS)
  3. * Copyright (c) 2006-2015, 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 wpa_eapol_key_192 *err192;
  56. struct rsn_error_kde error;
  57. u8 *rbuf, *pos;
  58. size_t kde_len;
  59. u16 key_info;
  60. kde_len = 2 + RSN_SELECTOR_LEN + sizeof(error);
  61. if (peer)
  62. kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
  63. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
  64. NULL, sizeof(*err) + kde_len, &rlen,
  65. (void *) &err);
  66. if (rbuf == NULL)
  67. return -1;
  68. err192 = (struct wpa_eapol_key_192 *) err;
  69. err->type = EAPOL_KEY_TYPE_RSN;
  70. key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  71. WPA_KEY_INFO_SECURE | WPA_KEY_INFO_ERROR |
  72. WPA_KEY_INFO_REQUEST;
  73. WPA_PUT_BE16(err->key_info, key_info);
  74. WPA_PUT_BE16(err->key_length, 0);
  75. os_memcpy(err->replay_counter, sm->request_counter,
  76. WPA_REPLAY_COUNTER_LEN);
  77. inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
  78. WPA_PUT_BE16(err->key_data_length, (u16) kde_len);
  79. pos = (u8 *) (err + 1);
  80. if (peer) {
  81. /* Peer MAC Address KDE */
  82. pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
  83. }
  84. /* Error KDE */
  85. error.mui = host_to_be16(mui);
  86. error.error_type = host_to_be16(error_type);
  87. wpa_add_kde(pos, RSN_KEY_DATA_ERROR, (u8 *) &error, sizeof(error));
  88. if (peer) {
  89. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error (peer "
  90. MACSTR " mui %d error_type %d)",
  91. MAC2STR(peer), mui, error_type);
  92. } else {
  93. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK Error "
  94. "(mui %d error_type %d)", mui, error_type);
  95. }
  96. wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, dst,
  97. ETH_P_EAPOL, rbuf, rlen, err192->key_mic);
  98. return 0;
  99. }
  100. static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
  101. const unsigned char *src_addr,
  102. const struct wpa_eapol_key *key,
  103. int ver, struct wpa_peerkey *peerkey)
  104. {
  105. size_t rlen;
  106. struct wpa_eapol_key *reply;
  107. struct wpa_eapol_key_192 *reply192;
  108. u8 *rbuf, *pos;
  109. size_t kde_len;
  110. u16 key_info;
  111. /* KDEs: Peer RSN IE, Initiator MAC Address, Initiator Nonce */
  112. kde_len = peerkey->rsnie_p_len +
  113. 2 + RSN_SELECTOR_LEN + ETH_ALEN +
  114. 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN;
  115. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
  116. NULL, sizeof(*reply) + kde_len, &rlen,
  117. (void *) &reply);
  118. if (rbuf == NULL)
  119. return -1;
  120. reply192 = (struct wpa_eapol_key_192 *) reply;
  121. reply->type = EAPOL_KEY_TYPE_RSN;
  122. key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  123. WPA_KEY_INFO_SECURE;
  124. WPA_PUT_BE16(reply->key_info, key_info);
  125. WPA_PUT_BE16(reply->key_length, 0);
  126. os_memcpy(reply->replay_counter, key->replay_counter,
  127. WPA_REPLAY_COUNTER_LEN);
  128. os_memcpy(reply->key_nonce, peerkey->pnonce, WPA_NONCE_LEN);
  129. WPA_PUT_BE16(reply->key_data_length, (u16) kde_len);
  130. pos = (u8 *) (reply + 1);
  131. /* Peer RSN IE */
  132. pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
  133. /* Initiator MAC Address KDE */
  134. pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peerkey->addr, ETH_ALEN);
  135. /* Initiator Nonce */
  136. wpa_add_kde(pos, RSN_KEY_DATA_NONCE, peerkey->inonce, WPA_NONCE_LEN);
  137. wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
  138. wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, src_addr,
  139. ETH_P_EAPOL, rbuf, rlen, reply192->key_mic);
  140. return 0;
  141. }
  142. static int wpa_supplicant_process_smk_m2(
  143. struct wpa_sm *sm, const unsigned char *src_addr,
  144. const struct wpa_eapol_key *key, size_t extra_len, int ver)
  145. {
  146. struct wpa_peerkey *peerkey;
  147. struct wpa_eapol_ie_parse kde;
  148. struct wpa_ie_data ie;
  149. int cipher;
  150. struct rsn_ie_hdr *hdr;
  151. u8 *pos;
  152. wpa_printf(MSG_DEBUG, "RSN: Received SMK M2");
  153. if (!sm->peerkey_enabled || sm->proto != WPA_PROTO_RSN) {
  154. wpa_printf(MSG_INFO, "RSN: SMK handshake not allowed for "
  155. "the current network");
  156. return -1;
  157. }
  158. if (wpa_supplicant_parse_ies((const u8 *) (key + 1), extra_len, &kde) <
  159. 0) {
  160. wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M2");
  161. return -1;
  162. }
  163. if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
  164. kde.mac_addr_len < ETH_ALEN) {
  165. wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
  166. "SMK M2");
  167. return -1;
  168. }
  169. wpa_printf(MSG_DEBUG, "RSN: SMK M2 - SMK initiator " MACSTR,
  170. MAC2STR(kde.mac_addr));
  171. if (kde.rsn_ie_len > PEERKEY_MAX_IE_LEN) {
  172. wpa_printf(MSG_INFO, "RSN: Too long Initiator RSN IE in SMK "
  173. "M2");
  174. return -1;
  175. }
  176. if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
  177. wpa_printf(MSG_INFO, "RSN: Failed to parse RSN IE in SMK M2");
  178. return -1;
  179. }
  180. cipher = wpa_pick_pairwise_cipher(ie.pairwise_cipher &
  181. sm->allowed_pairwise_cipher, 0);
  182. if (cipher < 0) {
  183. wpa_printf(MSG_INFO, "RSN: No acceptable cipher in SMK M2");
  184. wpa_supplicant_send_smk_error(sm, src_addr, kde.mac_addr,
  185. STK_MUI_SMK, STK_ERR_CPHR_NS,
  186. ver);
  187. return -1;
  188. }
  189. wpa_printf(MSG_DEBUG, "RSN: Using %s for PeerKey",
  190. wpa_cipher_txt(cipher));
  191. /* TODO: find existing entry and if found, use that instead of adding
  192. * a new one; how to handle the case where both ends initiate at the
  193. * same time? */
  194. peerkey = os_zalloc(sizeof(*peerkey));
  195. if (peerkey == NULL)
  196. return -1;
  197. os_memcpy(peerkey->addr, kde.mac_addr, ETH_ALEN);
  198. os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
  199. os_memcpy(peerkey->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
  200. peerkey->rsnie_i_len = kde.rsn_ie_len;
  201. peerkey->cipher = cipher;
  202. peerkey->akmp = ie.key_mgmt;
  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. * @akmp: Negotiated AKM
  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 akmp)
  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 (wpa_key_mgmt_sha256(akmp))
  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, 0, 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, peerkey->stk.kck_len, ver,
  351. peerkey->addr, ETH_P_EAPOL, mbuf, mlen,
  352. 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->akmp);
  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->akmp);
  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. stk, peerkey->akmp, peerkey->cipher);
  580. /* Supplicant: swap tx/rx Mic keys */
  581. os_memcpy(buf, &stk->tk[16], 8);
  582. os_memcpy(&stk->tk[16], &stk->tk[24], 8);
  583. os_memcpy(&stk->tk[24], buf, 8);
  584. peerkey->tstk_set = 1;
  585. kde_buf_len = peerkey->rsnie_p_len +
  586. 2 + RSN_SELECTOR_LEN + sizeof(lifetime) +
  587. 2 + RSN_SELECTOR_LEN + PMKID_LEN;
  588. kde_buf = os_malloc(kde_buf_len);
  589. if (kde_buf == NULL)
  590. return;
  591. pos = kde_buf;
  592. pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len);
  593. lifetime = host_to_be32(peerkey->lifetime);
  594. pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
  595. (u8 *) &lifetime, sizeof(lifetime));
  596. wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN);
  597. if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver,
  598. peerkey->pnonce, kde_buf, kde_buf_len,
  599. stk)) {
  600. os_free(kde_buf);
  601. return;
  602. }
  603. os_free(kde_buf);
  604. os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN);
  605. }
  606. static void wpa_supplicant_update_smk_lifetime(struct wpa_sm *sm,
  607. struct wpa_peerkey *peerkey,
  608. struct wpa_eapol_ie_parse *kde)
  609. {
  610. u32 lifetime;
  611. if (kde->lifetime == NULL || kde->lifetime_len < sizeof(lifetime))
  612. return;
  613. lifetime = WPA_GET_BE32(kde->lifetime);
  614. if (lifetime >= peerkey->lifetime) {
  615. wpa_printf(MSG_DEBUG, "RSN: Peer used SMK lifetime %u seconds "
  616. "which is larger than or equal to own value %u "
  617. "seconds - ignored", lifetime, peerkey->lifetime);
  618. return;
  619. }
  620. wpa_printf(MSG_DEBUG, "RSN: Peer used shorter SMK lifetime %u seconds "
  621. "(own was %u seconds) - updated",
  622. lifetime, peerkey->lifetime);
  623. peerkey->lifetime = lifetime;
  624. eloop_cancel_timeout(wpa_supplicant_smk_timeout, sm, peerkey);
  625. eloop_register_timeout(lifetime, 0, wpa_supplicant_smk_timeout,
  626. sm, peerkey);
  627. }
  628. static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
  629. struct wpa_peerkey *peerkey,
  630. const struct wpa_eapol_key *key,
  631. u16 ver, const u8 *key_data,
  632. size_t key_data_len)
  633. {
  634. struct wpa_eapol_ie_parse kde;
  635. wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
  636. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  637. os_memset(&kde, 0, sizeof(kde));
  638. /* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
  639. * from the peer. It may also include Lifetime KDE. */
  640. wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", key_data, key_data_len);
  641. if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0 ||
  642. kde.pmkid == NULL || kde.rsn_ie == NULL) {
  643. wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
  644. return;
  645. }
  646. if (os_memcmp_const(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
  647. wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
  648. kde.pmkid, PMKID_LEN);
  649. return;
  650. }
  651. if (kde.rsn_ie_len != peerkey->rsnie_p_len ||
  652. os_memcmp(kde.rsn_ie, peerkey->rsnie_p, kde.rsn_ie_len) != 0) {
  653. wpa_printf(MSG_INFO, "RSN: Peer RSN IE in SMK and STK "
  654. "handshakes did not match");
  655. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in SMK handshake",
  656. peerkey->rsnie_p, peerkey->rsnie_p_len);
  657. wpa_hexdump(MSG_DEBUG, "RSN: Peer RSN IE in STK handshake",
  658. kde.rsn_ie, kde.rsn_ie_len);
  659. return;
  660. }
  661. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  662. wpa_supplicant_send_stk_3_of_4(sm, peerkey);
  663. os_memcpy(peerkey->pnonce, key->key_nonce, WPA_NONCE_LEN);
  664. }
  665. static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
  666. struct wpa_peerkey *peerkey,
  667. const struct wpa_eapol_key *key,
  668. u16 ver, const u8 *key_data,
  669. size_t key_data_len)
  670. {
  671. struct wpa_eapol_ie_parse kde;
  672. size_t key_len;
  673. const u8 *_key;
  674. u8 key_buf[32], rsc[6];
  675. wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
  676. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  677. os_memset(&kde, 0, sizeof(kde));
  678. /* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
  679. * Lifetime KDE. */
  680. wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", key_data, key_data_len);
  681. if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0) {
  682. wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
  683. "STK 3/4");
  684. return;
  685. }
  686. if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
  687. os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
  688. wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
  689. "handshakes did not match");
  690. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
  691. "handshake",
  692. peerkey->rsnie_i, peerkey->rsnie_i_len);
  693. wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
  694. "handshake",
  695. kde.rsn_ie, kde.rsn_ie_len);
  696. return;
  697. }
  698. if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
  699. wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
  700. "4-Way Handshake differs from 3 of STK 4-Way "
  701. "Handshake - drop packet (src=" MACSTR ")",
  702. MAC2STR(peerkey->addr));
  703. return;
  704. }
  705. wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);
  706. if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
  707. WPA_GET_BE16(key->key_info),
  708. &peerkey->stk))
  709. return;
  710. _key = peerkey->stk.tk;
  711. if (peerkey->cipher == WPA_CIPHER_TKIP) {
  712. /* Swap Tx/Rx keys for Michael MIC */
  713. os_memcpy(key_buf, _key, 16);
  714. os_memcpy(key_buf + 16, _key + 24, 8);
  715. os_memcpy(key_buf + 24, _key + 16, 8);
  716. _key = key_buf;
  717. key_len = 32;
  718. } else
  719. key_len = 16;
  720. os_memset(rsc, 0, 6);
  721. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  722. rsc, sizeof(rsc), _key, key_len) < 0) {
  723. os_memset(key_buf, 0, sizeof(key_buf));
  724. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  725. "driver.");
  726. return;
  727. }
  728. os_memset(key_buf, 0, sizeof(key_buf));
  729. }
  730. static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
  731. struct wpa_peerkey *peerkey,
  732. const struct wpa_eapol_key *key,
  733. u16 ver)
  734. {
  735. u8 rsc[6];
  736. wpa_printf(MSG_DEBUG, "RSN: RX message 4 of STK 4-Way Handshake from "
  737. MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
  738. os_memset(rsc, 0, 6);
  739. if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
  740. rsc, sizeof(rsc), peerkey->stk.tk,
  741. peerkey->cipher == WPA_CIPHER_TKIP ? 32 : 16) < 0) {
  742. wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
  743. "driver.");
  744. return;
  745. }
  746. }
  747. /**
  748. * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
  749. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  750. * @peerkey: Pointer to the PeerKey data for the peer
  751. * @key: Pointer to the EAPOL-Key frame header
  752. * @ver: Version bits from EAPOL-Key Key Info
  753. * @buf: Pointer to the beginning of EAPOL-Key frame
  754. * @len: Length of the EAPOL-Key frame
  755. * Returns: 0 on success, -1 on failure
  756. */
  757. int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
  758. struct wpa_peerkey *peerkey,
  759. struct wpa_eapol_key_192 *key, u16 ver,
  760. const u8 *buf, size_t len)
  761. {
  762. u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
  763. size_t mic_len = 16;
  764. int ok = 0;
  765. if (peerkey->initiator && !peerkey->stk_set) {
  766. wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
  767. sm->own_addr, peerkey->addr,
  768. peerkey->inonce, key->key_nonce,
  769. &peerkey->stk, peerkey->akmp, peerkey->cipher);
  770. peerkey->stk_set = 1;
  771. }
  772. os_memcpy(mic, key->key_mic, mic_len);
  773. if (peerkey->tstk_set) {
  774. os_memset(key->key_mic, 0, mic_len);
  775. wpa_eapol_key_mic(peerkey->tstk.kck, peerkey->tstk.kck_len,
  776. sm->key_mgmt, ver, buf, len, key->key_mic);
  777. if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
  778. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  779. "when using TSTK - ignoring TSTK");
  780. } else {
  781. ok = 1;
  782. peerkey->tstk_set = 0;
  783. peerkey->stk_set = 1;
  784. os_memcpy(&peerkey->stk, &peerkey->tstk,
  785. sizeof(peerkey->stk));
  786. os_memset(&peerkey->tstk, 0, sizeof(peerkey->tstk));
  787. }
  788. }
  789. if (!ok && peerkey->stk_set) {
  790. os_memset(key->key_mic, 0, mic_len);
  791. wpa_eapol_key_mic(peerkey->stk.kck, peerkey->stk.kck_len,
  792. sm->key_mgmt, ver, buf, len, key->key_mic);
  793. if (os_memcmp_const(mic, key->key_mic, mic_len) != 0) {
  794. wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
  795. "- dropping packet");
  796. return -1;
  797. }
  798. ok = 1;
  799. }
  800. if (!ok) {
  801. wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
  802. "- dropping packet");
  803. return -1;
  804. }
  805. os_memcpy(peerkey->replay_counter, key->replay_counter,
  806. WPA_REPLAY_COUNTER_LEN);
  807. peerkey->replay_counter_set = 1;
  808. return 0;
  809. }
  810. /**
  811. * wpa_sm_stkstart - Send EAPOL-Key Request for STK handshake (STK M1)
  812. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  813. * @peer: MAC address of the peer STA
  814. * Returns: 0 on success, or -1 on failure
  815. *
  816. * Send an EAPOL-Key Request to the current authenticator to start STK
  817. * handshake with the peer.
  818. */
  819. int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
  820. {
  821. size_t rlen, kde_len;
  822. struct wpa_eapol_key *req;
  823. int key_info, ver;
  824. u8 bssid[ETH_ALEN], *rbuf, *pos, *count_pos;
  825. u16 count;
  826. struct rsn_ie_hdr *hdr;
  827. struct wpa_peerkey *peerkey;
  828. struct wpa_ie_data ie;
  829. if (sm->proto != WPA_PROTO_RSN || !sm->ptk_set || !sm->peerkey_enabled)
  830. return -1;
  831. if (sm->ap_rsn_ie &&
  832. wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &ie) == 0 &&
  833. !(ie.capabilities & WPA_CAPABILITY_PEERKEY_ENABLED)) {
  834. wpa_printf(MSG_DEBUG, "RSN: Current AP does not support STK");
  835. return -1;
  836. }
  837. if (sm->pairwise_cipher != WPA_CIPHER_TKIP)
  838. ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
  839. else
  840. ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
  841. if (wpa_sm_get_bssid(sm, bssid) < 0) {
  842. wpa_printf(MSG_WARNING, "Failed to read BSSID for EAPOL-Key "
  843. "SMK M1");
  844. return -1;
  845. }
  846. /* TODO: find existing entry and if found, use that instead of adding
  847. * a new one */
  848. peerkey = os_zalloc(sizeof(*peerkey));
  849. if (peerkey == NULL)
  850. return -1;
  851. peerkey->initiator = 1;
  852. os_memcpy(peerkey->addr, peer, ETH_ALEN);
  853. peerkey->akmp = sm->key_mgmt;
  854. /* SMK M1:
  855. * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
  856. * MIC=MIC, DataKDs=(RSNIE_I, MAC_P KDE))
  857. */
  858. hdr = (struct rsn_ie_hdr *) peerkey->rsnie_i;
  859. hdr->elem_id = WLAN_EID_RSN;
  860. WPA_PUT_LE16(hdr->version, RSN_VERSION);
  861. pos = (u8 *) (hdr + 1);
  862. /* Group Suite can be anything for SMK RSN IE; receiver will just
  863. * ignore it. */
  864. RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
  865. pos += RSN_SELECTOR_LEN;
  866. count_pos = pos;
  867. pos += 2;
  868. count = rsn_cipher_put_suites(pos, sm->allowed_pairwise_cipher);
  869. pos += count * RSN_SELECTOR_LEN;
  870. WPA_PUT_LE16(count_pos, count);
  871. hdr->len = (pos - peerkey->rsnie_i) - 2;
  872. peerkey->rsnie_i_len = pos - peerkey->rsnie_i;
  873. wpa_hexdump(MSG_DEBUG, "WPA: RSN IE for SMK handshake",
  874. peerkey->rsnie_i, peerkey->rsnie_i_len);
  875. kde_len = peerkey->rsnie_i_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
  876. rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
  877. sizeof(*req) + kde_len, &rlen,
  878. (void *) &req);
  879. if (rbuf == NULL) {
  880. wpa_supplicant_peerkey_free(sm, peerkey);
  881. return -1;
  882. }
  883. req->type = EAPOL_KEY_TYPE_RSN;
  884. key_info = WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
  885. WPA_KEY_INFO_SECURE | WPA_KEY_INFO_REQUEST | ver;
  886. WPA_PUT_BE16(req->key_info, key_info);
  887. WPA_PUT_BE16(req->key_length, 0);
  888. os_memcpy(req->replay_counter, sm->request_counter,
  889. WPA_REPLAY_COUNTER_LEN);
  890. inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
  891. if (random_get_bytes(peerkey->inonce, WPA_NONCE_LEN)) {
  892. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  893. "WPA: Failed to get random data for INonce");
  894. os_free(rbuf);
  895. wpa_supplicant_peerkey_free(sm, peerkey);
  896. return -1;
  897. }
  898. os_memcpy(req->key_nonce, peerkey->inonce, WPA_NONCE_LEN);
  899. wpa_hexdump(MSG_DEBUG, "WPA: INonce for SMK handshake",
  900. req->key_nonce, WPA_NONCE_LEN);
  901. WPA_PUT_BE16(req->key_data_length, (u16) kde_len);
  902. pos = (u8 *) (req + 1);
  903. /* Initiator RSN IE */
  904. pos = wpa_add_ie(pos, peerkey->rsnie_i, peerkey->rsnie_i_len);
  905. /* Peer MAC address KDE */
  906. wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN);
  907. wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer "
  908. MACSTR ")", MAC2STR(peer));
  909. wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
  910. ETH_P_EAPOL, rbuf, rlen, req->key_mic);
  911. peerkey->next = sm->peerkey;
  912. sm->peerkey = peerkey;
  913. return 0;
  914. }
  915. /**
  916. * peerkey_deinit - Free PeerKey values
  917. * @sm: Pointer to WPA state machine data from wpa_sm_init()
  918. */
  919. void peerkey_deinit(struct wpa_sm *sm)
  920. {
  921. struct wpa_peerkey *prev, *peerkey = sm->peerkey;
  922. while (peerkey) {
  923. prev = peerkey;
  924. peerkey = peerkey->next;
  925. wpa_supplicant_peerkey_free(sm, prev);
  926. }
  927. sm->peerkey = NULL;
  928. }
  929. void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
  930. struct wpa_eapol_key *key, u16 key_info, u16 ver,
  931. const u8 *key_data, size_t key_data_len)
  932. {
  933. if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
  934. (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
  935. /* 3/4 STK 4-Way Handshake */
  936. wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver,
  937. key_data, key_data_len);
  938. } else if (key_info & WPA_KEY_INFO_ACK) {
  939. /* 1/4 STK 4-Way Handshake */
  940. wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver,
  941. key_data, key_data_len);
  942. } else if (key_info & WPA_KEY_INFO_SECURE) {
  943. /* 4/4 STK 4-Way Handshake */
  944. wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
  945. } else {
  946. /* 2/4 STK 4-Way Handshake */
  947. wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver,
  948. key_data, key_data_len);
  949. }
  950. }
  951. void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
  952. struct wpa_eapol_key *key, size_t extra_len,
  953. u16 key_info, u16 ver)
  954. {
  955. if (key_info & WPA_KEY_INFO_ERROR) {
  956. /* SMK Error */
  957. wpa_supplicant_process_smk_error(sm, src_addr, key, extra_len);
  958. } else if (key_info & WPA_KEY_INFO_ACK) {
  959. /* SMK M2 */
  960. wpa_supplicant_process_smk_m2(sm, src_addr, key, extra_len,
  961. ver);
  962. } else {
  963. /* SMK M4 or M5 */
  964. wpa_supplicant_process_smk_m45(sm, src_addr, key, extra_len,
  965. ver);
  966. }
  967. }
  968. #endif /* CONFIG_PEERKEY */