2 * EAP peer method: EAP-TTLS (draft-ietf-pppext-eap-ttls-03.txt)
3 * Copyright (c) 2004-2006, 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.
19 #include "eap_tls_common.h"
20 #include "config_ssid.h"
28 /* Maximum supported PEAP version
29 * 0 = draft-ietf-pppext-eap-ttls-03.txt / draft-funk-eap-ttls-v0-00.txt
30 * 1 = draft-funk-eap-ttls-v1-00.txt
32 #define EAP_TTLS_VERSION 0 /* TTLSv1 implementation is not yet complete */
35 #define MSCHAPV2_KEY_LEN 16
38 static void eap_ttls_deinit(struct eap_sm
*sm
, void *priv
);
41 struct eap_ttls_data
{
42 struct eap_ssl_data ssl
;
45 int ttls_version
, force_ttls_version
;
47 const struct eap_method
*phase2_method
;
54 EAP_TTLS_PHASE2_MSCHAPV2
,
55 EAP_TTLS_PHASE2_MSCHAP
,
59 struct eap_method_type phase2_eap_type
;
60 struct eap_method_type
*phase2_eap_types
;
61 size_t num_phase2_eap_types
;
64 int auth_response_valid
;
66 int resuming
; /* starting a resumed session */
67 int reauth
; /* reauthentication */
70 u8
*pending_phase2_req
;
71 size_t pending_phase2_req_len
;
75 static void * eap_ttls_init(struct eap_sm
*sm
)
77 struct eap_ttls_data
*data
;
78 struct wpa_ssid
*config
= eap_get_config(sm
);
81 data
= os_zalloc(sizeof(*data
));
84 data
->ttls_version
= EAP_TTLS_VERSION
;
85 data
->force_ttls_version
= -1;
87 data
->phase2_type
= EAP_TTLS_PHASE2_EAP
;
89 if (config
&& config
->phase1
) {
90 char *pos
= os_strstr(config
->phase1
, "ttlsver=");
92 data
->force_ttls_version
= atoi(pos
+ 8);
93 data
->ttls_version
= data
->force_ttls_version
;
94 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Forced TTLS version "
95 "%d", data
->force_ttls_version
);
99 if (config
&& config
->phase2
) {
100 if (os_strstr(config
->phase2
, "autheap=")) {
102 data
->phase2_type
= EAP_TTLS_PHASE2_EAP
;
103 } else if (os_strstr(config
->phase2
, "auth=MSCHAPV2")) {
104 selected
= "MSCHAPV2";
105 data
->phase2_type
= EAP_TTLS_PHASE2_MSCHAPV2
;
106 } else if (os_strstr(config
->phase2
, "auth=MSCHAP")) {
108 data
->phase2_type
= EAP_TTLS_PHASE2_MSCHAP
;
109 } else if (os_strstr(config
->phase2
, "auth=PAP")) {
111 data
->phase2_type
= EAP_TTLS_PHASE2_PAP
;
112 } else if (os_strstr(config
->phase2
, "auth=CHAP")) {
114 data
->phase2_type
= EAP_TTLS_PHASE2_CHAP
;
117 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase2 type: %s", selected
);
119 if (data
->phase2_type
== EAP_TTLS_PHASE2_EAP
) {
120 if (config
&& config
->phase2
) {
121 char *start
, *pos
, *buf
;
122 struct eap_method_type
*methods
= NULL
, *_methods
;
124 size_t num_methods
= 0;
125 start
= buf
= os_strdup(config
->phase2
);
127 eap_ttls_deinit(sm
, data
);
130 while (start
&& *start
!= '\0') {
132 pos
= os_strstr(start
, "autheap=");
135 if (start
!= pos
&& *(pos
- 1) != ' ') {
141 pos
= os_strchr(start
, ' ');
144 method
= eap_get_phase2_type(start
, &vendor
);
145 if (vendor
== EAP_VENDOR_IETF
&&
146 method
== EAP_TYPE_NONE
) {
147 wpa_printf(MSG_ERROR
, "EAP-TTLS: "
148 "Unsupported Phase2 EAP "
149 "method '%s'", start
);
152 _methods
= os_realloc(
153 methods
, num_methods
*
155 if (_methods
== NULL
) {
158 eap_ttls_deinit(sm
, data
);
162 methods
[num_methods
- 1].vendor
=
164 methods
[num_methods
- 1].method
=
171 data
->phase2_eap_types
= methods
;
172 data
->num_phase2_eap_types
= num_methods
;
174 if (data
->phase2_eap_types
== NULL
) {
175 data
->phase2_eap_types
= eap_get_phase2_types(
176 config
, &data
->num_phase2_eap_types
);
178 if (data
->phase2_eap_types
== NULL
) {
179 wpa_printf(MSG_ERROR
, "EAP-TTLS: No Phase2 EAP method "
181 eap_ttls_deinit(sm
, data
);
184 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: Phase2 EAP types",
185 (u8
*) data
->phase2_eap_types
,
186 data
->num_phase2_eap_types
*
187 sizeof(struct eap_method_type
));
188 data
->phase2_eap_type
.vendor
= EAP_VENDOR_IETF
;
189 data
->phase2_eap_type
.method
= EAP_TYPE_NONE
;
192 if (!(tls_capabilities(sm
->ssl_ctx
) & TLS_CAPABILITY_IA
) &&
193 data
->ttls_version
> 0) {
194 if (data
->force_ttls_version
> 0) {
195 wpa_printf(MSG_INFO
, "EAP-TTLS: Forced TTLSv%d and "
196 "TLS library does not support TLS/IA.",
197 data
->force_ttls_version
);
198 eap_ttls_deinit(sm
, data
);
201 data
->ttls_version
= 0;
208 static void eap_ttls_deinit(struct eap_sm
*sm
, void *priv
)
210 struct eap_ttls_data
*data
= priv
;
213 if (data
->phase2_priv
&& data
->phase2_method
)
214 data
->phase2_method
->deinit(sm
, data
->phase2_priv
);
215 os_free(data
->phase2_eap_types
);
216 if (data
->ssl_initialized
)
217 eap_tls_ssl_deinit(sm
, &data
->ssl
);
218 os_free(data
->key_data
);
219 os_free(data
->pending_phase2_req
);
224 static int eap_ttls_encrypt(struct eap_sm
*sm
, struct eap_ttls_data
*data
,
225 int id
, const u8
*plain
, size_t plain_len
,
226 u8
**out_data
, size_t *out_len
)
230 struct eap_hdr
*resp
;
232 /* TODO: add support for fragmentation, if needed. This will need to
233 * add TLS Message Length field, if the frame is fragmented. */
234 resp
= os_malloc(sizeof(struct eap_hdr
) + 2 + data
->ssl
.tls_out_limit
);
238 resp
->code
= EAP_CODE_RESPONSE
;
239 resp
->identifier
= id
;
241 pos
= (u8
*) (resp
+ 1);
242 *pos
++ = EAP_TYPE_TTLS
;
243 *pos
++ = data
->ttls_version
;
245 res
= tls_connection_encrypt(sm
->ssl_ctx
, data
->ssl
.conn
,
247 pos
, data
->ssl
.tls_out_limit
);
249 wpa_printf(MSG_INFO
, "EAP-TTLS: Failed to encrypt Phase 2 "
255 *out_len
= sizeof(struct eap_hdr
) + 2 + res
;
256 resp
->length
= host_to_be16(*out_len
);
257 *out_data
= (u8
*) resp
;
262 static u8
* eap_ttls_avp_hdr(u8
*avphdr
, u32 avp_code
, u32 vendor_id
,
263 int mandatory
, size_t len
)
265 struct ttls_avp_vendor
*avp
;
269 avp
= (struct ttls_avp_vendor
*) avphdr
;
270 flags
= mandatory
? AVP_FLAGS_MANDATORY
: 0;
272 flags
|= AVP_FLAGS_VENDOR
;
273 hdrlen
= sizeof(*avp
);
274 avp
->vendor_id
= host_to_be32(vendor_id
);
276 hdrlen
= sizeof(struct ttls_avp
);
279 avp
->avp_code
= host_to_be32(avp_code
);
280 avp
->avp_length
= host_to_be32((flags
<< 24) | (hdrlen
+ len
));
282 return avphdr
+ hdrlen
;
286 static u8
* eap_ttls_avp_add(u8
*start
, u8
*avphdr
, u32 avp_code
,
287 u32 vendor_id
, int mandatory
,
288 u8
*data
, size_t len
)
291 pos
= eap_ttls_avp_hdr(avphdr
, avp_code
, vendor_id
, mandatory
, len
);
292 os_memcpy(pos
, data
, len
);
299 static int eap_ttls_avp_encapsulate(u8
**resp
, size_t *resp_len
, u32 avp_code
,
304 avp
= os_malloc(sizeof(struct ttls_avp
) + *resp_len
+ 4);
312 pos
= eap_ttls_avp_hdr(avp
, avp_code
, 0, mandatory
, *resp_len
);
313 os_memcpy(pos
, *resp
, *resp_len
);
318 *resp_len
= pos
- avp
;
323 static int eap_ttls_ia_permute_inner_secret(struct eap_sm
*sm
,
324 struct eap_ttls_data
*data
,
325 const u8
*key
, size_t key_len
)
332 buf_len
= 2 + key_len
;
333 buf
= os_malloc(buf_len
);
336 WPA_PUT_BE16(buf
, key_len
);
337 os_memcpy(buf
+ 2, key
, key_len
);
343 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: Session keys for TLS/IA inner "
344 "secret permutation", buf
, buf_len
);
345 ret
= tls_connection_ia_permute_inner_secret(sm
->ssl_ctx
,
354 static int eap_ttls_v0_derive_key(struct eap_sm
*sm
,
355 struct eap_ttls_data
*data
)
357 os_free(data
->key_data
);
358 data
->key_data
= eap_tls_derive_key(sm
, &data
->ssl
,
359 "ttls keying material",
361 if (!data
->key_data
) {
362 wpa_printf(MSG_INFO
, "EAP-TTLS: Failed to derive key");
366 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: Derived key",
367 data
->key_data
, EAP_TLS_KEY_LEN
);
373 static int eap_ttls_v1_derive_key(struct eap_sm
*sm
,
374 struct eap_ttls_data
*data
)
376 struct tls_keys keys
;
379 os_free(data
->key_data
);
380 data
->key_data
= NULL
;
382 os_memset(&keys
, 0, sizeof(keys
));
383 if (tls_connection_get_keys(sm
->ssl_ctx
, data
->ssl
.conn
, &keys
) ||
384 keys
.client_random
== NULL
|| keys
.server_random
== NULL
||
385 keys
.inner_secret
== NULL
) {
386 wpa_printf(MSG_INFO
, "EAP-TTLS: Could not get inner secret, "
387 "client random, or server random to derive keying "
392 rnd
= os_malloc(keys
.client_random_len
+ keys
.server_random_len
);
393 data
->key_data
= os_malloc(EAP_TLS_KEY_LEN
);
394 if (rnd
== NULL
|| data
->key_data
== NULL
) {
395 wpa_printf(MSG_INFO
, "EAP-TTLS: No memory for key derivation");
397 os_free(data
->key_data
);
398 data
->key_data
= NULL
;
401 os_memcpy(rnd
, keys
.client_random
, keys
.client_random_len
);
402 os_memcpy(rnd
+ keys
.client_random_len
, keys
.server_random
,
403 keys
.server_random_len
);
405 if (tls_prf(keys
.inner_secret
, keys
.inner_secret_len
,
406 "ttls v1 keying material", rnd
, keys
.client_random_len
+
407 keys
.server_random_len
, data
->key_data
, EAP_TLS_KEY_LEN
)) {
408 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Failed to derive key");
410 os_free(data
->key_data
);
411 data
->key_data
= NULL
;
415 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: client/server random",
416 rnd
, keys
.client_random_len
+ keys
.server_random_len
);
417 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: TLS/IA inner secret",
418 keys
.inner_secret
, keys
.inner_secret_len
);
422 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: Derived key",
423 data
->key_data
, EAP_TLS_KEY_LEN
);
429 static u8
* eap_ttls_implicit_challenge(struct eap_sm
*sm
,
430 struct eap_ttls_data
*data
, size_t len
)
432 struct tls_keys keys
;
435 if (data
->ttls_version
== 0) {
436 return eap_tls_derive_key(sm
, &data
->ssl
, "ttls challenge",
440 os_memset(&keys
, 0, sizeof(keys
));
441 if (tls_connection_get_keys(sm
->ssl_ctx
, data
->ssl
.conn
, &keys
) ||
442 keys
.client_random
== NULL
|| keys
.server_random
== NULL
||
443 keys
.inner_secret
== NULL
) {
444 wpa_printf(MSG_INFO
, "EAP-TTLS: Could not get inner secret, "
445 "client random, or server random to derive "
446 "implicit challenge");
450 rnd
= os_malloc(keys
.client_random_len
+ keys
.server_random_len
);
451 challenge
= os_malloc(len
);
452 if (rnd
== NULL
|| challenge
== NULL
) {
453 wpa_printf(MSG_INFO
, "EAP-TTLS: No memory for implicit "
454 "challenge derivation");
459 os_memcpy(rnd
, keys
.server_random
, keys
.server_random_len
);
460 os_memcpy(rnd
+ keys
.server_random_len
, keys
.client_random
,
461 keys
.client_random_len
);
463 if (tls_prf(keys
.inner_secret
, keys
.inner_secret_len
,
464 "inner application challenge", rnd
,
465 keys
.client_random_len
+ keys
.server_random_len
,
467 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Failed to derive implicit "
476 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: Derived implicit challenge",
483 static int eap_ttls_phase2_nak(struct eap_ttls_data
*data
, struct eap_hdr
*hdr
,
484 u8
**resp
, size_t *resp_len
)
486 struct eap_hdr
*resp_hdr
;
487 u8
*pos
= (u8
*) (hdr
+ 1);
490 /* TODO: add support for expanded Nak */
491 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 Request: Nak type=%d", *pos
);
492 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: Allowed Phase2 EAP types",
493 (u8
*) data
->phase2_eap_types
, data
->num_phase2_eap_types
*
494 sizeof(struct eap_method_type
));
495 *resp_len
= sizeof(struct eap_hdr
) + 1;
496 *resp
= os_malloc(*resp_len
+ data
->num_phase2_eap_types
);
500 resp_hdr
= (struct eap_hdr
*) (*resp
);
501 resp_hdr
->code
= EAP_CODE_RESPONSE
;
502 resp_hdr
->identifier
= hdr
->identifier
;
503 pos
= (u8
*) (resp_hdr
+ 1);
504 *pos
++ = EAP_TYPE_NAK
;
505 for (i
= 0; i
< data
->num_phase2_eap_types
; i
++) {
506 if (data
->phase2_eap_types
[i
].vendor
== EAP_VENDOR_IETF
&&
507 data
->phase2_eap_types
[i
].method
< 256) {
509 *pos
++ = data
->phase2_eap_types
[i
].method
;
512 resp_hdr
->length
= host_to_be16(*resp_len
);
518 static int eap_ttls_phase2_request_eap(struct eap_sm
*sm
,
519 struct eap_ttls_data
*data
,
520 struct eap_method_ret
*ret
,
522 u8
**resp
, size_t *resp_len
)
524 size_t len
= be_to_host16(hdr
->length
);
526 struct eap_method_ret iret
;
527 struct wpa_ssid
*config
= eap_get_config(sm
);
529 if (len
<= sizeof(struct eap_hdr
)) {
530 wpa_printf(MSG_INFO
, "EAP-TTLS: too short "
531 "Phase 2 request (len=%lu)", (unsigned long) len
);
534 pos
= (u8
*) (hdr
+ 1);
535 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos
);
537 case EAP_TYPE_IDENTITY
:
538 *resp
= eap_sm_buildIdentity(sm
, hdr
->identifier
, resp_len
, 1);
541 if (data
->phase2_eap_type
.vendor
== EAP_VENDOR_IETF
&&
542 data
->phase2_eap_type
.method
== EAP_TYPE_NONE
) {
544 for (i
= 0; i
< data
->num_phase2_eap_types
; i
++) {
545 if (data
->phase2_eap_types
[i
].vendor
!=
547 data
->phase2_eap_types
[i
].method
!= *pos
)
550 data
->phase2_eap_type
.vendor
=
551 data
->phase2_eap_types
[i
].vendor
;
552 data
->phase2_eap_type
.method
=
553 data
->phase2_eap_types
[i
].method
;
554 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Selected "
555 "Phase 2 EAP vendor %d method %d",
556 data
->phase2_eap_type
.vendor
,
557 data
->phase2_eap_type
.method
);
561 if (*pos
!= data
->phase2_eap_type
.method
||
562 *pos
== EAP_TYPE_NONE
) {
563 if (eap_ttls_phase2_nak(data
, hdr
, resp
, resp_len
))
568 if (data
->phase2_priv
== NULL
) {
569 data
->phase2_method
= eap_sm_get_eap_methods(
570 EAP_VENDOR_IETF
, *pos
);
571 if (data
->phase2_method
) {
573 sm
->mschapv2_full_key
= 1;
575 data
->phase2_method
->init(sm
);
577 sm
->mschapv2_full_key
= 0;
580 if (data
->phase2_priv
== NULL
|| data
->phase2_method
== NULL
) {
581 wpa_printf(MSG_INFO
, "EAP-TTLS: failed to initialize "
582 "Phase 2 EAP method %d", *pos
);
585 os_memset(&iret
, 0, sizeof(iret
));
586 *resp
= data
->phase2_method
->process(sm
, data
->phase2_priv
,
587 &iret
, (u8
*) hdr
, len
,
589 if ((iret
.methodState
== METHOD_DONE
||
590 iret
.methodState
== METHOD_MAY_CONT
) &&
591 (iret
.decision
== DECISION_UNCOND_SUCC
||
592 iret
.decision
== DECISION_COND_SUCC
||
593 iret
.decision
== DECISION_FAIL
)) {
594 ret
->methodState
= iret
.methodState
;
595 ret
->decision
= iret
.decision
;
597 if (data
->ttls_version
> 0) {
598 const struct eap_method
*m
= data
->phase2_method
;
599 void *priv
= data
->phase2_priv
;
601 /* TTLSv1 requires TLS/IA FinalPhaseFinished */
602 if (ret
->decision
== DECISION_UNCOND_SUCC
)
603 ret
->decision
= DECISION_COND_SUCC
;
604 ret
->methodState
= METHOD_CONT
;
606 if (ret
->decision
== DECISION_COND_SUCC
&&
607 m
->isKeyAvailable
&& m
->getKey
&&
608 m
->isKeyAvailable(sm
, priv
)) {
611 key
= m
->getKey(sm
, priv
, &key_len
);
613 eap_ttls_ia_permute_inner_secret(
614 sm
, data
, key
, key_len
);
623 (config
->pending_req_identity
|| config
->pending_req_password
||
624 config
->pending_req_otp
)) {
631 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: AVP encapsulate EAP Response",
633 return eap_ttls_avp_encapsulate(resp
, resp_len
,
634 RADIUS_ATTR_EAP_MESSAGE
, 1);
638 static int eap_ttls_phase2_request_mschapv2(struct eap_sm
*sm
,
639 struct eap_ttls_data
*data
,
640 struct eap_method_ret
*ret
,
641 u8
**resp
, size_t *resp_len
)
643 struct wpa_ssid
*config
= eap_get_config(sm
);
644 u8
*buf
, *pos
, *challenge
, *username
, *peer_challenge
;
645 size_t username_len
, i
;
647 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
649 /* MSCHAPv2 does not include optional domain name in the
650 * challenge-response calculation, so remove domain prefix
652 username
= config
->identity
;
653 username_len
= config
->identity_len
;
655 for (i
= 0; i
< username_len
; i
++) {
656 if (username
[i
] == '\\') {
657 username_len
-= i
+ 1;
663 pos
= buf
= os_malloc(config
->identity_len
+ 1000);
665 wpa_printf(MSG_ERROR
,
666 "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
671 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_USER_NAME
, 0, 1,
672 config
->identity
, config
->identity_len
);
674 /* MS-CHAP-Challenge */
675 challenge
= eap_ttls_implicit_challenge(
676 sm
, data
, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
* 2 + 1);
677 if (challenge
== NULL
) {
679 wpa_printf(MSG_ERROR
, "EAP-TTLS/MSCHAPV2: Failed to derive "
680 "implicit challenge");
683 peer_challenge
= challenge
+ 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
;
685 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_MS_CHAP_CHALLENGE
,
686 RADIUS_VENDOR_ID_MICROSOFT
, 1,
687 challenge
, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
);
689 /* MS-CHAP2-Response */
690 pos
= eap_ttls_avp_hdr(pos
, RADIUS_ATTR_MS_CHAP2_RESPONSE
,
691 RADIUS_VENDOR_ID_MICROSOFT
, 1,
692 EAP_TTLS_MSCHAPV2_RESPONSE_LEN
);
693 data
->ident
= challenge
[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
];
694 *pos
++ = data
->ident
;
695 *pos
++ = 0; /* Flags */
696 os_memcpy(pos
, peer_challenge
, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
);
697 pos
+= EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
;
698 os_memset(pos
, 0, 8); /* Reserved, must be zero */
700 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: MSCHAPV2: implicit auth_challenge",
701 challenge
, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
);
702 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: MSCHAPV2: peer_challenge",
703 peer_challenge
, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN
);
704 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-TTLS: MSCHAPV2 username",
705 username
, username_len
);
706 wpa_hexdump_ascii_key(MSG_DEBUG
, "EAP-TTLS: MSCHAPV2 password",
707 config
->password
, config
->password_len
);
708 generate_nt_response(challenge
, peer_challenge
,
709 username
, username_len
,
710 config
->password
, config
->password_len
,
712 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: MSCHAPV2 response", pos
, 24);
713 generate_authenticator_response(config
->password
, config
->password_len
,
714 peer_challenge
, challenge
,
715 username
, username_len
,
716 pos
, data
->auth_response
);
717 data
->auth_response_valid
= 1;
719 if (data
->ttls_version
> 0) {
720 u8 pw_hash
[16], pw_hash_hash
[16], master_key
[16];
721 u8 session_key
[2 * MSCHAPV2_KEY_LEN
];
722 nt_password_hash(config
->password
, config
->password_len
,
724 hash_nt_password_hash(pw_hash
, pw_hash_hash
);
725 get_master_key(pw_hash_hash
, pos
/* nt_response */,
727 get_asymetric_start_key(master_key
, session_key
,
728 MSCHAPV2_KEY_LEN
, 0, 0);
729 get_asymetric_start_key(master_key
,
730 session_key
+ MSCHAPV2_KEY_LEN
,
731 MSCHAPV2_KEY_LEN
, 1, 0);
732 eap_ttls_ia_permute_inner_secret(sm
, data
,
734 sizeof(session_key
));
742 *resp_len
= pos
- buf
;
744 if (sm
->workaround
&& data
->ttls_version
== 0) {
745 /* At least FreeRADIUS seems to be terminating
746 * EAP-TTLS/MSHCAPV2 without the expected MS-CHAP-v2 Success
748 wpa_printf(MSG_DEBUG
, "EAP-TTLS/MSCHAPV2: EAP workaround - "
749 "allow success without tunneled response");
750 ret
->methodState
= METHOD_MAY_CONT
;
751 ret
->decision
= DECISION_COND_SUCC
;
758 static int eap_ttls_phase2_request_mschap(struct eap_sm
*sm
,
759 struct eap_ttls_data
*data
,
760 struct eap_method_ret
*ret
,
761 u8
**resp
, size_t *resp_len
)
763 struct wpa_ssid
*config
= eap_get_config(sm
);
764 u8
*buf
, *pos
, *challenge
;
766 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 MSCHAP Request");
768 pos
= buf
= os_malloc(config
->identity_len
+ 1000);
770 wpa_printf(MSG_ERROR
,
771 "EAP-TTLS/MSCHAP: Failed to allocate memory");
776 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_USER_NAME
, 0, 1,
777 config
->identity
, config
->identity_len
);
779 /* MS-CHAP-Challenge */
780 challenge
= eap_ttls_implicit_challenge(sm
, data
, EAP_TLS_KEY_LEN
);
781 if (challenge
== NULL
) {
783 wpa_printf(MSG_ERROR
, "EAP-TTLS/MSCHAP: Failed to derive "
784 "implicit challenge");
788 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_MS_CHAP_CHALLENGE
,
789 RADIUS_VENDOR_ID_MICROSOFT
, 1,
790 challenge
, EAP_TTLS_MSCHAP_CHALLENGE_LEN
);
792 /* MS-CHAP-Response */
793 pos
= eap_ttls_avp_hdr(pos
, RADIUS_ATTR_MS_CHAP_RESPONSE
,
794 RADIUS_VENDOR_ID_MICROSOFT
, 1,
795 EAP_TTLS_MSCHAP_RESPONSE_LEN
);
796 data
->ident
= challenge
[EAP_TTLS_MSCHAP_CHALLENGE_LEN
];
797 *pos
++ = data
->ident
;
798 *pos
++ = 1; /* Flags: Use NT style passwords */
799 os_memset(pos
, 0, 24); /* LM-Response */
801 nt_challenge_response(challenge
,
802 config
->password
, config
->password_len
,
803 pos
); /* NT-Response */
804 wpa_hexdump_ascii_key(MSG_DEBUG
, "EAP-TTLS: MSCHAP password",
805 config
->password
, config
->password_len
);
806 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: MSCHAP implicit challenge",
807 challenge
, EAP_TTLS_MSCHAP_CHALLENGE_LEN
);
808 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: MSCHAP response", pos
, 24);
814 *resp_len
= pos
- buf
;
816 if (data
->ttls_version
> 0) {
817 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
818 * so do not allow connection to be terminated yet. */
819 ret
->methodState
= METHOD_CONT
;
820 ret
->decision
= DECISION_COND_SUCC
;
822 /* EAP-TTLS/MSCHAP does not provide tunneled success
823 * notification, so assume that Phase2 succeeds. */
824 ret
->methodState
= METHOD_DONE
;
825 ret
->decision
= DECISION_COND_SUCC
;
832 static int eap_ttls_phase2_request_pap(struct eap_sm
*sm
,
833 struct eap_ttls_data
*data
,
834 struct eap_method_ret
*ret
,
835 u8
**resp
, size_t *resp_len
)
837 struct wpa_ssid
*config
= eap_get_config(sm
);
841 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 PAP Request");
843 pos
= buf
= os_malloc(config
->identity_len
+ config
->password_len
+
846 wpa_printf(MSG_ERROR
,
847 "EAP-TTLS/PAP: Failed to allocate memory");
852 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_USER_NAME
, 0, 1,
853 config
->identity
, config
->identity_len
);
855 /* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
856 * the data, so no separate encryption is used in the AVP itself.
857 * However, the password is padded to obfuscate its length. */
858 pad
= (16 - (config
->password_len
& 15)) & 15;
859 pos
= eap_ttls_avp_hdr(pos
, RADIUS_ATTR_USER_PASSWORD
, 0, 1,
860 config
->password_len
+ pad
);
861 os_memcpy(pos
, config
->password
, config
->password_len
);
862 pos
+= config
->password_len
;
863 os_memset(pos
, 0, pad
);
868 *resp_len
= pos
- buf
;
870 if (data
->ttls_version
> 0) {
871 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
872 * so do not allow connection to be terminated yet. */
873 ret
->methodState
= METHOD_CONT
;
874 ret
->decision
= DECISION_COND_SUCC
;
876 /* EAP-TTLS/PAP does not provide tunneled success notification,
877 * so assume that Phase2 succeeds. */
878 ret
->methodState
= METHOD_DONE
;
879 ret
->decision
= DECISION_COND_SUCC
;
886 static int eap_ttls_phase2_request_chap(struct eap_sm
*sm
,
887 struct eap_ttls_data
*data
,
888 struct eap_method_ret
*ret
,
889 u8
**resp
, size_t *resp_len
)
891 struct wpa_ssid
*config
= eap_get_config(sm
);
892 u8
*buf
, *pos
, *challenge
;
896 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Phase 2 CHAP Request");
898 pos
= buf
= os_malloc(config
->identity_len
+ 1000);
900 wpa_printf(MSG_ERROR
,
901 "EAP-TTLS/CHAP: Failed to allocate memory");
906 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_USER_NAME
, 0, 1,
907 config
->identity
, config
->identity_len
);
910 challenge
= eap_ttls_implicit_challenge(sm
, data
, EAP_TLS_KEY_LEN
);
911 if (challenge
== NULL
) {
913 wpa_printf(MSG_ERROR
, "EAP-TTLS/CHAP: Failed to derive "
914 "implicit challenge");
918 pos
= eap_ttls_avp_add(buf
, pos
, RADIUS_ATTR_CHAP_CHALLENGE
, 0, 1,
919 challenge
, EAP_TTLS_CHAP_CHALLENGE_LEN
);
922 pos
= eap_ttls_avp_hdr(pos
, RADIUS_ATTR_CHAP_PASSWORD
, 0, 1,
923 1 + EAP_TTLS_CHAP_PASSWORD_LEN
);
924 data
->ident
= challenge
[EAP_TTLS_CHAP_CHALLENGE_LEN
];
925 *pos
++ = data
->ident
;
927 /* MD5(Ident + Password + Challenge) */
928 addr
[0] = &data
->ident
;
930 addr
[1] = config
->password
;
931 len
[1] = config
->password_len
;
933 len
[2] = EAP_TTLS_CHAP_CHALLENGE_LEN
;
934 md5_vector(3, addr
, len
, pos
);
936 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-TTLS: CHAP username",
937 config
->identity
, config
->identity_len
);
938 wpa_hexdump_ascii_key(MSG_DEBUG
, "EAP-TTLS: CHAP password",
939 config
->password
, config
->password_len
);
940 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: CHAP implicit challenge",
941 challenge
, EAP_TTLS_CHAP_CHALLENGE_LEN
);
942 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: CHAP password",
943 pos
, EAP_TTLS_CHAP_PASSWORD_LEN
);
944 pos
+= EAP_TTLS_CHAP_PASSWORD_LEN
;
949 *resp_len
= pos
- buf
;
951 if (data
->ttls_version
> 0) {
952 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
953 * so do not allow connection to be terminated yet. */
954 ret
->methodState
= METHOD_CONT
;
955 ret
->decision
= DECISION_COND_SUCC
;
957 /* EAP-TTLS/CHAP does not provide tunneled success
958 * notification, so assume that Phase2 succeeds. */
959 ret
->methodState
= METHOD_DONE
;
960 ret
->decision
= DECISION_COND_SUCC
;
967 static int eap_ttls_phase2_request(struct eap_sm
*sm
,
968 struct eap_ttls_data
*data
,
969 struct eap_method_ret
*ret
,
970 const struct eap_hdr
*req
,
972 u8
**resp
, size_t *resp_len
)
977 if (data
->phase2_type
== EAP_TTLS_PHASE2_MSCHAPV2
||
978 data
->phase2_type
== EAP_TTLS_PHASE2_MSCHAP
||
979 data
->phase2_type
== EAP_TTLS_PHASE2_PAP
||
980 data
->phase2_type
== EAP_TTLS_PHASE2_CHAP
) {
981 if (eap_get_config_identity(sm
, &len
) == NULL
) {
983 "EAP-TTLS: Identity not configured");
984 eap_sm_request_identity(sm
);
985 if (eap_get_config_password(sm
, &len
) == NULL
)
986 eap_sm_request_password(sm
);
990 if (eap_get_config_password(sm
, &len
) == NULL
) {
992 "EAP-TTLS: Password not configured");
993 eap_sm_request_password(sm
);
998 switch (data
->phase2_type
) {
999 case EAP_TTLS_PHASE2_EAP
:
1000 res
= eap_ttls_phase2_request_eap(sm
, data
, ret
, hdr
,
1003 case EAP_TTLS_PHASE2_MSCHAPV2
:
1004 res
= eap_ttls_phase2_request_mschapv2(sm
, data
, ret
,
1007 case EAP_TTLS_PHASE2_MSCHAP
:
1008 res
= eap_ttls_phase2_request_mschap(sm
, data
, ret
,
1011 case EAP_TTLS_PHASE2_PAP
:
1012 res
= eap_ttls_phase2_request_pap(sm
, data
, ret
,
1015 case EAP_TTLS_PHASE2_CHAP
:
1016 res
= eap_ttls_phase2_request_chap(sm
, data
, ret
,
1020 wpa_printf(MSG_ERROR
, "EAP-TTLS: Phase 2 - Unknown");
1026 ret
->methodState
= METHOD_DONE
;
1027 ret
->decision
= DECISION_FAIL
;
1034 static u8
* eap_ttls_build_phase_finished(struct eap_sm
*sm
,
1035 struct eap_ttls_data
*data
,
1040 struct eap_hdr
*req
;
1042 const int max_len
= 300;
1044 len
= sizeof(struct eap_hdr
) + 2 + max_len
;
1045 req
= os_malloc(len
);
1049 req
->code
= EAP_CODE_RESPONSE
;
1050 req
->identifier
= id
;
1052 pos
= (u8
*) (req
+ 1);
1053 *pos
++ = EAP_TYPE_TTLS
;
1054 *pos
++ = data
->ttls_version
;
1056 len
= tls_connection_ia_send_phase_finished(sm
->ssl_ctx
,
1058 final
, pos
, max_len
);
1064 *reqDataLen
= sizeof(struct eap_hdr
) + 2 + len
;
1065 req
->length
= host_to_be16(*reqDataLen
);
1071 static int eap_ttls_decrypt(struct eap_sm
*sm
, struct eap_ttls_data
*data
,
1072 struct eap_method_ret
*ret
,
1073 const struct eap_hdr
*req
,
1074 const u8
*in_data
, size_t in_len
,
1075 u8
**out_data
, size_t *out_len
)
1077 u8
*in_decrypted
= NULL
, *pos
;
1078 int res
, retval
= 0;
1079 struct eap_hdr
*hdr
= NULL
;
1080 u8
*resp
= NULL
, *mschapv2
= NULL
, *eapdata
= NULL
;
1081 size_t resp_len
, eap_len
= 0, len_decrypted
= 0, len
, buf_len
, left
;
1082 struct ttls_avp
*avp
;
1083 u8 recv_response
[20];
1084 int mschapv2_error
= 0;
1085 struct wpa_ssid
*config
= eap_get_config(sm
);
1088 int need_more_input
;
1090 wpa_printf(MSG_DEBUG
, "EAP-TTLS: received %lu bytes encrypted data for"
1091 " Phase 2", (unsigned long) in_len
);
1093 if (data
->pending_phase2_req
) {
1094 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Pending Phase 2 request - "
1095 "skip decryption and use old data");
1096 /* Clear TLS reassembly state. */
1097 os_free(data
->ssl
.tls_in
);
1098 data
->ssl
.tls_in
= NULL
;
1099 data
->ssl
.tls_in_len
= 0;
1100 data
->ssl
.tls_in_left
= 0;
1101 data
->ssl
.tls_in_total
= 0;
1103 in_decrypted
= data
->pending_phase2_req
;
1104 data
->pending_phase2_req
= NULL
;
1105 len_decrypted
= data
->pending_phase2_req_len
;
1106 if (data
->pending_phase2_req_len
== 0) {
1107 os_free(in_decrypted
);
1108 in_decrypted
= NULL
;
1109 goto fake_req_identity
;
1114 if (in_len
== 0 && data
->phase2_start
) {
1115 data
->phase2_start
= 0;
1116 /* EAP-TTLS does not use Phase2 on fast re-auth; this must be
1117 * done only if TLS part was indeed resuming a previous
1118 * session. Most Authentication Servers terminate EAP-TTLS
1119 * before reaching this point, but some do not. Make
1120 * wpa_supplicant stop phase 2 here, if needed. */
1122 tls_connection_resumed(sm
->ssl_ctx
, data
->ssl
.conn
)) {
1123 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Session resumption - "
1125 *out_data
= eap_tls_build_ack(&data
->ssl
, out_len
,
1128 ret
->methodState
= METHOD_DONE
;
1129 ret
->decision
= DECISION_UNCOND_SUCC
;
1130 data
->phase2_success
= 1;
1134 wpa_printf(MSG_DEBUG
, "EAP-TTLS: empty data in beginning of "
1135 "Phase 2 - use fake EAP-Request Identity");
1136 buf_len
= sizeof(*hdr
) + 1;
1137 in_decrypted
= os_malloc(buf_len
);
1138 if (in_decrypted
== NULL
) {
1139 wpa_printf(MSG_WARNING
, "EAP-TTLS: failed to allocate "
1140 "memory for fake EAP-Identity Request");
1144 hdr
= (struct eap_hdr
*) in_decrypted
;
1145 hdr
->code
= EAP_CODE_REQUEST
;
1146 hdr
->identifier
= 0;
1147 hdr
->length
= host_to_be16(sizeof(*hdr
) + 1);
1148 in_decrypted
[sizeof(*hdr
)] = EAP_TYPE_IDENTITY
;
1152 msg
= eap_tls_data_reassemble(sm
, &data
->ssl
, in_data
, in_len
,
1153 &msg_len
, &need_more_input
);
1155 return need_more_input
? 1 : -1;
1158 if (data
->ssl
.tls_in_total
> buf_len
)
1159 buf_len
= data
->ssl
.tls_in_total
;
1160 in_decrypted
= os_malloc(buf_len
);
1161 if (in_decrypted
== NULL
) {
1162 os_free(data
->ssl
.tls_in
);
1163 data
->ssl
.tls_in
= NULL
;
1164 data
->ssl
.tls_in_len
= 0;
1165 wpa_printf(MSG_WARNING
, "EAP-TTLS: failed to allocate memory "
1171 res
= tls_connection_decrypt(sm
->ssl_ctx
, data
->ssl
.conn
,
1172 msg
, msg_len
, in_decrypted
, buf_len
);
1173 os_free(data
->ssl
.tls_in
);
1174 data
->ssl
.tls_in
= NULL
;
1175 data
->ssl
.tls_in_len
= 0;
1177 wpa_printf(MSG_INFO
, "EAP-TTLS: Failed to decrypt Phase 2 "
1182 len_decrypted
= res
;
1184 if (data
->ttls_version
> 0 && len_decrypted
== 0 &&
1185 tls_connection_ia_final_phase_finished(sm
->ssl_ctx
,
1187 wpa_printf(MSG_DEBUG
, "EAP-TTLS: FinalPhaseFinished received");
1188 wpa_printf(MSG_INFO
, "EAP-TTLS: TLS/IA authentication "
1190 ret
->methodState
= METHOD_DONE
;
1191 ret
->decision
= DECISION_UNCOND_SUCC
;
1192 data
->phase2_success
= 1;
1193 *out_data
= eap_ttls_build_phase_finished(sm
, data
,
1196 eap_ttls_v1_derive_key(sm
, data
);
1201 data
->phase2_start
= 0;
1203 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: Decrypted Phase 2 AVPs",
1204 in_decrypted
, len_decrypted
);
1205 if (len_decrypted
< sizeof(struct ttls_avp
)) {
1206 wpa_printf(MSG_WARNING
, "EAP-TTLS: Too short Phase 2 AVP frame"
1207 " len=%lu expected %lu or more - dropped",
1208 (unsigned long) len_decrypted
,
1209 (unsigned long) sizeof(struct ttls_avp
));
1216 left
= len_decrypted
;
1220 u32 avp_code
, avp_length
, vendor_id
= 0;
1221 u8 avp_flags
, *dpos
;
1223 avp
= (struct ttls_avp
*) pos
;
1224 avp_code
= be_to_host32(avp
->avp_code
);
1225 avp_length
= be_to_host32(avp
->avp_length
);
1226 avp_flags
= (avp_length
>> 24) & 0xff;
1227 avp_length
&= 0xffffff;
1228 wpa_printf(MSG_DEBUG
, "EAP-TTLS: AVP: code=%d flags=0x%02x "
1229 "length=%d", (int) avp_code
, avp_flags
,
1231 if (avp_length
> left
) {
1232 wpa_printf(MSG_WARNING
, "EAP-TTLS: AVP overflow "
1233 "(len=%d, left=%lu) - dropped",
1234 (int) avp_length
, (unsigned long) left
);
1238 if (avp_length
< sizeof(*avp
)) {
1239 wpa_printf(MSG_WARNING
, "EAP-TTLS: Invalid AVP length "
1244 dpos
= (u8
*) (avp
+ 1);
1245 dlen
= avp_length
- sizeof(*avp
);
1246 if (avp_flags
& AVP_FLAGS_VENDOR
) {
1248 wpa_printf(MSG_WARNING
, "EAP-TTLS: vendor AVP "
1253 vendor_id
= be_to_host32(* (u32
*) dpos
);
1254 wpa_printf(MSG_DEBUG
, "EAP-TTLS: AVP vendor_id %d",
1260 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: AVP data", dpos
, dlen
);
1262 if (vendor_id
== 0 && avp_code
== RADIUS_ATTR_EAP_MESSAGE
) {
1263 wpa_printf(MSG_DEBUG
, "EAP-TTLS: AVP - EAP Message");
1264 if (eapdata
== NULL
) {
1265 eapdata
= os_malloc(dlen
);
1266 if (eapdata
== NULL
) {
1268 wpa_printf(MSG_WARNING
, "EAP-TTLS: "
1269 "failed to allocate memory "
1270 "for Phase 2 EAP data");
1273 os_memcpy(eapdata
, dpos
, dlen
);
1276 u8
*neweap
= os_realloc(eapdata
,
1278 if (neweap
== NULL
) {
1280 wpa_printf(MSG_WARNING
, "EAP-TTLS: "
1281 "failed to allocate memory "
1282 "for Phase 2 EAP data");
1285 os_memcpy(neweap
+ eap_len
, dpos
, dlen
);
1289 } else if (vendor_id
== 0 &&
1290 avp_code
== RADIUS_ATTR_REPLY_MESSAGE
) {
1291 /* This is an optional message that can be displayed to
1293 wpa_hexdump_ascii(MSG_DEBUG
,
1294 "EAP-TTLS: AVP - Reply-Message",
1296 } else if (vendor_id
== RADIUS_VENDOR_ID_MICROSOFT
&&
1297 avp_code
== RADIUS_ATTR_MS_CHAP2_SUCCESS
) {
1298 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-TTLS: "
1299 "MS-CHAP2-Success", dpos
, dlen
);
1301 wpa_printf(MSG_WARNING
, "EAP-TTLS: Unexpected "
1302 "MS-CHAP2-Success length "
1303 "(len=%lu, expected 43)",
1304 (unsigned long) dlen
);
1309 } else if (vendor_id
== RADIUS_VENDOR_ID_MICROSOFT
&&
1310 avp_code
== RADIUS_ATTR_MS_CHAP_ERROR
) {
1311 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-TTLS: "
1312 "MS-CHAP-Error", dpos
, dlen
);
1314 } else if (avp_flags
& AVP_FLAGS_MANDATORY
) {
1315 wpa_printf(MSG_WARNING
, "EAP-TTLS: Unsupported "
1316 "mandatory AVP code %d vendor_id %d - "
1317 "dropped", (int) avp_code
, (int) vendor_id
);
1321 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Ignoring unsupported "
1322 "AVP code %d vendor_id %d",
1323 (int) avp_code
, (int) vendor_id
);
1326 pad
= (4 - (avp_length
& 3)) & 3;
1327 pos
+= avp_length
+ pad
;
1328 if (left
< avp_length
+ pad
)
1331 left
-= avp_length
+ pad
;
1334 switch (data
->phase2_type
) {
1335 case EAP_TTLS_PHASE2_EAP
:
1336 if (eapdata
== NULL
) {
1337 wpa_printf(MSG_WARNING
, "EAP-TTLS: No EAP Message in "
1338 "the packet - dropped");
1343 wpa_hexdump(MSG_DEBUG
, "EAP-TTLS: Phase 2 EAP",
1345 hdr
= (struct eap_hdr
*) eapdata
;
1347 if (eap_len
< sizeof(*hdr
)) {
1348 wpa_printf(MSG_WARNING
, "EAP-TTLS: Too short Phase 2 "
1349 "EAP frame (len=%lu, expected %lu or more) "
1350 "- dropped", (unsigned long) eap_len
,
1351 (unsigned long) sizeof(*hdr
));
1355 len
= be_to_host16(hdr
->length
);
1356 if (len
> eap_len
) {
1357 wpa_printf(MSG_INFO
, "EAP-TTLS: Length mismatch in "
1358 "Phase 2 EAP frame (EAP hdr len=%lu, EAP "
1359 "data len in AVP=%lu)",
1360 (unsigned long) len
,
1361 (unsigned long) eap_len
);
1365 wpa_printf(MSG_DEBUG
, "EAP-TTLS: received Phase 2: code=%d "
1366 "identifier=%d length=%lu",
1367 hdr
->code
, hdr
->identifier
, (unsigned long) len
);
1369 switch (hdr
->code
) {
1370 case EAP_CODE_REQUEST
:
1371 if (eap_ttls_phase2_request(sm
, data
, ret
, req
, hdr
,
1372 &resp
, &resp_len
)) {
1373 wpa_printf(MSG_INFO
, "EAP-TTLS: Phase2 "
1374 "Request processing failed");
1380 wpa_printf(MSG_INFO
, "EAP-TTLS: Unexpected code=%d in "
1381 "Phase 2 EAP header", hdr
->code
);
1386 case EAP_TTLS_PHASE2_MSCHAPV2
:
1387 if (mschapv2_error
) {
1388 wpa_printf(MSG_DEBUG
, "EAP-TTLS/MSCHAPV2: Received "
1389 "MS-CHAP-Error - failed");
1390 ret
->methodState
= METHOD_DONE
;
1391 ret
->decision
= DECISION_FAIL
;
1392 *out_data
= eap_tls_build_ack(&data
->ssl
, out_len
,
1398 if (mschapv2
== NULL
) {
1399 wpa_printf(MSG_WARNING
, "EAP-TTLS: no MS-CHAP2-Success"
1400 " AVP received for Phase2 MSCHAPV2");
1404 if (mschapv2
[0] != data
->ident
) {
1405 wpa_printf(MSG_WARNING
, "EAP-TTLS: Ident mismatch "
1406 "for Phase 2 MSCHAPV2 (received Ident "
1407 "0x%02x, expected 0x%02x)",
1408 mschapv2
[0], data
->ident
);
1412 if (!data
->auth_response_valid
||
1413 mschapv2
[1] != 'S' || mschapv2
[2] != '=' ||
1414 hexstr2bin((char *) (mschapv2
+ 3), recv_response
, 20) ||
1415 os_memcmp(data
->auth_response
, recv_response
, 20) != 0) {
1416 wpa_printf(MSG_WARNING
, "EAP-TTLS: Invalid "
1417 "authenticator response in Phase 2 "
1418 "MSCHAPV2 success request");
1423 wpa_printf(MSG_INFO
, "EAP-TTLS: Phase 2 MSCHAPV2 "
1424 "authentication succeeded");
1425 if (data
->ttls_version
> 0) {
1426 /* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report
1427 * success, so do not allow connection to be terminated
1429 ret
->methodState
= METHOD_CONT
;
1430 ret
->decision
= DECISION_COND_SUCC
;
1432 ret
->methodState
= METHOD_DONE
;
1433 ret
->decision
= DECISION_UNCOND_SUCC
;
1434 data
->phase2_success
= 1;
1437 /* Reply with empty data; authentication server will reply
1438 * with EAP-Success after this. */
1441 case EAP_TTLS_PHASE2_MSCHAP
:
1442 case EAP_TTLS_PHASE2_PAP
:
1443 case EAP_TTLS_PHASE2_CHAP
:
1444 /* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled
1445 * requests to the supplicant */
1446 wpa_printf(MSG_INFO
, "EAP-TTLS: Phase 2 received unexpected "
1453 wpa_hexdump_key(MSG_DEBUG
, "EAP-TTLS: Encrypting Phase 2 data",
1456 if (eap_ttls_encrypt(sm
, data
, req
->identifier
,
1457 resp
, resp_len
, out_data
, out_len
)) {
1458 wpa_printf(MSG_INFO
, "EAP-TTLS: Failed to encrypt "
1462 } else if (config
->pending_req_identity
||
1463 config
->pending_req_password
||
1464 config
->pending_req_otp
||
1465 config
->pending_req_new_password
) {
1466 os_free(data
->pending_phase2_req
);
1467 data
->pending_phase2_req
= os_malloc(len_decrypted
);
1468 if (data
->pending_phase2_req
) {
1469 os_memcpy(data
->pending_phase2_req
, in_decrypted
,
1471 data
->pending_phase2_req_len
= len_decrypted
;
1476 os_free(in_decrypted
);
1480 ret
->methodState
= METHOD_DONE
;
1481 ret
->decision
= DECISION_FAIL
;
1488 static u8
* eap_ttls_process(struct eap_sm
*sm
, void *priv
,
1489 struct eap_method_ret
*ret
,
1490 const u8
*reqData
, size_t reqDataLen
,
1491 size_t *respDataLen
)
1493 const struct eap_hdr
*req
;
1496 u8 flags
, *resp
, id
;
1498 struct eap_ttls_data
*data
= priv
;
1499 struct wpa_ssid
*config
= eap_get_config(sm
);
1501 pos
= eap_tls_process_init(sm
, &data
->ssl
, EAP_TYPE_TTLS
, ret
,
1502 reqData
, reqDataLen
, &left
, &flags
);
1505 req
= (const struct eap_hdr
*) reqData
;
1506 id
= req
->identifier
;
1508 if (flags
& EAP_TLS_FLAGS_START
) {
1509 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Start (server ver=%d, own "
1510 "ver=%d)", flags
& EAP_PEAP_VERSION_MASK
,
1511 data
->ttls_version
);
1512 if ((flags
& EAP_PEAP_VERSION_MASK
) < data
->ttls_version
)
1513 data
->ttls_version
= flags
& EAP_PEAP_VERSION_MASK
;
1514 if (data
->force_ttls_version
>= 0 &&
1515 data
->force_ttls_version
!= data
->ttls_version
) {
1516 wpa_printf(MSG_WARNING
, "EAP-TTLS: Failed to select "
1517 "forced TTLS version %d",
1518 data
->force_ttls_version
);
1519 ret
->methodState
= METHOD_DONE
;
1520 ret
->decision
= DECISION_FAIL
;
1521 ret
->allowNotifications
= FALSE
;
1524 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Using TTLS version %d",
1525 data
->ttls_version
);
1527 if (data
->ttls_version
> 0)
1528 data
->ssl
.tls_ia
= 1;
1529 if (!data
->ssl_initialized
&&
1530 eap_tls_ssl_init(sm
, &data
->ssl
, config
)) {
1531 wpa_printf(MSG_INFO
, "EAP-TTLS: Failed to initialize "
1535 data
->ssl_initialized
= 1;
1537 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Start");
1538 /* draft-ietf-pppext-eap-ttls-03.txt, Ch. 8.1:
1539 * EAP-TTLS Start packet may, in a future specification, be
1540 * allowed to contain data. Client based on this draft version
1541 * must ignore such data but must not reject the Start packet.
1544 } else if (!data
->ssl_initialized
) {
1545 wpa_printf(MSG_DEBUG
, "EAP-TTLS: First message did not "
1546 "include Start flag");
1547 ret
->methodState
= METHOD_DONE
;
1548 ret
->decision
= DECISION_FAIL
;
1549 ret
->allowNotifications
= FALSE
;
1554 if (tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
) &&
1556 res
= eap_ttls_decrypt(sm
, data
, ret
, req
, pos
, left
,
1557 &resp
, respDataLen
);
1559 res
= eap_tls_process_helper(sm
, &data
->ssl
, EAP_TYPE_TTLS
,
1560 data
->ttls_version
, id
, pos
, left
,
1561 &resp
, respDataLen
);
1563 if (tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
)) {
1564 wpa_printf(MSG_DEBUG
,
1565 "EAP-TTLS: TLS done, proceed to Phase 2");
1566 if (data
->resuming
) {
1567 wpa_printf(MSG_DEBUG
, "EAP-TTLS: fast reauth -"
1568 " may skip Phase 2");
1569 ret
->decision
= DECISION_COND_SUCC
;
1570 ret
->methodState
= METHOD_MAY_CONT
;
1572 data
->phase2_start
= 1;
1573 if (data
->ttls_version
== 0)
1574 eap_ttls_v0_derive_key(sm
, data
);
1576 if (*respDataLen
== 0) {
1577 if (eap_ttls_decrypt(sm
, data
, ret
, req
, NULL
,
1578 0, &resp
, respDataLen
)) {
1579 wpa_printf(MSG_WARNING
, "EAP-TTLS: "
1580 "failed to process early "
1581 "start for Phase 2");
1590 * Application data included in the handshake message.
1592 os_free(data
->pending_phase2_req
);
1593 data
->pending_phase2_req
= resp
;
1594 data
->pending_phase2_req_len
= *respDataLen
;
1597 res
= eap_ttls_decrypt(sm
, data
, ret
, req
, pos
, left
,
1598 &resp
, respDataLen
);
1602 if (data
->ttls_version
== 0 && ret
->methodState
== METHOD_DONE
) {
1603 ret
->allowNotifications
= FALSE
;
1604 if (ret
->decision
== DECISION_UNCOND_SUCC
||
1605 ret
->decision
== DECISION_COND_SUCC
) {
1606 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Authentication "
1607 "completed successfully");
1608 data
->phase2_success
= 1;
1610 } else if (data
->ttls_version
== 0 && sm
->workaround
&&
1611 ret
->methodState
== METHOD_MAY_CONT
&&
1612 (ret
->decision
== DECISION_UNCOND_SUCC
||
1613 ret
->decision
== DECISION_COND_SUCC
)) {
1614 wpa_printf(MSG_DEBUG
, "EAP-TTLS: Authentication "
1615 "completed successfully (EAP workaround)");
1616 data
->phase2_success
= 1;
1620 return eap_tls_build_ack(&data
->ssl
, respDataLen
, id
,
1621 EAP_TYPE_TTLS
, data
->ttls_version
);
1627 static Boolean
eap_ttls_has_reauth_data(struct eap_sm
*sm
, void *priv
)
1629 struct eap_ttls_data
*data
= priv
;
1630 return tls_connection_established(sm
->ssl_ctx
, data
->ssl
.conn
) &&
1631 data
->phase2_success
;
1635 static void eap_ttls_deinit_for_reauth(struct eap_sm
*sm
, void *priv
)
1637 struct eap_ttls_data
*data
= priv
;
1638 os_free(data
->pending_phase2_req
);
1639 data
->pending_phase2_req
= NULL
;
1643 static void * eap_ttls_init_for_reauth(struct eap_sm
*sm
, void *priv
)
1645 struct eap_ttls_data
*data
= priv
;
1646 os_free(data
->key_data
);
1647 data
->key_data
= NULL
;
1648 if (eap_tls_reauth_init(sm
, &data
->ssl
)) {
1652 if (data
->phase2_priv
&& data
->phase2_method
&&
1653 data
->phase2_method
->init_for_reauth
)
1654 data
->phase2_method
->init_for_reauth(sm
, data
->phase2_priv
);
1655 data
->phase2_start
= 0;
1656 data
->phase2_success
= 0;
1663 static int eap_ttls_get_status(struct eap_sm
*sm
, void *priv
, char *buf
,
1664 size_t buflen
, int verbose
)
1666 struct eap_ttls_data
*data
= priv
;
1669 len
= eap_tls_status(sm
, &data
->ssl
, buf
, buflen
, verbose
);
1670 ret
= os_snprintf(buf
+ len
, buflen
- len
,
1671 "EAP-TTLSv%d Phase2 method=",
1672 data
->ttls_version
);
1673 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1676 switch (data
->phase2_type
) {
1677 case EAP_TTLS_PHASE2_EAP
:
1678 ret
= os_snprintf(buf
+ len
, buflen
- len
, "EAP-%s\n",
1679 data
->phase2_method
?
1680 data
->phase2_method
->name
: "?");
1682 case EAP_TTLS_PHASE2_MSCHAPV2
:
1683 ret
= os_snprintf(buf
+ len
, buflen
- len
, "MSCHAPV2\n");
1685 case EAP_TTLS_PHASE2_MSCHAP
:
1686 ret
= os_snprintf(buf
+ len
, buflen
- len
, "MSCHAP\n");
1688 case EAP_TTLS_PHASE2_PAP
:
1689 ret
= os_snprintf(buf
+ len
, buflen
- len
, "PAP\n");
1691 case EAP_TTLS_PHASE2_CHAP
:
1692 ret
= os_snprintf(buf
+ len
, buflen
- len
, "CHAP\n");
1698 if (ret
< 0 || (size_t) ret
>= buflen
- len
)
1706 static Boolean
eap_ttls_isKeyAvailable(struct eap_sm
*sm
, void *priv
)
1708 struct eap_ttls_data
*data
= priv
;
1709 return data
->key_data
!= NULL
&& data
->phase2_success
;
1713 static u8
* eap_ttls_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
1715 struct eap_ttls_data
*data
= priv
;
1718 if (data
->key_data
== NULL
|| !data
->phase2_success
)
1721 key
= os_malloc(EAP_TLS_KEY_LEN
);
1725 *len
= EAP_TLS_KEY_LEN
;
1726 os_memcpy(key
, data
->key_data
, EAP_TLS_KEY_LEN
);
1732 int eap_peer_ttls_register(void)
1734 struct eap_method
*eap
;
1737 eap
= eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION
,
1738 EAP_VENDOR_IETF
, EAP_TYPE_TTLS
, "TTLS");
1742 eap
->init
= eap_ttls_init
;
1743 eap
->deinit
= eap_ttls_deinit
;
1744 eap
->process
= eap_ttls_process
;
1745 eap
->isKeyAvailable
= eap_ttls_isKeyAvailable
;
1746 eap
->getKey
= eap_ttls_getKey
;
1747 eap
->get_status
= eap_ttls_get_status
;
1748 eap
->has_reauth_data
= eap_ttls_has_reauth_data
;
1749 eap
->deinit_for_reauth
= eap_ttls_deinit_for_reauth
;
1750 eap
->init_for_reauth
= eap_ttls_init_for_reauth
;
1752 ret
= eap_peer_method_register(eap
);
1754 eap_peer_method_free(eap
);