eap_psk.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * EAP peer method: EAP-PSK (RFC 4764)
  3. * Copyright (c) 2004-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. * Note: EAP-PSK is an EAP authentication method and as such, completely
  9. * different from WPA-PSK. This file is not needed for WPA-PSK functionality.
  10. */
  11. #include "includes.h"
  12. #include "common.h"
  13. #include "crypto/aes_wrap.h"
  14. #include "crypto/random.h"
  15. #include "eap_common/eap_psk_common.h"
  16. #include "eap_i.h"
  17. struct eap_psk_data {
  18. enum { PSK_INIT, PSK_MAC_SENT, PSK_DONE } state;
  19. u8 rand_p[EAP_PSK_RAND_LEN];
  20. u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
  21. u8 *id_s, *id_p;
  22. size_t id_s_len, id_p_len;
  23. u8 msk[EAP_MSK_LEN];
  24. u8 emsk[EAP_EMSK_LEN];
  25. };
  26. static void * eap_psk_init(struct eap_sm *sm)
  27. {
  28. struct eap_psk_data *data;
  29. const u8 *identity, *password;
  30. size_t identity_len, password_len;
  31. password = eap_get_config_password(sm, &password_len);
  32. if (!password || password_len != 16) {
  33. wpa_printf(MSG_INFO, "EAP-PSK: 16-octet pre-shared key not "
  34. "configured");
  35. return NULL;
  36. }
  37. data = os_zalloc(sizeof(*data));
  38. if (data == NULL)
  39. return NULL;
  40. if (eap_psk_key_setup(password, data->ak, data->kdk)) {
  41. os_free(data);
  42. return NULL;
  43. }
  44. wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
  45. wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);
  46. data->state = PSK_INIT;
  47. identity = eap_get_config_identity(sm, &identity_len);
  48. if (identity) {
  49. data->id_p = os_malloc(identity_len);
  50. if (data->id_p)
  51. os_memcpy(data->id_p, identity, identity_len);
  52. data->id_p_len = identity_len;
  53. }
  54. if (data->id_p == NULL) {
  55. wpa_printf(MSG_INFO, "EAP-PSK: could not get own identity");
  56. os_free(data);
  57. return NULL;
  58. }
  59. return data;
  60. }
  61. static void eap_psk_deinit(struct eap_sm *sm, void *priv)
  62. {
  63. struct eap_psk_data *data = priv;
  64. os_free(data->id_s);
  65. os_free(data->id_p);
  66. os_free(data);
  67. }
  68. static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
  69. struct eap_method_ret *ret,
  70. const struct wpabuf *reqData)
  71. {
  72. const struct eap_psk_hdr_1 *hdr1;
  73. struct eap_psk_hdr_2 *hdr2;
  74. struct wpabuf *resp;
  75. u8 *buf, *pos;
  76. size_t buflen, len;
  77. const u8 *cpos;
  78. wpa_printf(MSG_DEBUG, "EAP-PSK: in INIT state");
  79. cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
  80. hdr1 = (const struct eap_psk_hdr_1 *) cpos;
  81. if (cpos == NULL || len < sizeof(*hdr1)) {
  82. wpa_printf(MSG_INFO, "EAP-PSK: Invalid first message "
  83. "length (%lu; expected %lu or more)",
  84. (unsigned long) len,
  85. (unsigned long) sizeof(*hdr1));
  86. ret->ignore = TRUE;
  87. return NULL;
  88. }
  89. wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr1->flags);
  90. if (EAP_PSK_FLAGS_GET_T(hdr1->flags) != 0) {
  91. wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 0)",
  92. EAP_PSK_FLAGS_GET_T(hdr1->flags));
  93. ret->methodState = METHOD_DONE;
  94. ret->decision = DECISION_FAIL;
  95. return NULL;
  96. }
  97. wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s,
  98. EAP_PSK_RAND_LEN);
  99. os_free(data->id_s);
  100. data->id_s_len = len - sizeof(*hdr1);
  101. data->id_s = os_malloc(data->id_s_len);
  102. if (data->id_s == NULL) {
  103. wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory for "
  104. "ID_S (len=%lu)", (unsigned long) data->id_s_len);
  105. ret->ignore = TRUE;
  106. return NULL;
  107. }
  108. os_memcpy(data->id_s, (u8 *) (hdr1 + 1), data->id_s_len);
  109. wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S",
  110. data->id_s, data->id_s_len);
  111. if (random_get_bytes(data->rand_p, EAP_PSK_RAND_LEN)) {
  112. wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
  113. ret->ignore = TRUE;
  114. return NULL;
  115. }
  116. resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
  117. sizeof(*hdr2) + data->id_p_len, EAP_CODE_RESPONSE,
  118. eap_get_id(reqData));
  119. if (resp == NULL)
  120. return NULL;
  121. hdr2 = wpabuf_put(resp, sizeof(*hdr2));
  122. hdr2->flags = EAP_PSK_FLAGS_SET_T(1); /* T=1 */
  123. os_memcpy(hdr2->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
  124. os_memcpy(hdr2->rand_p, data->rand_p, EAP_PSK_RAND_LEN);
  125. wpabuf_put_data(resp, data->id_p, data->id_p_len);
  126. /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
  127. buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
  128. buf = os_malloc(buflen);
  129. if (buf == NULL) {
  130. wpabuf_free(resp);
  131. return NULL;
  132. }
  133. os_memcpy(buf, data->id_p, data->id_p_len);
  134. pos = buf + data->id_p_len;
  135. os_memcpy(pos, data->id_s, data->id_s_len);
  136. pos += data->id_s_len;
  137. os_memcpy(pos, hdr1->rand_s, EAP_PSK_RAND_LEN);
  138. pos += EAP_PSK_RAND_LEN;
  139. os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
  140. if (omac1_aes_128(data->ak, buf, buflen, hdr2->mac_p)) {
  141. os_free(buf);
  142. wpabuf_free(resp);
  143. return NULL;
  144. }
  145. os_free(buf);
  146. wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_P", hdr2->rand_p,
  147. EAP_PSK_RAND_LEN);
  148. wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", hdr2->mac_p, EAP_PSK_MAC_LEN);
  149. wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_P",
  150. data->id_p, data->id_p_len);
  151. data->state = PSK_MAC_SENT;
  152. return resp;
  153. }
  154. static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data,
  155. struct eap_method_ret *ret,
  156. const struct wpabuf *reqData)
  157. {
  158. const struct eap_psk_hdr_3 *hdr3;
  159. struct eap_psk_hdr_4 *hdr4;
  160. struct wpabuf *resp;
  161. u8 *buf, *rpchannel, nonce[16], *decrypted;
  162. const u8 *pchannel, *tag, *msg;
  163. u8 mac[EAP_PSK_MAC_LEN];
  164. size_t buflen, left, data_len, len, plen;
  165. int failed = 0;
  166. const u8 *pos;
  167. wpa_printf(MSG_DEBUG, "EAP-PSK: in MAC_SENT state");
  168. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK,
  169. reqData, &len);
  170. hdr3 = (const struct eap_psk_hdr_3 *) pos;
  171. if (pos == NULL || len < sizeof(*hdr3)) {
  172. wpa_printf(MSG_INFO, "EAP-PSK: Invalid third message "
  173. "length (%lu; expected %lu or more)",
  174. (unsigned long) len,
  175. (unsigned long) sizeof(*hdr3));
  176. ret->ignore = TRUE;
  177. return NULL;
  178. }
  179. left = len - sizeof(*hdr3);
  180. pchannel = (const u8 *) (hdr3 + 1);
  181. wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr3->flags);
  182. if (EAP_PSK_FLAGS_GET_T(hdr3->flags) != 2) {
  183. wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 2)",
  184. EAP_PSK_FLAGS_GET_T(hdr3->flags));
  185. ret->methodState = METHOD_DONE;
  186. ret->decision = DECISION_FAIL;
  187. return NULL;
  188. }
  189. wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr3->rand_s,
  190. EAP_PSK_RAND_LEN);
  191. wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_S", hdr3->mac_s, EAP_PSK_MAC_LEN);
  192. wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL", pchannel, left);
  193. if (left < 4 + 16 + 1) {
  194. wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in "
  195. "third message (len=%lu, expected 21)",
  196. (unsigned long) left);
  197. ret->ignore = TRUE;
  198. return NULL;
  199. }
  200. /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
  201. buflen = data->id_s_len + EAP_PSK_RAND_LEN;
  202. buf = os_malloc(buflen);
  203. if (buf == NULL)
  204. return NULL;
  205. os_memcpy(buf, data->id_s, data->id_s_len);
  206. os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
  207. if (omac1_aes_128(data->ak, buf, buflen, mac)) {
  208. os_free(buf);
  209. return NULL;
  210. }
  211. os_free(buf);
  212. if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
  213. wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third "
  214. "message");
  215. ret->methodState = METHOD_DONE;
  216. ret->decision = DECISION_FAIL;
  217. return NULL;
  218. }
  219. wpa_printf(MSG_DEBUG, "EAP-PSK: MAC_S verified successfully");
  220. if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek,
  221. data->msk, data->emsk)) {
  222. ret->methodState = METHOD_DONE;
  223. ret->decision = DECISION_FAIL;
  224. return NULL;
  225. }
  226. wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN);
  227. wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN);
  228. wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
  229. os_memset(nonce, 0, 12);
  230. os_memcpy(nonce + 12, pchannel, 4);
  231. pchannel += 4;
  232. left -= 4;
  233. tag = pchannel;
  234. pchannel += 16;
  235. left -= 16;
  236. msg = pchannel;
  237. wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - nonce",
  238. nonce, sizeof(nonce));
  239. wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr",
  240. wpabuf_head(reqData), 5);
  241. wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - cipher msg", msg, left);
  242. decrypted = os_malloc(left);
  243. if (decrypted == NULL) {
  244. ret->methodState = METHOD_DONE;
  245. ret->decision = DECISION_FAIL;
  246. return NULL;
  247. }
  248. os_memcpy(decrypted, msg, left);
  249. if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
  250. wpabuf_head(reqData),
  251. sizeof(struct eap_hdr) + 1 +
  252. sizeof(*hdr3) - EAP_PSK_MAC_LEN, decrypted,
  253. left, tag)) {
  254. wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
  255. os_free(decrypted);
  256. return NULL;
  257. }
  258. wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message",
  259. decrypted, left);
  260. /* Verify R flag */
  261. switch (decrypted[0] >> 6) {
  262. case EAP_PSK_R_FLAG_CONT:
  263. wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported");
  264. failed = 1;
  265. break;
  266. case EAP_PSK_R_FLAG_DONE_SUCCESS:
  267. wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS");
  268. break;
  269. case EAP_PSK_R_FLAG_DONE_FAILURE:
  270. wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE");
  271. wpa_printf(MSG_INFO, "EAP-PSK: Authentication server rejected "
  272. "authentication");
  273. failed = 1;
  274. break;
  275. }
  276. data_len = 1;
  277. if ((decrypted[0] & EAP_PSK_E_FLAG) && left > 1)
  278. data_len++;
  279. plen = sizeof(*hdr4) + 4 + 16 + data_len;
  280. resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, plen,
  281. EAP_CODE_RESPONSE, eap_get_id(reqData));
  282. if (resp == NULL) {
  283. os_free(decrypted);
  284. return NULL;
  285. }
  286. hdr4 = wpabuf_put(resp, sizeof(*hdr4));
  287. hdr4->flags = EAP_PSK_FLAGS_SET_T(3); /* T=3 */
  288. os_memcpy(hdr4->rand_s, hdr3->rand_s, EAP_PSK_RAND_LEN);
  289. rpchannel = wpabuf_put(resp, 4 + 16 + data_len);
  290. /* nonce++ */
  291. inc_byte_array(nonce, sizeof(nonce));
  292. os_memcpy(rpchannel, nonce + 12, 4);
  293. if (decrypted[0] & EAP_PSK_E_FLAG) {
  294. wpa_printf(MSG_DEBUG, "EAP-PSK: Unsupported E (Ext) flag");
  295. failed = 1;
  296. rpchannel[4 + 16] = (EAP_PSK_R_FLAG_DONE_FAILURE << 6) |
  297. EAP_PSK_E_FLAG;
  298. if (left > 1) {
  299. /* Add empty EXT_Payload with same EXT_Type */
  300. rpchannel[4 + 16 + 1] = decrypted[1];
  301. }
  302. } else if (failed)
  303. rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_FAILURE << 6;
  304. else
  305. rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6;
  306. wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (plaintext)",
  307. rpchannel + 4 + 16, data_len);
  308. if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce),
  309. wpabuf_head(resp),
  310. sizeof(struct eap_hdr) + 1 + sizeof(*hdr4),
  311. rpchannel + 4 + 16, data_len, rpchannel + 4)) {
  312. os_free(decrypted);
  313. wpabuf_free(resp);
  314. return NULL;
  315. }
  316. wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (PCHANNEL)",
  317. rpchannel, 4 + 16 + data_len);
  318. wpa_printf(MSG_DEBUG, "EAP-PSK: Completed %ssuccessfully",
  319. failed ? "un" : "");
  320. data->state = PSK_DONE;
  321. ret->methodState = METHOD_DONE;
  322. ret->decision = failed ? DECISION_FAIL : DECISION_UNCOND_SUCC;
  323. os_free(decrypted);
  324. return resp;
  325. }
  326. static struct wpabuf * eap_psk_process(struct eap_sm *sm, void *priv,
  327. struct eap_method_ret *ret,
  328. const struct wpabuf *reqData)
  329. {
  330. struct eap_psk_data *data = priv;
  331. const u8 *pos;
  332. struct wpabuf *resp = NULL;
  333. size_t len;
  334. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
  335. if (pos == NULL) {
  336. ret->ignore = TRUE;
  337. return NULL;
  338. }
  339. ret->ignore = FALSE;
  340. ret->methodState = METHOD_MAY_CONT;
  341. ret->decision = DECISION_FAIL;
  342. ret->allowNotifications = TRUE;
  343. switch (data->state) {
  344. case PSK_INIT:
  345. resp = eap_psk_process_1(data, ret, reqData);
  346. break;
  347. case PSK_MAC_SENT:
  348. resp = eap_psk_process_3(data, ret, reqData);
  349. break;
  350. case PSK_DONE:
  351. wpa_printf(MSG_DEBUG, "EAP-PSK: in DONE state - ignore "
  352. "unexpected message");
  353. ret->ignore = TRUE;
  354. return NULL;
  355. }
  356. if (ret->methodState == METHOD_DONE) {
  357. ret->allowNotifications = FALSE;
  358. }
  359. return resp;
  360. }
  361. static Boolean eap_psk_isKeyAvailable(struct eap_sm *sm, void *priv)
  362. {
  363. struct eap_psk_data *data = priv;
  364. return data->state == PSK_DONE;
  365. }
  366. static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len)
  367. {
  368. struct eap_psk_data *data = priv;
  369. u8 *key;
  370. if (data->state != PSK_DONE)
  371. return NULL;
  372. key = os_malloc(EAP_MSK_LEN);
  373. if (key == NULL)
  374. return NULL;
  375. *len = EAP_MSK_LEN;
  376. os_memcpy(key, data->msk, EAP_MSK_LEN);
  377. return key;
  378. }
  379. static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
  380. {
  381. struct eap_psk_data *data = priv;
  382. u8 *key;
  383. if (data->state != PSK_DONE)
  384. return NULL;
  385. key = os_malloc(EAP_EMSK_LEN);
  386. if (key == NULL)
  387. return NULL;
  388. *len = EAP_EMSK_LEN;
  389. os_memcpy(key, data->emsk, EAP_EMSK_LEN);
  390. return key;
  391. }
  392. int eap_peer_psk_register(void)
  393. {
  394. struct eap_method *eap;
  395. int ret;
  396. eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
  397. EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK");
  398. if (eap == NULL)
  399. return -1;
  400. eap->init = eap_psk_init;
  401. eap->deinit = eap_psk_deinit;
  402. eap->process = eap_psk_process;
  403. eap->isKeyAvailable = eap_psk_isKeyAvailable;
  404. eap->getKey = eap_psk_getKey;
  405. eap->get_emsk = eap_psk_get_emsk;
  406. ret = eap_peer_method_register(eap);
  407. if (ret)
  408. eap_peer_method_free(eap);
  409. return ret;
  410. }