2 * hostapd / EAP-TTLS (draft-ietf-pppext-eap-ttls-05.txt)
3 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 #include "eap_tls_common.h"
29 /* Maximum supported PEAP version
30 * 0 = draft-ietf-pppext-eap-ttls-03.txt / draft-funk-eap-ttls-v0-00.txt
31 * 1 = draft-funk-eap-ttls-v1-00.txt
33 #define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */
36 #define MSCHAPV2_KEY_LEN 16
39 static void eap_ttls_reset(struct eap_sm *sm, void *priv);
42 struct eap_ttls_data {
43 struct eap_ssl_data ssl;
45 START, PHASE1, PHASE2_START, PHASE2_METHOD,
46 PHASE2_MSCHAPV2_RESP, PHASE_FINISHED, SUCCESS, FAILURE
51 const struct eap_method *phase2_method;
54 u8 mschapv2_auth_response[20];
56 int tls_ia_configured;
60 static const char * eap_ttls_state_txt(int state)
68 return "PHASE2_START";
70 return "PHASE2_METHOD";
71 case PHASE2_MSCHAPV2_RESP:
72 return "PHASE2_MSCHAPV2_RESP";
74 return "PHASE_FINISHED";
85 static void eap_ttls_state(struct eap_ttls_data *data, int state)
87 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
88 eap_ttls_state_txt(data->state),
89 eap_ttls_state_txt(state));
94 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
95 int mandatory, size_t len)
97 struct ttls_avp_vendor *avp;
101 avp = (struct ttls_avp_vendor *) avphdr;
102 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
104 flags |= AVP_FLAGS_VENDOR;
105 hdrlen = sizeof(*avp);
106 avp->vendor_id = host_to_be32(vendor_id);
108 hdrlen = sizeof(struct ttls_avp);
111 avp->avp_code = host_to_be32(avp_code);
112 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
114 return avphdr + hdrlen;
118 static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
123 avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
130 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
131 memcpy(pos, *resp, *resp_len);
136 *resp_len = pos - avp;
141 struct eap_ttls_avp {
142 /* Note: eap is allocated memory; caller is responsible for freeing
143 * it. All the other pointers are pointing to the packet data, i.e.,
144 * they must not be freed separately. */
148 size_t user_name_len;
150 size_t user_password_len;
152 size_t chap_challenge_len;
154 size_t chap_password_len;
155 u8 *mschap_challenge;
156 size_t mschap_challenge_len;
158 size_t mschap_response_len;
159 u8 *mschap2_response;
160 size_t mschap2_response_len;
164 static int eap_ttls_avp_parse(u8 *buf, size_t len, struct eap_ttls_avp *parse)
166 struct ttls_avp *avp;
172 memset(parse, 0, sizeof(*parse));
175 u32 avp_code, avp_length, vendor_id = 0;
178 avp = (struct ttls_avp *) pos;
179 avp_code = be_to_host32(avp->avp_code);
180 avp_length = be_to_host32(avp->avp_length);
181 avp_flags = (avp_length >> 24) & 0xff;
182 avp_length &= 0xffffff;
183 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
184 "length=%d", (int) avp_code, avp_flags,
186 if ((int) avp_length > left) {
187 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
188 "(len=%d, left=%d) - dropped",
189 (int) avp_length, left);
192 if (avp_length < sizeof(*avp)) {
193 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
197 dpos = (u8 *) (avp + 1);
198 dlen = avp_length - sizeof(*avp);
199 if (avp_flags & AVP_FLAGS_VENDOR) {
201 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
205 vendor_id = be_to_host32(* (u32 *) dpos);
206 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
212 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
214 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
215 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
216 if (parse->eap == NULL) {
217 parse->eap = malloc(dlen);
218 if (parse->eap == NULL) {
219 wpa_printf(MSG_WARNING, "EAP-TTLS: "
220 "failed to allocate memory "
221 "for Phase 2 EAP data");
224 memcpy(parse->eap, dpos, dlen);
225 parse->eap_len = dlen;
227 u8 *neweap = realloc(parse->eap,
228 parse->eap_len + dlen);
229 if (neweap == NULL) {
230 wpa_printf(MSG_WARNING, "EAP-TTLS: "
231 "failed to allocate memory "
232 "for Phase 2 EAP data");
235 memcpy(neweap + parse->eap_len, dpos, dlen);
237 parse->eap_len += dlen;
239 } else if (vendor_id == 0 &&
240 avp_code == RADIUS_ATTR_USER_NAME) {
241 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
243 parse->user_name = dpos;
244 parse->user_name_len = dlen;
245 } else if (vendor_id == 0 &&
246 avp_code == RADIUS_ATTR_USER_PASSWORD) {
248 size_t password_len = dlen;
249 while (password_len > 0 &&
250 password[password_len - 1] == '\0') {
253 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
254 "User-Password (PAP)",
255 password, password_len);
256 parse->user_password = password;
257 parse->user_password_len = password_len;
258 } else if (vendor_id == 0 &&
259 avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
260 wpa_hexdump(MSG_DEBUG,
261 "EAP-TTLS: CHAP-Challenge (CHAP)",
263 parse->chap_challenge = dpos;
264 parse->chap_challenge_len = dlen;
265 } else if (vendor_id == 0 &&
266 avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
267 wpa_hexdump(MSG_DEBUG,
268 "EAP-TTLS: CHAP-Password (CHAP)",
270 parse->chap_password = dpos;
271 parse->chap_password_len = dlen;
272 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
273 avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
274 wpa_hexdump(MSG_DEBUG,
275 "EAP-TTLS: MS-CHAP-Challenge",
277 parse->mschap_challenge = dpos;
278 parse->mschap_challenge_len = dlen;
279 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
280 avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
281 wpa_hexdump(MSG_DEBUG,
282 "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
284 parse->mschap_response = dpos;
285 parse->mschap_response_len = dlen;
286 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
287 avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
288 wpa_hexdump(MSG_DEBUG,
289 "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
291 parse->mschap2_response = dpos;
292 parse->mschap2_response_len = dlen;
293 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
294 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
295 "mandatory AVP code %d vendor_id %d - "
296 "dropped", (int) avp_code, (int) vendor_id);
299 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
300 "AVP code %d vendor_id %d",
301 (int) avp_code, (int) vendor_id);
304 pad = (4 - (avp_length & 3)) & 3;
305 pos += avp_length + pad;
306 left -= avp_length + pad;
318 static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
319 struct eap_ttls_data *data, size_t len)
321 struct tls_keys keys;
324 if (data->ttls_version == 0) {
325 return eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
329 memset(&keys, 0, sizeof(keys));
330 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
331 keys.client_random == NULL || keys.server_random == NULL ||
332 keys.inner_secret == NULL) {
333 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
334 "client random, or server random to derive "
335 "implicit challenge");
339 rnd = malloc(keys.client_random_len + keys.server_random_len);
340 challenge = malloc(len);
341 if (rnd == NULL || challenge == NULL) {
342 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
343 "challenge derivation");
348 memcpy(rnd, keys.server_random, keys.server_random_len);
349 memcpy(rnd + keys.server_random_len, keys.client_random,
350 keys.client_random_len);
352 if (tls_prf(keys.inner_secret, keys.inner_secret_len,
353 "inner application challenge", rnd,
354 keys.client_random_len + keys.server_random_len,
356 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
365 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
372 static void * eap_ttls_init(struct eap_sm *sm)
374 struct eap_ttls_data *data;
376 data = wpa_zalloc(sizeof(*data));
379 data->ttls_version = EAP_TTLS_VERSION;
380 data->force_version = -1;
381 if (sm->user && sm->user->force_version >= 0) {
382 data->force_version = sm->user->force_version;
383 wpa_printf(MSG_DEBUG, "EAP-TTLS: forcing version %d",
384 data->force_version);
385 data->ttls_version = data->force_version;
389 if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) &&
390 data->ttls_version > 0) {
391 if (data->force_version > 0) {
392 wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and "
393 "TLS library does not support TLS/IA.",
394 data->force_version);
395 eap_ttls_reset(sm, data);
398 data->ttls_version = 0;
401 if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
402 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
403 eap_ttls_reset(sm, data);
411 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
413 struct eap_ttls_data *data = priv;
416 if (data->phase2_priv && data->phase2_method)
417 data->phase2_method->reset(sm, data->phase2_priv);
418 eap_tls_ssl_deinit(sm, &data->ssl);
423 static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
424 int id, size_t *reqDataLen)
429 *reqDataLen = sizeof(*req) + 2;
430 req = malloc(*reqDataLen);
432 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
434 eap_ttls_state(data, FAILURE);
438 req->code = EAP_CODE_REQUEST;
439 req->identifier = id;
440 req->length = htons(*reqDataLen);
441 pos = (u8 *) (req + 1);
442 *pos++ = EAP_TYPE_TTLS;
443 *pos = EAP_TLS_FLAGS_START | data->ttls_version;
445 eap_ttls_state(data, PHASE1);
451 static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
452 int id, size_t *reqDataLen)
457 res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
458 data->ttls_version, id, &req,
461 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
462 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
464 eap_ttls_state(data, PHASE2_START);
468 return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
474 static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
475 int id, u8 *plain, size_t plain_len,
482 /* TODO: add support for fragmentation, if needed. This will need to
483 * add TLS Message Length field, if the frame is fragmented. */
484 req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
488 req->code = EAP_CODE_REQUEST;
489 req->identifier = id;
491 pos = (u8 *) (req + 1);
492 *pos++ = EAP_TYPE_TTLS;
493 *pos++ = data->ttls_version;
495 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
497 pos, data->ssl.tls_out_limit);
499 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
505 *out_len = sizeof(struct eap_hdr) + 2 + res;
506 req->length = host_to_be16(*out_len);
511 static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,
512 struct eap_ttls_data *data,
513 int id, size_t *reqDataLen)
519 req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
524 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
527 if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
529 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
534 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "
535 "2 data", req, req_len);
537 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
544 static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,
545 struct eap_ttls_data *data,
546 int id, size_t *reqDataLen)
548 u8 *req, *encr_req, *pos, *end;
552 pos = req = malloc(100);
557 if (data->mschapv2_resp_ok) {
558 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
559 RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
560 *pos++ = data->mschapv2_ident;
561 ret = snprintf((char *) pos, end - pos, "S=");
562 if (ret >= 0 && ret < end - pos)
564 pos += wpa_snprintf_hex_uppercase(
565 (char *) pos, end - pos, data->mschapv2_auth_response,
566 sizeof(data->mschapv2_auth_response));
568 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
569 RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
570 memcpy(pos, "Failed", 6);
576 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
577 "data", req, req_len);
579 encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
586 static u8 * eap_ttls_build_phase_finished(struct eap_sm *sm,
587 struct eap_ttls_data *data,
594 const int max_len = 300;
596 len = sizeof(struct eap_hdr) + 2 + max_len;
601 req->code = EAP_CODE_REQUEST;
602 req->identifier = id;
604 pos = (u8 *) (req + 1);
605 *pos++ = EAP_TYPE_TTLS;
606 *pos++ = data->ttls_version;
608 len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
610 final, pos, max_len);
616 *reqDataLen = sizeof(struct eap_hdr) + 2 + len;
617 req->length = host_to_be16(*reqDataLen);
623 static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
626 struct eap_ttls_data *data = priv;
628 switch (data->state) {
630 return eap_ttls_build_start(sm, data, id, reqDataLen);
632 return eap_ttls_build_req(sm, data, id, reqDataLen);
634 return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);
635 case PHASE2_MSCHAPV2_RESP:
636 return eap_ttls_build_phase2_mschapv2(sm, data, id,
639 return eap_ttls_build_phase_finished(sm, data, id, 1,
642 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
643 __func__, data->state);
649 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
650 u8 *respData, size_t respDataLen)
652 struct eap_hdr *resp;
655 resp = (struct eap_hdr *) respData;
656 pos = (u8 *) (resp + 1);
657 if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_TTLS ||
658 (ntohs(resp->length)) > respDataLen) {
659 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
667 static int eap_ttls_ia_permute_inner_secret(struct eap_sm *sm,
668 struct eap_ttls_data *data,
669 const u8 *key, size_t key_len)
676 buf_len = 2 + key_len;
677 buf = malloc(buf_len);
680 WPA_PUT_BE16(buf, key_len);
681 memcpy(buf + 2, key, key_len);
687 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Session keys for TLS/IA inner "
688 "secret permutation", buf, buf_len);
689 ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
698 static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
699 struct eap_ttls_data *data,
700 const u8 *user_password,
701 size_t user_password_len)
703 /* TODO: add support for verifying that the user entry accepts
705 if (!sm->user || !sm->user->password || sm->user->password_hash) {
706 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
707 "password configured");
708 eap_ttls_state(data, FAILURE);
712 if (sm->user->password_len != user_password_len ||
713 memcmp(sm->user->password, user_password, user_password_len) != 0)
715 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
716 eap_ttls_state(data, FAILURE);
720 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
721 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
726 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
727 struct eap_ttls_data *data,
729 size_t challenge_len,
733 u8 *chal, hash[MD5_MAC_LEN];
737 if (challenge == NULL || password == NULL ||
738 challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
739 password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
740 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
741 "(challenge len %lu password len %lu)",
742 (unsigned long) challenge_len,
743 (unsigned long) password_len);
744 eap_ttls_state(data, FAILURE);
748 /* TODO: add support for verifying that the user entry accepts
750 if (!sm->user || !sm->user->password || sm->user->password_hash) {
751 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
752 "password configured");
753 eap_ttls_state(data, FAILURE);
757 chal = eap_ttls_implicit_challenge(sm, data,
758 EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
760 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
761 "challenge from TLS data");
762 eap_ttls_state(data, FAILURE);
766 if (memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
767 password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
768 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
770 eap_ttls_state(data, FAILURE);
775 /* MD5(Ident + Password + Challenge) */
778 addr[1] = sm->user->password;
779 len[1] = sm->user->password_len;
781 len[2] = challenge_len;
782 md5_vector(3, addr, len, hash);
784 if (memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
785 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
786 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
789 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
790 eap_ttls_state(data, FAILURE);
795 static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
796 struct eap_ttls_data *data,
797 u8 *challenge, size_t challenge_len,
798 u8 *response, size_t response_len)
800 u8 *chal, nt_response[24];
802 if (challenge == NULL || response == NULL ||
803 challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
804 response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
805 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
806 "attributes (challenge len %lu response len %lu)",
807 (unsigned long) challenge_len,
808 (unsigned long) response_len);
809 eap_ttls_state(data, FAILURE);
813 /* TODO: add support for verifying that the user entry accepts
814 * EAP-TTLS/MSCHAP. */
815 if (!sm->user || !sm->user->password) {
816 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
818 eap_ttls_state(data, FAILURE);
822 chal = eap_ttls_implicit_challenge(sm, data,
823 EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
825 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
826 "challenge from TLS data");
827 eap_ttls_state(data, FAILURE);
831 if (memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
832 response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
833 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
835 eap_ttls_state(data, FAILURE);
840 if (sm->user->password_hash)
841 challenge_response(challenge, sm->user->password, nt_response);
843 nt_challenge_response(challenge, sm->user->password,
844 sm->user->password_len, nt_response);
846 if (memcmp(nt_response, response + 2 + 24, 24) == 0) {
847 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
848 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
851 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
852 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
853 response + 2 + 24, 24);
854 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
856 eap_ttls_state(data, FAILURE);
861 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
862 struct eap_ttls_data *data,
864 size_t challenge_len,
865 u8 *response, size_t response_len)
867 u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
869 size_t username_len, i;
871 if (challenge == NULL || response == NULL ||
872 challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
873 response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
874 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
875 "attributes (challenge len %lu response len %lu)",
876 (unsigned long) challenge_len,
877 (unsigned long) response_len);
878 eap_ttls_state(data, FAILURE);
882 /* TODO: add support for verifying that the user entry accepts
883 * EAP-TTLS/MSCHAPV2. */
884 if (!sm->user || !sm->user->password) {
885 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
887 eap_ttls_state(data, FAILURE);
891 /* MSCHAPv2 does not include optional domain name in the
892 * challenge-response calculation, so remove domain prefix
894 username = sm->identity;
895 username_len = sm->identity_len;
896 for (i = 0; i < username_len; i++) {
897 if (username[i] == '\\') {
898 username_len -= i + 1;
904 chal = eap_ttls_implicit_challenge(
905 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
907 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
908 "challenge from TLS data");
909 eap_ttls_state(data, FAILURE);
913 if (memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
914 response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
915 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
917 eap_ttls_state(data, FAILURE);
922 auth_challenge = challenge;
923 peer_challenge = response + 2;
925 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
926 username, username_len);
927 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
928 auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
929 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
930 peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
932 if (sm->user->password_hash) {
933 generate_nt_response_pwhash(auth_challenge, peer_challenge,
934 username, username_len,
938 generate_nt_response(auth_challenge, peer_challenge,
939 username, username_len,
941 sm->user->password_len,
945 rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
946 if (memcmp(nt_response, rx_resp, 24) == 0) {
947 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
949 data->mschapv2_resp_ok = 1;
950 if (data->ttls_version > 0) {
952 u8 pw_hash_buf[16], pw_hash_hash[16], master_key[16];
953 u8 session_key[2 * MSCHAPV2_KEY_LEN];
955 if (sm->user->password_hash)
956 pw_hash = sm->user->password;
958 nt_password_hash(sm->user->password,
959 sm->user->password_len,
961 pw_hash = pw_hash_buf;
963 hash_nt_password_hash(pw_hash, pw_hash_hash);
964 get_master_key(pw_hash_hash, nt_response, master_key);
965 get_asymetric_start_key(master_key, session_key,
966 MSCHAPV2_KEY_LEN, 0, 0);
967 get_asymetric_start_key(master_key,
968 session_key + MSCHAPV2_KEY_LEN,
969 MSCHAPV2_KEY_LEN, 1, 0);
970 eap_ttls_ia_permute_inner_secret(sm, data,
972 sizeof(session_key));
975 if (sm->user->password_hash) {
976 generate_authenticator_response_pwhash(
978 peer_challenge, auth_challenge,
979 username, username_len, nt_response,
980 data->mschapv2_auth_response);
982 generate_authenticator_response(
983 sm->user->password, sm->user->password_len,
984 peer_challenge, auth_challenge,
985 username, username_len, nt_response,
986 data->mschapv2_auth_response);
989 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
991 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
993 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
995 data->mschapv2_resp_ok = 0;
997 eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
998 data->mschapv2_ident = response[0];
1002 static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
1003 struct eap_ttls_data *data,
1006 if (data->phase2_priv && data->phase2_method) {
1007 data->phase2_method->reset(sm, data->phase2_priv);
1008 data->phase2_method = NULL;
1009 data->phase2_priv = NULL;
1011 data->phase2_method = eap_sm_get_eap_methods(EAP_VENDOR_IETF,
1013 if (!data->phase2_method)
1016 sm->init_phase2 = 1;
1017 data->phase2_priv = data->phase2_method->init(sm);
1018 sm->init_phase2 = 0;
1023 static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
1024 struct eap_ttls_data *data,
1025 u8 *in_data, size_t in_len)
1027 u8 next_type = EAP_TYPE_NONE;
1028 struct eap_hdr *hdr;
1031 const struct eap_method *m = data->phase2_method;
1032 void *priv = data->phase2_priv;
1034 if (data->phase2_priv == NULL) {
1035 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
1036 "initialized?!", __func__);
1040 hdr = (struct eap_hdr *) in_data;
1041 pos = (u8 *) (hdr + 1);
1043 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
1044 left = in_len - sizeof(*hdr);
1045 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
1046 "allowed types", pos + 1, left - 1);
1047 eap_sm_process_nak(sm, pos + 1, left - 1);
1048 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
1049 sm->user->methods[sm->user_eap_method_index].method !=
1051 next_type = sm->user->methods[
1052 sm->user_eap_method_index++].method;
1053 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
1055 eap_ttls_phase2_eap_init(sm, data, next_type);
1057 eap_ttls_state(data, FAILURE);
1062 if (m->check(sm, priv, in_data, in_len)) {
1063 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
1064 "ignore the packet");
1068 m->process(sm, priv, in_data, in_len);
1070 if (!m->isDone(sm, priv))
1073 if (!m->isSuccess(sm, priv)) {
1074 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
1075 eap_ttls_state(data, FAILURE);
1079 switch (data->state) {
1081 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1082 wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
1083 "Identity not found in the user "
1085 sm->identity, sm->identity_len);
1086 eap_ttls_state(data, FAILURE);
1090 eap_ttls_state(data, PHASE2_METHOD);
1091 next_type = sm->user->methods[0].method;
1092 sm->user_eap_method_index = 1;
1093 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
1096 if (data->ttls_version > 0) {
1100 key = m->getKey(sm, priv, &key_len);
1101 eap_ttls_ia_permute_inner_secret(sm, data,
1104 eap_ttls_state(data, PHASE_FINISHED);
1106 eap_ttls_state(data, SUCCESS);
1111 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
1112 __func__, data->state);
1116 eap_ttls_phase2_eap_init(sm, data, next_type);
1120 static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
1121 struct eap_ttls_data *data,
1122 const u8 *eap, size_t eap_len)
1124 struct eap_hdr *hdr;
1127 if (data->state == PHASE2_START) {
1128 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
1129 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
1131 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
1132 "initialize EAP-Identity");
1137 if (eap_len < sizeof(*hdr)) {
1138 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
1139 "packet (len=%lu)", (unsigned long) eap_len);
1143 hdr = (struct eap_hdr *) eap;
1144 len = be_to_host16(hdr->length);
1145 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
1146 "identifier=%d length=%lu", hdr->code, hdr->identifier,
1147 (unsigned long) len);
1148 if (len > eap_len) {
1149 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
1150 " EAP frame (hdr len=%lu, data len in AVP=%lu)",
1151 (unsigned long) len, (unsigned long) eap_len);
1155 switch (hdr->code) {
1156 case EAP_CODE_RESPONSE:
1157 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
1161 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
1162 "Phase 2 EAP header", hdr->code);
1168 static void eap_ttls_process_phase2(struct eap_sm *sm,
1169 struct eap_ttls_data *data,
1170 struct eap_hdr *resp,
1171 u8 *in_data, size_t in_len)
1174 int len_decrypted, res;
1175 struct eap_ttls_avp parse;
1178 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
1179 " Phase 2", (unsigned long) in_len);
1181 res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
1182 if (res < 0 || res == 1)
1186 if (data->ssl.tls_in_total > buf_len)
1187 buf_len = data->ssl.tls_in_total;
1188 in_decrypted = malloc(buf_len);
1189 if (in_decrypted == NULL) {
1190 free(data->ssl.tls_in);
1191 data->ssl.tls_in = NULL;
1192 data->ssl.tls_in_len = 0;
1193 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
1198 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1200 in_decrypted, buf_len);
1201 free(data->ssl.tls_in);
1202 data->ssl.tls_in = NULL;
1203 data->ssl.tls_in_len = 0;
1204 if (len_decrypted < 0) {
1205 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
1208 eap_ttls_state(data, FAILURE);
1212 if (data->state == PHASE_FINISHED) {
1213 if (len_decrypted == 0 &&
1214 tls_connection_ia_final_phase_finished(sm->ssl_ctx,
1216 wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished "
1218 eap_ttls_state(data, SUCCESS);
1220 wpa_printf(MSG_INFO, "EAP-TTLS: Did not receive valid "
1221 "FinalPhaseFinished");
1222 eap_ttls_state(data, FAILURE);
1229 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
1230 in_decrypted, len_decrypted);
1232 if (eap_ttls_avp_parse(in_decrypted, len_decrypted, &parse) < 0) {
1233 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
1235 eap_ttls_state(data, FAILURE);
1239 if (parse.user_name) {
1241 sm->identity = malloc(parse.user_name_len);
1243 memcpy(sm->identity, parse.user_name,
1244 parse.user_name_len);
1245 sm->identity_len = parse.user_name_len;
1247 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
1249 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1250 "found in the user database");
1251 eap_ttls_state(data, FAILURE);
1257 eap_ttls_process_phase2_eap(sm, data, parse.eap,
1259 } else if (parse.user_password) {
1260 eap_ttls_process_phase2_pap(sm, data, parse.user_password,
1261 parse.user_password_len);
1262 } else if (parse.chap_password) {
1263 eap_ttls_process_phase2_chap(sm, data,
1264 parse.chap_challenge,
1265 parse.chap_challenge_len,
1266 parse.chap_password,
1267 parse.chap_password_len);
1268 } else if (parse.mschap_response) {
1269 eap_ttls_process_phase2_mschap(sm, data,
1270 parse.mschap_challenge,
1271 parse.mschap_challenge_len,
1272 parse.mschap_response,
1273 parse.mschap_response_len);
1274 } else if (parse.mschap2_response) {
1275 eap_ttls_process_phase2_mschapv2(sm, data,
1276 parse.mschap_challenge,
1277 parse.mschap_challenge_len,
1278 parse.mschap2_response,
1279 parse.mschap2_response_len);
1288 static void eap_ttls_process(struct eap_sm *sm, void *priv,
1289 u8 *respData, size_t respDataLen)
1291 struct eap_ttls_data *data = priv;
1292 struct eap_hdr *resp;
1295 unsigned int tls_msg_len;
1298 resp = (struct eap_hdr *) respData;
1299 pos = (u8 *) (resp + 1);
1302 left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
1303 wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
1304 "Flags 0x%02x", (unsigned long) respDataLen, flags);
1305 peer_version = flags & EAP_PEAP_VERSION_MASK;
1306 if (peer_version < data->ttls_version) {
1307 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
1309 peer_version, data->ttls_version, peer_version);
1310 data->ttls_version = peer_version;
1313 if (data->ttls_version > 0 && !data->tls_ia_configured) {
1314 if (tls_connection_set_ia(sm->ssl_ctx, data->ssl.conn, 1)) {
1315 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to enable "
1317 eap_ttls_state(data, FAILURE);
1320 data->tls_ia_configured = 1;
1323 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1325 wpa_printf(MSG_INFO, "EAP-TTLS: Short frame with TLS "
1327 eap_ttls_state(data, FAILURE);
1330 tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
1332 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS Message Length: %d",
1334 if (data->ssl.tls_in_left == 0) {
1335 data->ssl.tls_in_total = tls_msg_len;
1336 data->ssl.tls_in_left = tls_msg_len;
1337 free(data->ssl.tls_in);
1338 data->ssl.tls_in = NULL;
1339 data->ssl.tls_in_len = 0;
1345 switch (data->state) {
1347 if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
1348 wpa_printf(MSG_INFO, "EAP-TTLS: TLS processing "
1350 eap_ttls_state(data, FAILURE);
1355 case PHASE_FINISHED:
1356 eap_ttls_process_phase2(sm, data, resp, pos, left);
1358 case PHASE2_MSCHAPV2_RESP:
1359 if (data->mschapv2_resp_ok && left == 0) {
1360 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1361 "acknowledged response");
1362 eap_ttls_state(data, data->ttls_version > 0 ?
1363 PHASE_FINISHED : SUCCESS);
1364 } else if (!data->mschapv2_resp_ok) {
1365 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
1366 "acknowledged error");
1367 eap_ttls_state(data, FAILURE);
1369 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
1370 "frame from peer (payload len %d, expected "
1371 "empty frame)", left);
1372 eap_ttls_state(data, FAILURE);
1376 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1377 data->state, __func__);
1381 if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
1382 wpa_printf(MSG_INFO, "EAP-TTLS: Locally detected fatal error "
1383 "in TLS processing");
1384 eap_ttls_state(data, FAILURE);
1389 static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
1391 struct eap_ttls_data *data = priv;
1392 return data->state == SUCCESS || data->state == FAILURE;
1396 static u8 * eap_ttls_v1_derive_key(struct eap_sm *sm,
1397 struct eap_ttls_data *data)
1399 struct tls_keys keys;
1402 memset(&keys, 0, sizeof(keys));
1403 if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
1404 keys.client_random == NULL || keys.server_random == NULL ||
1405 keys.inner_secret == NULL) {
1406 wpa_printf(MSG_INFO, "EAP-TTLS: Could not get inner secret, "
1407 "client random, or server random to derive keying "
1412 rnd = malloc(keys.client_random_len + keys.server_random_len);
1413 key = malloc(EAP_TLS_KEY_LEN);
1414 if (rnd == NULL || key == NULL) {
1415 wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
1420 memcpy(rnd, keys.client_random, keys.client_random_len);
1421 memcpy(rnd + keys.client_random_len, keys.server_random,
1422 keys.server_random_len);
1424 if (tls_prf(keys.inner_secret, keys.inner_secret_len,
1425 "ttls v1 keying material", rnd, keys.client_random_len +
1426 keys.server_random_len, key, EAP_TLS_KEY_LEN)) {
1427 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1433 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: client/server random",
1434 rnd, keys.client_random_len + keys.server_random_len);
1435 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
1436 keys.inner_secret, keys.inner_secret_len);
1444 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1446 struct eap_ttls_data *data = priv;
1449 if (data->state != SUCCESS)
1452 if (data->ttls_version == 0) {
1453 eapKeyData = eap_tls_derive_key(sm, &data->ssl,
1454 "ttls keying material",
1457 eapKeyData = eap_ttls_v1_derive_key(sm, data);
1461 *len = EAP_TLS_KEY_LEN;
1462 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
1463 eapKeyData, EAP_TLS_KEY_LEN);
1465 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1472 static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
1474 struct eap_ttls_data *data = priv;
1475 return data->state == SUCCESS;
1479 int eap_server_ttls_register(void)
1481 struct eap_method *eap;
1484 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1485 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
1489 eap->init = eap_ttls_init;
1490 eap->reset = eap_ttls_reset;
1491 eap->buildReq = eap_ttls_buildReq;
1492 eap->check = eap_ttls_check;
1493 eap->process = eap_ttls_process;
1494 eap->isDone = eap_ttls_isDone;
1495 eap->getKey = eap_ttls_getKey;
1496 eap->isSuccess = eap_ttls_isSuccess;
1498 ret = eap_server_method_register(eap);
1500 eap_server_method_free(eap);