Import hostapd 0.5.8
[dragonfly.git] / contrib / hostapd-0.5.8 / eap_ttls.c
blob1c0f17e764b7623da29dcb275d11c70f23a64b78
1 /*
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
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
17 #include "hostapd.h"
18 #include "common.h"
19 #include "eap_i.h"
20 #include "eap_tls_common.h"
21 #include "ms_funcs.h"
22 #include "md5.h"
23 #include "sha1.h"
24 #include "crypto.h"
25 #include "tls.h"
26 #include "eap_ttls.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;
44 enum {
45 START, PHASE1, PHASE2_START, PHASE2_METHOD,
46 PHASE2_MSCHAPV2_RESP, PHASE_FINISHED, SUCCESS, FAILURE
47 } state;
49 int ttls_version;
50 int force_version;
51 const struct eap_method *phase2_method;
52 void *phase2_priv;
53 int mschapv2_resp_ok;
54 u8 mschapv2_auth_response[20];
55 u8 mschapv2_ident;
56 int tls_ia_configured;
60 static const char * eap_ttls_state_txt(int state)
62 switch (state) {
63 case START:
64 return "START";
65 case PHASE1:
66 return "PHASE1";
67 case PHASE2_START:
68 return "PHASE2_START";
69 case PHASE2_METHOD:
70 return "PHASE2_METHOD";
71 case PHASE2_MSCHAPV2_RESP:
72 return "PHASE2_MSCHAPV2_RESP";
73 case PHASE_FINISHED:
74 return "PHASE_FINISHED";
75 case SUCCESS:
76 return "SUCCESS";
77 case FAILURE:
78 return "FAILURE";
79 default:
80 return "Unknown?!";
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));
90 data->state = 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;
98 u8 flags;
99 size_t hdrlen;
101 avp = (struct ttls_avp_vendor *) avphdr;
102 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
103 if (vendor_id) {
104 flags |= AVP_FLAGS_VENDOR;
105 hdrlen = sizeof(*avp);
106 avp->vendor_id = host_to_be32(vendor_id);
107 } else {
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,
119 int mandatory)
121 u8 *avp, *pos;
123 avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
124 if (avp == NULL) {
125 free(*resp);
126 *resp_len = 0;
127 return -1;
130 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
131 memcpy(pos, *resp, *resp_len);
132 pos += *resp_len;
133 AVP_PAD(avp, pos);
134 free(*resp);
135 *resp = avp;
136 *resp_len = pos - avp;
137 return 0;
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. */
145 u8 *eap;
146 size_t eap_len;
147 u8 *user_name;
148 size_t user_name_len;
149 u8 *user_password;
150 size_t user_password_len;
151 u8 *chap_challenge;
152 size_t chap_challenge_len;
153 u8 *chap_password;
154 size_t chap_password_len;
155 u8 *mschap_challenge;
156 size_t mschap_challenge_len;
157 u8 *mschap_response;
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;
167 u8 *pos;
168 int left;
170 pos = buf;
171 left = len;
172 memset(parse, 0, sizeof(*parse));
174 while (left > 0) {
175 u32 avp_code, avp_length, vendor_id = 0;
176 u8 avp_flags, *dpos;
177 size_t pad, dlen;
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,
185 (int) avp_length);
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);
190 goto fail;
192 if (avp_length < sizeof(*avp)) {
193 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
194 "%d", avp_length);
195 goto fail;
197 dpos = (u8 *) (avp + 1);
198 dlen = avp_length - sizeof(*avp);
199 if (avp_flags & AVP_FLAGS_VENDOR) {
200 if (dlen < 4) {
201 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
202 "underflow");
203 goto fail;
205 vendor_id = be_to_host32(* (u32 *) dpos);
206 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
207 (int) vendor_id);
208 dpos += 4;
209 dlen -= 4;
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");
222 goto fail;
224 memcpy(parse->eap, dpos, dlen);
225 parse->eap_len = dlen;
226 } else {
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");
233 goto fail;
235 memcpy(neweap + parse->eap_len, dpos, dlen);
236 parse->eap = neweap;
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",
242 dpos, dlen);
243 parse->user_name = dpos;
244 parse->user_name_len = dlen;
245 } else if (vendor_id == 0 &&
246 avp_code == RADIUS_ATTR_USER_PASSWORD) {
247 u8 *password = dpos;
248 size_t password_len = dlen;
249 while (password_len > 0 &&
250 password[password_len - 1] == '\0') {
251 password_len--;
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)",
262 dpos, dlen);
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)",
269 dpos, dlen);
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",
276 dpos, dlen);
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)",
283 dpos, dlen);
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)",
290 dpos, dlen);
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);
297 goto fail;
298 } else {
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;
309 return 0;
311 fail:
312 free(parse->eap);
313 parse->eap = NULL;
314 return -1;
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;
322 u8 *challenge, *rnd;
324 if (data->ttls_version == 0) {
325 return eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
326 len);
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");
336 return NULL;
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");
344 free(rnd);
345 free(challenge);
346 return NULL;
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,
355 challenge, len)) {
356 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
357 "challenge");
358 free(rnd);
359 free(challenge);
360 return NULL;
363 free(rnd);
365 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
366 challenge, len);
368 return challenge;
372 static void * eap_ttls_init(struct eap_sm *sm)
374 struct eap_ttls_data *data;
376 data = wpa_zalloc(sizeof(*data));
377 if (data == NULL)
378 return NULL;
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;
387 data->state = START;
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);
396 return NULL;
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);
404 return NULL;
407 return data;
411 static void eap_ttls_reset(struct eap_sm *sm, void *priv)
413 struct eap_ttls_data *data = priv;
414 if (data == NULL)
415 return;
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);
419 free(data);
423 static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
424 int id, size_t *reqDataLen)
426 struct eap_hdr *req;
427 u8 *pos;
429 *reqDataLen = sizeof(*req) + 2;
430 req = malloc(*reqDataLen);
431 if (req == NULL) {
432 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
433 " request");
434 eap_ttls_state(data, FAILURE);
435 return NULL;
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);
447 return (u8 *) req;
451 static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
452 int id, size_t *reqDataLen)
454 int res;
455 u8 *req;
457 res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
458 data->ttls_version, id, &req,
459 reqDataLen);
461 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
462 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
463 "Phase2");
464 eap_ttls_state(data, PHASE2_START);
467 if (res == 1)
468 return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
469 data->ttls_version);
470 return req;
474 static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
475 int id, u8 *plain, size_t plain_len,
476 size_t *out_len)
478 int res;
479 u8 *pos;
480 struct eap_hdr *req;
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);
485 if (req == NULL)
486 return NULL;
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,
496 plain, plain_len,
497 pos, data->ssl.tls_out_limit);
498 if (res < 0) {
499 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
500 "data");
501 free(req);
502 return NULL;
505 *out_len = sizeof(struct eap_hdr) + 2 + res;
506 req->length = host_to_be16(*out_len);
507 return (u8 *) req;
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)
515 u8 *req, *encr_req;
516 size_t req_len;
519 req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
520 &req_len);
521 if (req == NULL)
522 return NULL;
524 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
525 req, req_len);
527 if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
528 1) < 0) {
529 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
530 "packet");
531 return NULL;
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);
538 free(req);
540 return encr_req;
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;
549 int ret;
550 size_t req_len;
552 pos = req = malloc(100);
553 if (req == NULL)
554 return NULL;
555 end = req + 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)
563 pos += ret;
564 pos += wpa_snprintf_hex_uppercase(
565 (char *) pos, end - pos, data->mschapv2_auth_response,
566 sizeof(data->mschapv2_auth_response));
567 } else {
568 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
569 RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
570 memcpy(pos, "Failed", 6);
571 pos += 6;
572 AVP_PAD(req, pos);
575 req_len = pos - req;
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);
580 free(req);
582 return encr_req;
586 static u8 * eap_ttls_build_phase_finished(struct eap_sm *sm,
587 struct eap_ttls_data *data,
588 int id, int final,
589 size_t *reqDataLen)
591 int len;
592 struct eap_hdr *req;
593 u8 *pos;
594 const int max_len = 300;
596 len = sizeof(struct eap_hdr) + 2 + max_len;
597 req = malloc(len);
598 if (req == NULL)
599 return NULL;
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,
609 data->ssl.conn,
610 final, pos, max_len);
611 if (len < 0) {
612 free(req);
613 return NULL;
616 *reqDataLen = sizeof(struct eap_hdr) + 2 + len;
617 req->length = host_to_be16(*reqDataLen);
619 return (u8 *) req;
623 static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
624 size_t *reqDataLen)
626 struct eap_ttls_data *data = priv;
628 switch (data->state) {
629 case START:
630 return eap_ttls_build_start(sm, data, id, reqDataLen);
631 case PHASE1:
632 return eap_ttls_build_req(sm, data, id, reqDataLen);
633 case PHASE2_METHOD:
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,
637 reqDataLen);
638 case PHASE_FINISHED:
639 return eap_ttls_build_phase_finished(sm, data, id, 1,
640 reqDataLen);
641 default:
642 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
643 __func__, data->state);
644 return NULL;
649 static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
650 u8 *respData, size_t respDataLen)
652 struct eap_hdr *resp;
653 u8 *pos;
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");
660 return TRUE;
663 return FALSE;
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)
671 u8 *buf;
672 size_t buf_len;
673 int ret;
675 if (key) {
676 buf_len = 2 + key_len;
677 buf = malloc(buf_len);
678 if (buf == NULL)
679 return -1;
680 WPA_PUT_BE16(buf, key_len);
681 memcpy(buf + 2, key, key_len);
682 } else {
683 buf = NULL;
684 buf_len = 0;
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,
690 data->ssl.conn,
691 buf, buf_len);
692 free(buf);
694 return ret;
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
704 * EAP-TTLS/PAP. */
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);
709 return;
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);
717 return;
720 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
721 eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
722 SUCCESS);
726 static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
727 struct eap_ttls_data *data,
728 const u8 *challenge,
729 size_t challenge_len,
730 const u8 *password,
731 size_t password_len)
733 u8 *chal, hash[MD5_MAC_LEN];
734 const u8 *addr[3];
735 size_t len[3];
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);
745 return;
748 /* TODO: add support for verifying that the user entry accepts
749 * EAP-TTLS/CHAP. */
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);
754 return;
757 chal = eap_ttls_implicit_challenge(sm, data,
758 EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
759 if (chal == NULL) {
760 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
761 "challenge from TLS data");
762 eap_ttls_state(data, FAILURE);
763 return;
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");
769 free(chal);
770 eap_ttls_state(data, FAILURE);
771 return;
773 free(chal);
775 /* MD5(Ident + Password + Challenge) */
776 addr[0] = password;
777 len[0] = 1;
778 addr[1] = sm->user->password;
779 len[1] = sm->user->password_len;
780 addr[2] = challenge;
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 :
787 SUCCESS);
788 } else {
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);
810 return;
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 "
817 "configured");
818 eap_ttls_state(data, FAILURE);
819 return;
822 chal = eap_ttls_implicit_challenge(sm, data,
823 EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
824 if (chal == NULL) {
825 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
826 "challenge from TLS data");
827 eap_ttls_state(data, FAILURE);
828 return;
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");
834 free(chal);
835 eap_ttls_state(data, FAILURE);
836 return;
838 free(chal);
840 if (sm->user->password_hash)
841 challenge_response(challenge, sm->user->password, nt_response);
842 else
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 :
849 SUCCESS);
850 } else {
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",
855 nt_response, 24);
856 eap_ttls_state(data, FAILURE);
861 static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
862 struct eap_ttls_data *data,
863 u8 *challenge,
864 size_t challenge_len,
865 u8 *response, size_t response_len)
867 u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
868 *auth_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);
879 return;
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 "
886 "configured");
887 eap_ttls_state(data, FAILURE);
888 return;
891 /* MSCHAPv2 does not include optional domain name in the
892 * challenge-response calculation, so remove domain prefix
893 * (if present). */
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;
899 username += i + 1;
900 break;
904 chal = eap_ttls_implicit_challenge(
905 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
906 if (chal == NULL) {
907 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
908 "challenge from TLS data");
909 eap_ttls_state(data, FAILURE);
910 return;
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");
916 free(chal);
917 eap_ttls_state(data, FAILURE);
918 return;
920 free(chal);
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,
935 sm->user->password,
936 nt_response);
937 } else {
938 generate_nt_response(auth_challenge, peer_challenge,
939 username, username_len,
940 sm->user->password,
941 sm->user->password_len,
942 nt_response);
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 "
948 "NT-Response");
949 data->mschapv2_resp_ok = 1;
950 if (data->ttls_version > 0) {
951 const u8 *pw_hash;
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;
957 else {
958 nt_password_hash(sm->user->password,
959 sm->user->password_len,
960 pw_hash_buf);
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,
971 session_key,
972 sizeof(session_key));
975 if (sm->user->password_hash) {
976 generate_authenticator_response_pwhash(
977 sm->user->password,
978 peer_challenge, auth_challenge,
979 username, username_len, nt_response,
980 data->mschapv2_auth_response);
981 } else {
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);
988 } else {
989 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
990 "NT-Response");
991 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
992 rx_resp, 24);
993 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
994 nt_response, 24);
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,
1004 EapType eap_type)
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,
1012 eap_type);
1013 if (!data->phase2_method)
1014 return -1;
1016 sm->init_phase2 = 1;
1017 data->phase2_priv = data->phase2_method->init(sm);
1018 sm->init_phase2 = 0;
1019 return 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;
1029 u8 *pos;
1030 size_t left;
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__);
1037 return;
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 !=
1050 EAP_TYPE_NONE) {
1051 next_type = sm->user->methods[
1052 sm->user_eap_method_index++].method;
1053 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
1054 next_type);
1055 eap_ttls_phase2_eap_init(sm, data, next_type);
1056 } else {
1057 eap_ttls_state(data, FAILURE);
1059 return;
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");
1065 return;
1068 m->process(sm, priv, in_data, in_len);
1070 if (!m->isDone(sm, priv))
1071 return;
1073 if (!m->isSuccess(sm, priv)) {
1074 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
1075 eap_ttls_state(data, FAILURE);
1076 return;
1079 switch (data->state) {
1080 case PHASE2_START:
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 "
1084 "database",
1085 sm->identity, sm->identity_len);
1086 eap_ttls_state(data, FAILURE);
1087 break;
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);
1094 break;
1095 case PHASE2_METHOD:
1096 if (data->ttls_version > 0) {
1097 if (m->getKey) {
1098 u8 *key;
1099 size_t key_len;
1100 key = m->getKey(sm, priv, &key_len);
1101 eap_ttls_ia_permute_inner_secret(sm, data,
1102 key, key_len);
1104 eap_ttls_state(data, PHASE_FINISHED);
1105 } else
1106 eap_ttls_state(data, SUCCESS);
1107 break;
1108 case FAILURE:
1109 break;
1110 default:
1111 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
1112 __func__, data->state);
1113 break;
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;
1125 size_t len;
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");
1133 return;
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);
1140 return;
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);
1152 return;
1155 switch (hdr->code) {
1156 case EAP_CODE_RESPONSE:
1157 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
1158 len);
1159 break;
1160 default:
1161 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
1162 "Phase 2 EAP header", hdr->code);
1163 break;
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)
1173 u8 *in_decrypted;
1174 int len_decrypted, res;
1175 struct eap_ttls_avp parse;
1176 size_t buf_len;
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)
1183 return;
1185 buf_len = in_len;
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 "
1194 "for decryption");
1195 return;
1198 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1199 in_data, in_len,
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 "
1206 "data");
1207 free(in_decrypted);
1208 eap_ttls_state(data, FAILURE);
1209 return;
1212 if (data->state == PHASE_FINISHED) {
1213 if (len_decrypted == 0 &&
1214 tls_connection_ia_final_phase_finished(sm->ssl_ctx,
1215 data->ssl.conn)) {
1216 wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished "
1217 "received");
1218 eap_ttls_state(data, SUCCESS);
1219 } else {
1220 wpa_printf(MSG_INFO, "EAP-TTLS: Did not receive valid "
1221 "FinalPhaseFinished");
1222 eap_ttls_state(data, FAILURE);
1225 free(in_decrypted);
1226 return;
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");
1234 free(in_decrypted);
1235 eap_ttls_state(data, FAILURE);
1236 return;
1239 if (parse.user_name) {
1240 free(sm->identity);
1241 sm->identity = malloc(parse.user_name_len);
1242 if (sm->identity) {
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)
1248 != 0) {
1249 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
1250 "found in the user database");
1251 eap_ttls_state(data, FAILURE);
1252 goto done;
1256 if (parse.eap) {
1257 eap_ttls_process_phase2_eap(sm, data, parse.eap,
1258 parse.eap_len);
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);
1282 done:
1283 free(in_decrypted);
1284 free(parse.eap);
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;
1293 u8 *pos, flags;
1294 int left;
1295 unsigned int tls_msg_len;
1296 int peer_version;
1298 resp = (struct eap_hdr *) respData;
1299 pos = (u8 *) (resp + 1);
1300 pos++;
1301 flags = *pos++;
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; "
1308 "use version %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 "
1316 "TLS/IA");
1317 eap_ttls_state(data, FAILURE);
1318 return;
1320 data->tls_ia_configured = 1;
1323 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1324 if (left < 4) {
1325 wpa_printf(MSG_INFO, "EAP-TTLS: Short frame with TLS "
1326 "length");
1327 eap_ttls_state(data, FAILURE);
1328 return;
1330 tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
1331 pos[3];
1332 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS Message Length: %d",
1333 tls_msg_len);
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;
1341 pos += 4;
1342 left -= 4;
1345 switch (data->state) {
1346 case PHASE1:
1347 if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
1348 wpa_printf(MSG_INFO, "EAP-TTLS: TLS processing "
1349 "failed");
1350 eap_ttls_state(data, FAILURE);
1352 break;
1353 case PHASE2_START:
1354 case PHASE2_METHOD:
1355 case PHASE_FINISHED:
1356 eap_ttls_process_phase2(sm, data, resp, pos, left);
1357 break;
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);
1368 } else {
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);
1374 break;
1375 default:
1376 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
1377 data->state, __func__);
1378 break;
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;
1400 u8 *rnd, *key;
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 "
1408 "material");
1409 return NULL;
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");
1416 free(rnd);
1417 free(key);
1418 return NULL;
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");
1428 free(rnd);
1429 free(key);
1430 return NULL;
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);
1438 free(rnd);
1440 return key;
1444 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
1446 struct eap_ttls_data *data = priv;
1447 u8 *eapKeyData;
1449 if (data->state != SUCCESS)
1450 return NULL;
1452 if (data->ttls_version == 0) {
1453 eapKeyData = eap_tls_derive_key(sm, &data->ssl,
1454 "ttls keying material",
1455 EAP_TLS_KEY_LEN);
1456 } else {
1457 eapKeyData = eap_ttls_v1_derive_key(sm, data);
1460 if (eapKeyData) {
1461 *len = EAP_TLS_KEY_LEN;
1462 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
1463 eapKeyData, EAP_TLS_KEY_LEN);
1464 } else {
1465 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
1468 return eapKeyData;
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;
1482 int ret;
1484 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1485 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
1486 if (eap == NULL)
1487 return -1;
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);
1499 if (ret)
1500 eap_server_method_free(eap);
1501 return ret;