2 * EAP-TEAP server (RFC 7170)
3 * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "crypto/aes_wrap.h"
13 #include "crypto/tls.h"
14 #include "crypto/random.h"
15 #include "eap_common/eap_teap_common.h"
17 #include "eap_tls_common.h"
20 static void eap_teap_reset(struct eap_sm
*sm
, void *priv
);
23 /* Private PAC-Opaque TLV types */
24 #define PAC_OPAQUE_TYPE_PAD 0
25 #define PAC_OPAQUE_TYPE_KEY 1
26 #define PAC_OPAQUE_TYPE_LIFETIME 2
27 #define PAC_OPAQUE_TYPE_IDENTITY 3
29 struct eap_teap_data
{
30 struct eap_ssl_data ssl
;
32 START
, PHASE1
, PHASE1B
, PHASE2_START
, PHASE2_ID
,
33 PHASE2_BASIC_AUTH
, PHASE2_METHOD
, CRYPTO_BINDING
, REQUEST_PAC
,
34 FAILURE_SEND_RESULT
, SUCCESS_SEND_RESULT
, SUCCESS
, FAILURE
41 const struct eap_method
*phase2_method
;
44 u8 crypto_binding_nonce
[32];
47 u8 simck_msk
[EAP_TEAP_SIMCK_LEN
];
48 u8 cmk_msk
[EAP_TEAP_CMK_LEN
];
49 u8 simck_emsk
[EAP_TEAP_SIMCK_LEN
];
50 u8 cmk_emsk
[EAP_TEAP_CMK_LEN
];
52 int cmk_emsk_available
;
54 u8 pac_opaque_encr
[16];
59 int anon_provisioning
;
60 int send_new_pac
; /* server triggered re-keying of Tunnel PAC */
61 struct wpabuf
*pending_phase2_resp
;
62 struct wpabuf
*server_outer_tlvs
;
63 struct wpabuf
*peer_outer_tlvs
;
64 u8
*identity
; /* from PAC-Opaque */
70 int pac_key_refresh_time
;
72 enum teap_error_codes error_code
;
76 static int eap_teap_process_phase2_start(struct eap_sm
*sm
,
77 struct eap_teap_data
*data
);
80 static const char * eap_teap_state_txt(int state
)
90 return "PHASE2_START";
93 case PHASE2_BASIC_AUTH
:
94 return "PHASE2_BASIC_AUTH";
96 return "PHASE2_METHOD";
98 return "CRYPTO_BINDING";
100 return "REQUEST_PAC";
101 case FAILURE_SEND_RESULT
:
102 return "FAILURE_SEND_RESULT";
103 case SUCCESS_SEND_RESULT
:
104 return "SUCCESS_SEND_RESULT";
115 static void eap_teap_state(struct eap_teap_data
*data
, int state
)
117 wpa_printf(MSG_DEBUG
, "EAP-TEAP: %s -> %s",
118 eap_teap_state_txt(data
->state
),
119 eap_teap_state_txt(state
));
124 static enum eap_type
eap_teap_req_failure(struct eap_teap_data
*data
,
125 enum teap_error_codes error
)
127 eap_teap_state(data
, FAILURE_SEND_RESULT
);
128 return EAP_TYPE_NONE
;
132 static int eap_teap_session_ticket_cb(void *ctx
, const u8
*ticket
, size_t len
,
133 const u8
*client_random
,
134 const u8
*server_random
,
137 struct eap_teap_data
*data
= ctx
;
138 const u8
*pac_opaque
;
139 size_t pac_opaque_len
;
140 u8
*buf
, *pos
, *end
, *pac_key
= NULL
;
141 os_time_t lifetime
= 0;
144 size_t identity_len
= 0;
146 wpa_printf(MSG_DEBUG
, "EAP-TEAP: SessionTicket callback");
147 wpa_hexdump(MSG_DEBUG
, "EAP-TEAP: SessionTicket (PAC-Opaque)",
150 if (len
< 4 || WPA_GET_BE16(ticket
) != PAC_TYPE_PAC_OPAQUE
) {
151 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Ignore invalid SessionTicket");
155 pac_opaque_len
= WPA_GET_BE16(ticket
+ 2);
156 pac_opaque
= ticket
+ 4;
157 if (pac_opaque_len
< 8 || pac_opaque_len
% 8 ||
158 pac_opaque_len
> len
- 4) {
159 wpa_printf(MSG_DEBUG
,
160 "EAP-TEAP: Ignore invalid PAC-Opaque (len=%lu left=%lu)",
161 (unsigned long) pac_opaque_len
,
162 (unsigned long) len
);
165 wpa_hexdump(MSG_DEBUG
, "EAP-TEAP: Received PAC-Opaque",
166 pac_opaque
, pac_opaque_len
);
168 buf
= os_malloc(pac_opaque_len
- 8);
170 wpa_printf(MSG_DEBUG
,
171 "EAP-TEAP: Failed to allocate memory for decrypting PAC-Opaque");
175 if (aes_unwrap(data
->pac_opaque_encr
, sizeof(data
->pac_opaque_encr
),
176 (pac_opaque_len
- 8) / 8, pac_opaque
, buf
) < 0) {
177 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Failed to decrypt PAC-Opaque");
180 * This may have been caused by server changing the PAC-Opaque
181 * encryption key, so just ignore this PAC-Opaque instead of
182 * failing the authentication completely. Provisioning can now
183 * be used to provision a new PAC.
188 end
= buf
+ pac_opaque_len
- 8;
189 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: Decrypted PAC-Opaque",
193 while (end
- pos
> 1) {
198 if (elen
> end
- pos
)
202 case PAC_OPAQUE_TYPE_PAD
:
204 case PAC_OPAQUE_TYPE_KEY
:
205 if (elen
!= EAP_TEAP_PAC_KEY_LEN
) {
206 wpa_printf(MSG_DEBUG
,
207 "EAP-TEAP: Invalid PAC-Key length %d",
213 wpa_hexdump_key(MSG_DEBUG
,
214 "EAP-TEAP: PAC-Key from decrypted PAC-Opaque",
215 pac_key
, EAP_TEAP_PAC_KEY_LEN
);
217 case PAC_OPAQUE_TYPE_LIFETIME
:
219 wpa_printf(MSG_DEBUG
,
220 "EAP-TEAP: Invalid PAC-Key lifetime length %d",
225 lifetime
= WPA_GET_BE32(pos
);
227 case PAC_OPAQUE_TYPE_IDENTITY
:
238 wpa_printf(MSG_DEBUG
,
239 "EAP-TEAP: No PAC-Key included in PAC-Opaque");
245 wpa_hexdump_ascii(MSG_DEBUG
,
246 "EAP-TEAP: Identity from PAC-Opaque",
247 identity
, identity_len
);
248 os_free(data
->identity
);
249 data
->identity
= os_malloc(identity_len
);
250 if (data
->identity
) {
251 os_memcpy(data
->identity
, identity
, identity_len
);
252 data
->identity_len
= identity_len
;
256 if (os_get_time(&now
) < 0 || lifetime
<= 0 || now
.sec
> lifetime
) {
257 wpa_printf(MSG_DEBUG
,
258 "EAP-TEAP: PAC-Key not valid anymore (lifetime=%ld now=%ld)",
260 data
->send_new_pac
= 2;
262 * Allow PAC to be used to allow a PAC update with some level
263 * of server authentication (i.e., do not fall back to full TLS
264 * handshake since we cannot be sure that the peer would be
265 * able to validate server certificate now). However, reject
266 * the authentication since the PAC was not valid anymore. Peer
267 * can connect again with the newly provisioned PAC after this.
269 } else if (lifetime
- now
.sec
< data
->pac_key_refresh_time
) {
270 wpa_printf(MSG_DEBUG
,
271 "EAP-TEAP: PAC-Key soft timeout; send an update if authentication succeeds");
272 data
->send_new_pac
= 1;
275 /* EAP-TEAP uses PAC-Key as the TLS master_secret */
276 os_memcpy(master_secret
, pac_key
, EAP_TEAP_PAC_KEY_LEN
);
284 static int eap_teap_derive_key_auth(struct eap_sm
*sm
,
285 struct eap_teap_data
*data
)
289 /* RFC 7170, Section 5.1 */
290 res
= tls_connection_export_key(sm
->cfg
->ssl_ctx
, data
->ssl
.conn
,
291 TEAP_TLS_EXPORTER_LABEL_SKS
, NULL
, 0,
292 data
->simck_msk
, EAP_TEAP_SIMCK_LEN
);
295 wpa_hexdump_key(MSG_DEBUG
,
296 "EAP-TEAP: session_key_seed (S-IMCK[0])",
297 data
->simck_msk
, EAP_TEAP_SIMCK_LEN
);
298 os_memcpy(data
->simck_emsk
, data
->simck_msk
, EAP_TEAP_SIMCK_LEN
);
304 static int eap_teap_update_icmk(struct eap_sm
*sm
, struct eap_teap_data
*data
)
306 u8
*msk
= NULL
, *emsk
= NULL
;
307 size_t msk_len
= 0, emsk_len
= 0;
310 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Deriving ICMK[%d] (S-IMCK and CMK)",
311 data
->simck_idx
+ 1);
313 if (sm
->cfg
->eap_teap_auth
== 1)
314 return eap_teap_derive_cmk_basic_pw_auth(data
->tls_cs
,
318 if (!data
->phase2_method
|| !data
->phase2_priv
) {
319 wpa_printf(MSG_INFO
, "EAP-TEAP: Phase 2 method not available");
323 if (data
->phase2_method
->getKey
) {
324 msk
= data
->phase2_method
->getKey(sm
, data
->phase2_priv
,
328 "EAP-TEAP: Could not fetch Phase 2 MSK");
333 if (data
->phase2_method
->get_emsk
) {
334 emsk
= data
->phase2_method
->get_emsk(sm
, data
->phase2_priv
,
338 res
= eap_teap_derive_imck(data
->tls_cs
,
339 data
->simck_msk
, data
->simck_emsk
,
340 msk
, msk_len
, emsk
, emsk_len
,
341 data
->simck_msk
, data
->cmk_msk
,
342 data
->simck_emsk
, data
->cmk_emsk
);
343 bin_clear_free(msk
, msk_len
);
344 bin_clear_free(emsk
, emsk_len
);
348 data
->cmk_emsk_available
= 1;
354 static void * eap_teap_init(struct eap_sm
*sm
)
356 struct eap_teap_data
*data
;
358 data
= os_zalloc(sizeof(*data
));
361 data
->teap_version
= EAP_TEAP_VERSION
;
364 if (eap_server_tls_ssl_init(sm
, &data
->ssl
, 0, EAP_TYPE_TEAP
)) {
365 wpa_printf(MSG_INFO
, "EAP-TEAP: Failed to initialize SSL.");
366 eap_teap_reset(sm
, data
);
370 /* TODO: Add anon-DH TLS cipher suites (and if one is negotiated,
371 * enforce inner EAP with mutual authentication to be used) */
373 if (tls_connection_set_session_ticket_cb(sm
->cfg
->ssl_ctx
,
375 eap_teap_session_ticket_cb
,
378 "EAP-TEAP: Failed to set SessionTicket callback");
379 eap_teap_reset(sm
, data
);
383 if (!sm
->cfg
->pac_opaque_encr_key
) {
385 "EAP-TEAP: No PAC-Opaque encryption key configured");
386 eap_teap_reset(sm
, data
);
389 os_memcpy(data
->pac_opaque_encr
, sm
->cfg
->pac_opaque_encr_key
,
390 sizeof(data
->pac_opaque_encr
));
392 if (!sm
->cfg
->eap_fast_a_id
) {
393 wpa_printf(MSG_INFO
, "EAP-TEAP: No A-ID configured");
394 eap_teap_reset(sm
, data
);
397 data
->srv_id
= os_malloc(sm
->cfg
->eap_fast_a_id_len
);
399 eap_teap_reset(sm
, data
);
402 os_memcpy(data
->srv_id
, sm
->cfg
->eap_fast_a_id
,
403 sm
->cfg
->eap_fast_a_id_len
);
404 data
->srv_id_len
= sm
->cfg
->eap_fast_a_id_len
;
406 if (!sm
->cfg
->eap_fast_a_id_info
) {
407 wpa_printf(MSG_INFO
, "EAP-TEAP: No A-ID-Info configured");
408 eap_teap_reset(sm
, data
);
411 data
->srv_id_info
= os_strdup(sm
->cfg
->eap_fast_a_id_info
);
412 if (!data
->srv_id_info
) {
413 eap_teap_reset(sm
, data
);
417 /* PAC-Key lifetime in seconds (hard limit) */
418 data
->pac_key_lifetime
= sm
->cfg
->pac_key_lifetime
;
421 * PAC-Key refresh time in seconds (soft limit on remaining hard
422 * limit). The server will generate a new PAC-Key when this number of
423 * seconds (or fewer) of the lifetime remains.
425 data
->pac_key_refresh_time
= sm
->cfg
->pac_key_refresh_time
;
431 static void eap_teap_reset(struct eap_sm
*sm
, void *priv
)
433 struct eap_teap_data
*data
= priv
;
437 if (data
->phase2_priv
&& data
->phase2_method
)
438 data
->phase2_method
->reset(sm
, data
->phase2_priv
);
439 eap_server_tls_ssl_deinit(sm
, &data
->ssl
);
440 os_free(data
->srv_id
);
441 os_free(data
->srv_id_info
);
442 wpabuf_free(data
->pending_phase2_resp
);
443 wpabuf_free(data
->server_outer_tlvs
);
444 wpabuf_free(data
->peer_outer_tlvs
);
445 os_free(data
->identity
);
446 forced_memzero(data
->simck_msk
, EAP_TEAP_SIMCK_LEN
);
447 forced_memzero(data
->simck_emsk
, EAP_TEAP_SIMCK_LEN
);
448 forced_memzero(data
->cmk_msk
, EAP_TEAP_CMK_LEN
);
449 forced_memzero(data
->cmk_emsk
, EAP_TEAP_CMK_LEN
);
450 forced_memzero(data
->pac_opaque_encr
, sizeof(data
->pac_opaque_encr
));
451 bin_clear_free(data
, sizeof(*data
));
455 static struct wpabuf
* eap_teap_build_start(struct eap_sm
*sm
,
456 struct eap_teap_data
*data
, u8 id
)
459 size_t outer_tlv_len
= sizeof(struct teap_tlv_hdr
) + data
->srv_id_len
;
460 const u8
*start
, *end
;
462 req
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_TEAP
,
463 1 + 4 + outer_tlv_len
, EAP_CODE_REQUEST
, id
);
465 wpa_printf(MSG_ERROR
,
466 "EAP-TEAP: Failed to allocate memory for request");
467 eap_teap_state(data
, FAILURE
);
471 wpabuf_put_u8(req
, EAP_TLS_FLAGS_START
| EAP_TEAP_FLAGS_OUTER_TLV_LEN
|
473 wpabuf_put_be32(req
, outer_tlv_len
);
475 start
= wpabuf_put(req
, 0);
477 /* RFC 7170, Section 4.2.2: Authority-ID TLV */
478 eap_teap_put_tlv(req
, TEAP_TLV_AUTHORITY_ID
,
479 data
->srv_id
, data
->srv_id_len
);
481 end
= wpabuf_put(req
, 0);
482 wpabuf_free(data
->server_outer_tlvs
);
483 data
->server_outer_tlvs
= wpabuf_alloc_copy(start
, end
- start
);
484 if (!data
->server_outer_tlvs
) {
485 eap_teap_state(data
, FAILURE
);
489 eap_teap_state(data
, PHASE1
);
495 static int eap_teap_phase1_done(struct eap_sm
*sm
, struct eap_teap_data
*data
)
499 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Phase 1 done, starting Phase 2");
501 data
->tls_cs
= tls_connection_get_cipher_suite(data
->ssl
.conn
);
502 wpa_printf(MSG_DEBUG
, "EAP-TEAP: TLS cipher suite 0x%04x",
505 if (tls_get_cipher(sm
->cfg
->ssl_ctx
, data
->ssl
.conn
,
506 cipher
, sizeof(cipher
)) < 0) {
507 wpa_printf(MSG_DEBUG
,
508 "EAP-TEAP: Failed to get cipher information");
509 eap_teap_state(data
, FAILURE
);
512 data
->anon_provisioning
= os_strstr(cipher
, "ADH") != NULL
;
514 if (data
->anon_provisioning
)
515 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Anonymous provisioning");
517 if (eap_teap_derive_key_auth(sm
, data
) < 0) {
518 eap_teap_state(data
, FAILURE
);
522 eap_teap_state(data
, PHASE2_START
);
528 static struct wpabuf
* eap_teap_build_phase2_req(struct eap_sm
*sm
,
529 struct eap_teap_data
*data
,
534 if (sm
->cfg
->eap_teap_auth
== 1) {
535 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Initiate Basic-Password-Auth");
536 req
= wpabuf_alloc(sizeof(struct teap_tlv_hdr
));
539 eap_teap_put_tlv_hdr(req
, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ
, 0);
543 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Initiate inner EAP method");
544 if (!data
->phase2_priv
) {
545 wpa_printf(MSG_DEBUG
,
546 "EAP-TEAP: Phase 2 method not initialized");
550 req
= data
->phase2_method
->buildReq(sm
, data
->phase2_priv
, id
);
554 wpa_hexdump_buf_key(MSG_MSGDUMP
, "EAP-TEAP: Phase 2 EAP-Request", req
);
555 return eap_teap_tlv_eap_payload(req
);
559 static struct wpabuf
* eap_teap_build_crypto_binding(
560 struct eap_sm
*sm
, struct eap_teap_data
*data
)
563 struct teap_tlv_result
*result
;
564 struct teap_tlv_crypto_binding
*cb
;
567 buf
= wpabuf_alloc(2 * sizeof(*result
) + sizeof(*cb
));
571 if (data
->send_new_pac
|| data
->anon_provisioning
||
572 data
->phase2_method
|| sm
->cfg
->eap_teap_separate_result
)
573 data
->final_result
= 0;
575 data
->final_result
= 1;
577 if (!data
->final_result
|| data
->eap_seq
> 0) {
578 /* Intermediate-Result */
579 wpa_printf(MSG_DEBUG
,
580 "EAP-TEAP: Add Intermediate-Result TLV (status=SUCCESS)");
581 result
= wpabuf_put(buf
, sizeof(*result
));
582 result
->tlv_type
= host_to_be16(TEAP_TLV_MANDATORY
|
583 TEAP_TLV_INTERMEDIATE_RESULT
);
584 result
->length
= host_to_be16(2);
585 result
->status
= host_to_be16(TEAP_STATUS_SUCCESS
);
588 if (data
->final_result
) {
590 wpa_printf(MSG_DEBUG
,
591 "EAP-TEAP: Add Result TLV (status=SUCCESS)");
592 result
= wpabuf_put(buf
, sizeof(*result
));
593 result
->tlv_type
= host_to_be16(TEAP_TLV_MANDATORY
|
595 result
->length
= host_to_be16(2);
596 result
->status
= host_to_be16(TEAP_STATUS_SUCCESS
);
599 /* Crypto-Binding TLV */
600 cb
= wpabuf_put(buf
, sizeof(*cb
));
601 cb
->tlv_type
= host_to_be16(TEAP_TLV_MANDATORY
|
602 TEAP_TLV_CRYPTO_BINDING
);
603 cb
->length
= host_to_be16(sizeof(*cb
) - sizeof(struct teap_tlv_hdr
));
604 cb
->version
= EAP_TEAP_VERSION
;
605 cb
->received_version
= data
->peer_version
;
606 /* FIX: RFC 7170 is not clear on which Flags value to use when
607 * Crypto-Binding TLV is used with Basic-Password-Auth */
608 flags
= data
->cmk_emsk_available
?
609 TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC
:
610 TEAP_CRYPTO_BINDING_MSK_CMAC
;
611 subtype
= TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST
;
612 cb
->subtype
= (flags
<< 4) | subtype
;
613 if (random_get_bytes(cb
->nonce
, sizeof(cb
->nonce
)) < 0) {
619 * RFC 7170, Section 4.2.13:
620 * The nonce in a request MUST have its least significant bit set to 0.
622 cb
->nonce
[sizeof(cb
->nonce
) - 1] &= ~0x01;
624 os_memcpy(data
->crypto_binding_nonce
, cb
->nonce
, sizeof(cb
->nonce
));
626 if (eap_teap_compound_mac(data
->tls_cs
, cb
, data
->server_outer_tlvs
,
627 data
->peer_outer_tlvs
, data
->cmk_msk
,
628 cb
->msk_compound_mac
) < 0) {
633 if (data
->cmk_emsk_available
&&
634 eap_teap_compound_mac(data
->tls_cs
, cb
, data
->server_outer_tlvs
,
635 data
->peer_outer_tlvs
, data
->cmk_emsk
,
636 cb
->emsk_compound_mac
) < 0) {
641 wpa_printf(MSG_DEBUG
,
642 "EAP-TEAP: Add Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
643 cb
->version
, cb
->received_version
, flags
, subtype
);
644 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Nonce",
645 cb
->nonce
, sizeof(cb
->nonce
));
646 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: EMSK Compound MAC",
647 cb
->emsk_compound_mac
, sizeof(cb
->emsk_compound_mac
));
648 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: MSK Compound MAC",
649 cb
->msk_compound_mac
, sizeof(cb
->msk_compound_mac
));
655 static struct wpabuf
* eap_teap_build_pac(struct eap_sm
*sm
,
656 struct eap_teap_data
*data
)
658 u8 pac_key
[EAP_TEAP_PAC_KEY_LEN
];
659 u8
*pac_buf
, *pac_opaque
;
662 size_t buf_len
, srv_id_info_len
, pac_len
;
663 struct teap_tlv_hdr
*pac_tlv
;
664 struct pac_attr_hdr
*pac_info
;
665 struct teap_tlv_result
*result
;
668 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Build a new PAC");
670 if (random_get_bytes(pac_key
, EAP_TEAP_PAC_KEY_LEN
) < 0 ||
671 os_get_time(&now
) < 0)
673 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: Generated PAC-Key",
674 pac_key
, EAP_TEAP_PAC_KEY_LEN
);
676 pac_len
= (2 + EAP_TEAP_PAC_KEY_LEN
) + (2 + 4) +
677 (2 + sm
->identity_len
) + 8;
678 pac_buf
= os_malloc(pac_len
);
682 srv_id_info_len
= os_strlen(data
->srv_id_info
);
685 *pos
++ = PAC_OPAQUE_TYPE_KEY
;
686 *pos
++ = EAP_TEAP_PAC_KEY_LEN
;
687 os_memcpy(pos
, pac_key
, EAP_TEAP_PAC_KEY_LEN
);
688 pos
+= EAP_TEAP_PAC_KEY_LEN
;
690 wpa_printf(MSG_DEBUG
, "EAP-TEAP: PAC-Key lifetime: %u seconds",
691 data
->pac_key_lifetime
);
692 *pos
++ = PAC_OPAQUE_TYPE_LIFETIME
;
694 WPA_PUT_BE32(pos
, now
.sec
+ data
->pac_key_lifetime
);
698 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-TEAP: PAC-Opaque Identity",
699 sm
->identity
, sm
->identity_len
);
700 *pos
++ = PAC_OPAQUE_TYPE_IDENTITY
;
701 *pos
++ = sm
->identity_len
;
702 os_memcpy(pos
, sm
->identity
, sm
->identity_len
);
703 pos
+= sm
->identity_len
;
706 pac_len
= pos
- pac_buf
;
707 while (pac_len
% 8) {
708 *pos
++ = PAC_OPAQUE_TYPE_PAD
;
712 pac_opaque
= os_malloc(pac_len
+ 8);
717 if (aes_wrap(data
->pac_opaque_encr
, sizeof(data
->pac_opaque_encr
),
718 pac_len
/ 8, pac_buf
, pac_opaque
) < 0) {
726 wpa_hexdump(MSG_DEBUG
, "EAP-TEAP: PAC-Opaque", pac_opaque
, pac_len
);
728 buf_len
= sizeof(*pac_tlv
) +
729 sizeof(struct pac_attr_hdr
) + EAP_TEAP_PAC_KEY_LEN
+
730 sizeof(struct pac_attr_hdr
) + pac_len
+
731 data
->srv_id_len
+ srv_id_info_len
+ 100 + sizeof(*result
);
732 buf
= wpabuf_alloc(buf_len
);
739 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Add Result TLV (status=SUCCESS)");
740 result
= wpabuf_put(buf
, sizeof(*result
));
741 WPA_PUT_BE16((u8
*) &result
->tlv_type
,
742 TEAP_TLV_MANDATORY
| TEAP_TLV_RESULT
);
743 WPA_PUT_BE16((u8
*) &result
->length
, 2);
744 WPA_PUT_BE16((u8
*) &result
->status
, TEAP_STATUS_SUCCESS
);
747 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Add PAC TLV");
748 pac_tlv
= wpabuf_put(buf
, sizeof(*pac_tlv
));
749 pac_tlv
->tlv_type
= host_to_be16(TEAP_TLV_MANDATORY
| TEAP_TLV_PAC
);
752 eap_teap_put_tlv(buf
, PAC_TYPE_PAC_KEY
, pac_key
, EAP_TEAP_PAC_KEY_LEN
);
755 eap_teap_put_tlv(buf
, PAC_TYPE_PAC_OPAQUE
, pac_opaque
, pac_len
);
759 pac_info
= wpabuf_put(buf
, sizeof(*pac_info
));
760 pac_info
->type
= host_to_be16(PAC_TYPE_PAC_INFO
);
762 /* PAC-Lifetime (inside PAC-Info) */
763 eap_teap_put_tlv_hdr(buf
, PAC_TYPE_CRED_LIFETIME
, 4);
764 wpabuf_put_be32(buf
, now
.sec
+ data
->pac_key_lifetime
);
766 /* A-ID (inside PAC-Info) */
767 eap_teap_put_tlv(buf
, PAC_TYPE_A_ID
, data
->srv_id
, data
->srv_id_len
);
769 /* Note: headers may be misaligned after A-ID */
772 eap_teap_put_tlv(buf
, PAC_TYPE_I_ID
, sm
->identity
,
776 /* A-ID-Info (inside PAC-Info) */
777 eap_teap_put_tlv(buf
, PAC_TYPE_A_ID_INFO
, data
->srv_id_info
,
780 /* PAC-Type (inside PAC-Info) */
781 eap_teap_put_tlv_hdr(buf
, PAC_TYPE_PAC_TYPE
, 2);
782 wpabuf_put_be16(buf
, PAC_TYPE_TUNNEL_PAC
);
784 /* Update PAC-Info and PAC TLV Length fields */
785 pos
= wpabuf_put(buf
, 0);
786 pac_info
->len
= host_to_be16(pos
- (u8
*) (pac_info
+ 1));
787 pac_tlv
->length
= host_to_be16(pos
- (u8
*) (pac_tlv
+ 1));
793 static int eap_teap_encrypt_phase2(struct eap_sm
*sm
,
794 struct eap_teap_data
*data
,
795 struct wpabuf
*plain
, int piggyback
)
799 wpa_hexdump_buf_key(MSG_DEBUG
, "EAP-TEAP: Encrypting Phase 2 TLVs",
801 encr
= eap_server_tls_encrypt(sm
, &data
->ssl
, plain
);
807 if (data
->ssl
.tls_out
&& piggyback
) {
808 wpa_printf(MSG_DEBUG
,
809 "EAP-TEAP: Piggyback Phase 2 data (len=%d) with last Phase 1 Message (len=%d used=%d)",
810 (int) wpabuf_len(encr
),
811 (int) wpabuf_len(data
->ssl
.tls_out
),
812 (int) data
->ssl
.tls_out_pos
);
813 if (wpabuf_resize(&data
->ssl
.tls_out
, wpabuf_len(encr
)) < 0) {
814 wpa_printf(MSG_WARNING
,
815 "EAP-TEAP: Failed to resize output buffer");
819 wpabuf_put_buf(data
->ssl
.tls_out
, encr
);
822 wpabuf_free(data
->ssl
.tls_out
);
823 data
->ssl
.tls_out_pos
= 0;
824 data
->ssl
.tls_out
= encr
;
831 static struct wpabuf
* eap_teap_buildReq(struct eap_sm
*sm
, void *priv
, u8 id
)
833 struct eap_teap_data
*data
= priv
;
834 struct wpabuf
*req
= NULL
;
837 if (data
->ssl
.state
== FRAG_ACK
) {
838 return eap_server_tls_build_ack(id
, EAP_TYPE_TEAP
,
842 if (data
->ssl
.state
== WAIT_FRAG_ACK
) {
843 return eap_server_tls_build_msg(&data
->ssl
, EAP_TYPE_TEAP
,
844 data
->teap_version
, id
);
847 switch (data
->state
) {
849 return eap_teap_build_start(sm
, data
, id
);
851 if (tls_connection_established(sm
->cfg
->ssl_ctx
,
853 if (eap_teap_phase1_done(sm
, data
) < 0)
855 if (data
->state
== PHASE2_START
) {
859 * Try to generate Phase 2 data to piggyback
860 * with the end of Phase 1 to avoid extra
863 wpa_printf(MSG_DEBUG
,
864 "EAP-TEAP: Try to start Phase 2");
865 res
= eap_teap_process_phase2_start(sm
, data
);
867 req
= eap_teap_build_crypto_binding(
875 req
= eap_teap_build_phase2_req(sm
, data
, id
);
881 case PHASE2_BASIC_AUTH
:
883 req
= eap_teap_build_phase2_req(sm
, data
, id
);
886 req
= eap_teap_build_crypto_binding(sm
, data
);
887 if (data
->phase2_method
) {
889 * Include the start of the next EAP method in the
890 * sequence in the same message with Crypto-Binding to
895 eap
= eap_teap_build_phase2_req(sm
, data
, id
);
896 req
= wpabuf_concat(req
, eap
);
897 eap_teap_state(data
, PHASE2_METHOD
);
901 req
= eap_teap_build_pac(sm
, data
);
903 case FAILURE_SEND_RESULT
:
904 req
= eap_teap_tlv_result(TEAP_STATUS_FAILURE
, 0);
905 if (data
->error_code
)
907 req
, eap_teap_tlv_error(data
->error_code
));
909 case SUCCESS_SEND_RESULT
:
910 req
= eap_teap_tlv_result(TEAP_STATUS_SUCCESS
, 0);
911 data
->final_result
= 1;
914 wpa_printf(MSG_DEBUG
, "EAP-TEAP: %s - unexpected state %d",
915 __func__
, data
->state
);
919 if (req
&& eap_teap_encrypt_phase2(sm
, data
, req
, piggyback
) < 0)
922 return eap_server_tls_build_msg(&data
->ssl
, EAP_TYPE_TEAP
,
923 data
->teap_version
, id
);
927 static Boolean
eap_teap_check(struct eap_sm
*sm
, void *priv
,
928 struct wpabuf
*respData
)
933 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_TEAP
, respData
, &len
);
934 if (!pos
|| len
< 1) {
935 wpa_printf(MSG_INFO
, "EAP-TEAP: Invalid frame");
943 static int eap_teap_phase2_init(struct eap_sm
*sm
, struct eap_teap_data
*data
,
944 int vendor
, enum eap_type eap_type
)
946 if (data
->phase2_priv
&& data
->phase2_method
) {
947 data
->phase2_method
->reset(sm
, data
->phase2_priv
);
948 data
->phase2_method
= NULL
;
949 data
->phase2_priv
= NULL
;
951 data
->phase2_method
= eap_server_get_eap_method(vendor
, eap_type
);
952 if (!data
->phase2_method
)
956 data
->phase2_priv
= data
->phase2_method
->init(sm
);
959 return data
->phase2_priv
? 0 : -1;
963 static void eap_teap_process_phase2_response(struct eap_sm
*sm
,
964 struct eap_teap_data
*data
,
965 u8
*in_data
, size_t in_len
)
967 int next_vendor
= EAP_VENDOR_IETF
;
968 enum eap_type next_type
= EAP_TYPE_NONE
;
973 const struct eap_method
*m
= data
->phase2_method
;
974 void *priv
= data
->phase2_priv
;
977 wpa_printf(MSG_DEBUG
,
978 "EAP-TEAP: %s - Phase 2 not initialized?!",
983 hdr
= (struct eap_hdr
*) in_data
;
984 pos
= (u8
*) (hdr
+ 1);
986 if (in_len
> sizeof(*hdr
) && *pos
== EAP_TYPE_NAK
) {
987 left
= in_len
- sizeof(*hdr
);
988 wpa_hexdump(MSG_DEBUG
,
989 "EAP-TEAP: Phase 2 type Nak'ed; allowed types",
991 #ifdef EAP_SERVER_TNC
992 if (m
&& m
->vendor
== EAP_VENDOR_IETF
&&
993 m
->method
== EAP_TYPE_TNC
) {
994 wpa_printf(MSG_DEBUG
,
995 "EAP-TEAP: Peer Nak'ed required TNC negotiation");
996 next_vendor
= EAP_VENDOR_IETF
;
997 next_type
= eap_teap_req_failure(data
, 0);
998 eap_teap_phase2_init(sm
, data
, next_vendor
, next_type
);
1001 #endif /* EAP_SERVER_TNC */
1002 eap_sm_process_nak(sm
, pos
+ 1, left
- 1);
1003 if (sm
->user
&& sm
->user_eap_method_index
< EAP_MAX_METHODS
&&
1004 sm
->user
->methods
[sm
->user_eap_method_index
].method
!=
1006 next_vendor
= sm
->user
->methods
[
1007 sm
->user_eap_method_index
].vendor
;
1008 next_type
= sm
->user
->methods
[
1009 sm
->user_eap_method_index
++].method
;
1010 wpa_printf(MSG_DEBUG
, "EAP-TEAP: try EAP type %u:%u",
1011 next_vendor
, next_type
);
1013 next_vendor
= EAP_VENDOR_IETF
;
1014 next_type
= eap_teap_req_failure(data
, 0);
1016 eap_teap_phase2_init(sm
, data
, next_vendor
, next_type
);
1020 wpabuf_set(&buf
, in_data
, in_len
);
1022 if (m
->check(sm
, priv
, &buf
)) {
1023 wpa_printf(MSG_DEBUG
,
1024 "EAP-TEAP: Phase 2 check() asked to ignore the packet");
1025 eap_teap_req_failure(data
, TEAP_ERROR_INNER_METHOD
);
1029 m
->process(sm
, priv
, &buf
);
1031 if (!m
->isDone(sm
, priv
))
1034 if (!m
->isSuccess(sm
, priv
)) {
1035 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Phase 2 method failed");
1036 next_vendor
= EAP_VENDOR_IETF
;
1037 next_type
= eap_teap_req_failure(data
, TEAP_ERROR_INNER_METHOD
);
1038 eap_teap_phase2_init(sm
, data
, next_vendor
, next_type
);
1042 switch (data
->state
) {
1044 if (eap_user_get(sm
, sm
->identity
, sm
->identity_len
, 1) != 0) {
1045 wpa_hexdump_ascii(MSG_DEBUG
,
1046 "EAP-TEAP: Phase 2 Identity not found in the user database",
1047 sm
->identity
, sm
->identity_len
);
1048 next_vendor
= EAP_VENDOR_IETF
;
1049 next_type
= eap_teap_req_failure(
1050 data
, TEAP_ERROR_INNER_METHOD
);
1054 eap_teap_state(data
, PHASE2_METHOD
);
1055 if (data
->anon_provisioning
) {
1056 /* TODO: Allow any inner EAP method that provides
1057 * mutual authentication and EMSK derivation (i.e.,
1058 * EAP-pwd or EAP-EKE). */
1059 next_vendor
= EAP_VENDOR_IETF
;
1060 next_type
= EAP_TYPE_PWD
;
1061 sm
->user_eap_method_index
= 0;
1063 next_vendor
= sm
->user
->methods
[0].vendor
;
1064 next_type
= sm
->user
->methods
[0].method
;
1065 sm
->user_eap_method_index
= 1;
1067 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Try EAP type %u:%u",
1068 next_vendor
, next_type
);
1071 case CRYPTO_BINDING
:
1072 eap_teap_update_icmk(sm
, data
);
1073 eap_teap_state(data
, CRYPTO_BINDING
);
1075 next_vendor
= EAP_VENDOR_IETF
;
1076 next_type
= EAP_TYPE_NONE
;
1077 #ifdef EAP_SERVER_TNC
1078 if (sm
->cfg
->tnc
&& !data
->tnc_started
) {
1079 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Initialize TNC");
1080 next_vendor
= EAP_VENDOR_IETF
;
1081 next_type
= EAP_TYPE_TNC
;
1082 data
->tnc_started
= 1;
1084 #endif /* EAP_SERVER_TNC */
1089 wpa_printf(MSG_DEBUG
, "EAP-TEAP: %s - unexpected state %d",
1090 __func__
, data
->state
);
1094 eap_teap_phase2_init(sm
, data
, next_vendor
, next_type
);
1098 static void eap_teap_process_phase2_eap(struct eap_sm
*sm
,
1099 struct eap_teap_data
*data
,
1100 u8
*in_data
, size_t in_len
)
1102 struct eap_hdr
*hdr
;
1105 hdr
= (struct eap_hdr
*) in_data
;
1106 if (in_len
< (int) sizeof(*hdr
)) {
1107 wpa_printf(MSG_INFO
,
1108 "EAP-TEAP: Too short Phase 2 EAP frame (len=%lu)",
1109 (unsigned long) in_len
);
1110 eap_teap_req_failure(data
, TEAP_ERROR_INNER_METHOD
);
1113 len
= be_to_host16(hdr
->length
);
1115 wpa_printf(MSG_INFO
,
1116 "EAP-TEAP: Length mismatch in Phase 2 EAP frame (len=%lu hdr->length=%lu)",
1117 (unsigned long) in_len
, (unsigned long) len
);
1118 eap_teap_req_failure(data
, TEAP_ERROR_INNER_METHOD
);
1121 wpa_printf(MSG_DEBUG
,
1122 "EAP-TEAP: Received Phase 2: code=%d identifier=%d length=%lu",
1123 hdr
->code
, hdr
->identifier
,
1124 (unsigned long) len
);
1125 switch (hdr
->code
) {
1126 case EAP_CODE_RESPONSE
:
1127 eap_teap_process_phase2_response(sm
, data
, (u8
*) hdr
, len
);
1130 wpa_printf(MSG_INFO
,
1131 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
1138 static void eap_teap_process_basic_auth_resp(struct eap_sm
*sm
,
1139 struct eap_teap_data
*data
,
1140 u8
*in_data
, size_t in_len
)
1142 u8
*pos
, *end
, *username
, *password
, *new_id
;
1143 u8 userlen
, passlen
;
1148 if (end
- pos
< 1) {
1149 wpa_printf(MSG_DEBUG
,
1150 "EAP-TEAP: No room for Basic-Password-Auth-Resp Userlen field");
1151 eap_teap_req_failure(data
, 0);
1155 if (end
- pos
< userlen
) {
1156 wpa_printf(MSG_DEBUG
,
1157 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Username field");
1158 eap_teap_req_failure(data
, 0);
1163 wpa_hexdump_ascii(MSG_DEBUG
,
1164 "EAP-TEAP: Basic-Password-Auth-Resp Username",
1167 if (end
- pos
< 1) {
1168 wpa_printf(MSG_DEBUG
,
1169 "EAP-TEAP: No room for Basic-Password-Auth-Resp Passlen field");
1170 eap_teap_req_failure(data
, 0);
1174 if (end
- pos
< passlen
) {
1175 wpa_printf(MSG_DEBUG
,
1176 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Password field");
1177 eap_teap_req_failure(data
, 0);
1182 wpa_hexdump_ascii_key(MSG_DEBUG
,
1183 "EAP-TEAP: Basic-Password-Auth-Resp Password",
1187 wpa_printf(MSG_DEBUG
,
1188 "EAP-TEAP: Unexpected %d extra octet(s) at the end of Basic-Password-Auth-Resp TLV",
1190 eap_teap_req_failure(data
, 0);
1194 if (eap_user_get(sm
, username
, userlen
, 1) != 0) {
1195 wpa_printf(MSG_DEBUG
,
1196 "EAP-TEAP: Username not found in the user database");
1197 eap_teap_req_failure(data
, 0);
1201 if (!sm
->user
|| !sm
->user
->password
|| sm
->user
->password_hash
) {
1202 wpa_printf(MSG_DEBUG
,
1203 "EAP-TEAP: No plaintext user password configured");
1204 eap_teap_req_failure(data
, 0);
1208 if (sm
->user
->password_len
!= passlen
||
1209 os_memcmp_const(sm
->user
->password
, password
, passlen
) != 0) {
1210 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Invalid password");
1211 eap_teap_req_failure(data
, 0);
1215 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Correct password");
1216 new_id
= os_memdup(username
, userlen
);
1218 os_free(sm
->identity
);
1219 sm
->identity
= new_id
;
1220 sm
->identity_len
= userlen
;
1222 eap_teap_state(data
, CRYPTO_BINDING
);
1223 eap_teap_update_icmk(sm
, data
);
1227 static int eap_teap_parse_tlvs(struct wpabuf
*data
,
1228 struct eap_teap_tlv_parse
*tlv
)
1235 os_memset(tlv
, 0, sizeof(*tlv
));
1237 pos
= wpabuf_mhead(data
);
1238 end
= pos
+ wpabuf_len(data
);
1239 while (end
- pos
> 4) {
1240 mandatory
= pos
[0] & 0x80;
1241 tlv_type
= WPA_GET_BE16(pos
) & 0x3fff;
1243 len
= WPA_GET_BE16(pos
);
1245 if (len
> (size_t) (end
- pos
)) {
1246 wpa_printf(MSG_INFO
, "EAP-TEAP: TLV overflow");
1249 wpa_printf(MSG_DEBUG
,
1250 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1251 tlv_type
, eap_teap_tlv_type_str(tlv_type
),
1253 mandatory
? " (mandatory)" : "");
1255 res
= eap_teap_parse_tlv(tlv
, tlv_type
, pos
, len
);
1260 wpa_printf(MSG_DEBUG
,
1261 "EAP-TEAP: NAK unknown mandatory TLV type %u",
1263 /* TODO: generate NAK TLV */
1267 wpa_printf(MSG_DEBUG
,
1268 "EAP-TEAP: Ignore unknown optional TLV type %u",
1279 static int eap_teap_validate_crypto_binding(
1280 struct eap_teap_data
*data
, const struct teap_tlv_crypto_binding
*cb
,
1285 subtype
= cb
->subtype
& 0x0f;
1286 flags
= cb
->subtype
>> 4;
1288 wpa_printf(MSG_DEBUG
,
1289 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
1290 cb
->version
, cb
->received_version
, flags
, subtype
);
1291 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Nonce",
1292 cb
->nonce
, sizeof(cb
->nonce
));
1293 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: EMSK Compound MAC",
1294 cb
->emsk_compound_mac
, sizeof(cb
->emsk_compound_mac
));
1295 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: MSK Compound MAC",
1296 cb
->msk_compound_mac
, sizeof(cb
->msk_compound_mac
));
1298 if (cb
->version
!= EAP_TEAP_VERSION
||
1299 cb
->received_version
!= data
->peer_version
) {
1300 wpa_printf(MSG_DEBUG
,
1301 "EAP-TEAP: Unexpected version in Crypto-Binding: Version %u Received Version %u",
1302 cb
->version
, cb
->received_version
);
1306 if (flags
< 1 || flags
> 3) {
1307 wpa_printf(MSG_DEBUG
,
1308 "EAP-TEAP: Unexpected Flags in Crypto-Binding: %u",
1313 if (subtype
!= TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE
) {
1314 wpa_printf(MSG_DEBUG
,
1315 "EAP-TEAP: Unexpected Sub-Type in Crypto-Binding: %u",
1320 if (os_memcmp_const(data
->crypto_binding_nonce
, cb
->nonce
,
1321 EAP_TEAP_NONCE_LEN
- 1) != 0 ||
1322 (data
->crypto_binding_nonce
[EAP_TEAP_NONCE_LEN
- 1] | 1) !=
1323 cb
->nonce
[EAP_TEAP_NONCE_LEN
- 1]) {
1324 wpa_printf(MSG_DEBUG
,
1325 "EAP-TEAP: Invalid Nonce in Crypto-Binding");
1329 if (flags
== TEAP_CRYPTO_BINDING_MSK_CMAC
||
1330 flags
== TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC
) {
1331 u8 msk_compound_mac
[EAP_TEAP_COMPOUND_MAC_LEN
];
1333 if (eap_teap_compound_mac(data
->tls_cs
, cb
,
1334 data
->server_outer_tlvs
,
1335 data
->peer_outer_tlvs
, data
->cmk_msk
,
1336 msk_compound_mac
) < 0)
1338 if (os_memcmp_const(msk_compound_mac
, cb
->msk_compound_mac
,
1339 EAP_TEAP_COMPOUND_MAC_LEN
) != 0) {
1340 wpa_hexdump(MSG_DEBUG
,
1341 "EAP-TEAP: Calculated MSK Compound MAC",
1343 EAP_TEAP_COMPOUND_MAC_LEN
);
1344 wpa_printf(MSG_INFO
,
1345 "EAP-TEAP: MSK Compound MAC did not match");
1350 if ((flags
== TEAP_CRYPTO_BINDING_EMSK_CMAC
||
1351 flags
== TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC
) &&
1352 data
->cmk_emsk_available
) {
1353 u8 emsk_compound_mac
[EAP_TEAP_COMPOUND_MAC_LEN
];
1355 if (eap_teap_compound_mac(data
->tls_cs
, cb
,
1356 data
->server_outer_tlvs
,
1357 data
->peer_outer_tlvs
, data
->cmk_emsk
,
1358 emsk_compound_mac
) < 0)
1360 if (os_memcmp_const(emsk_compound_mac
, cb
->emsk_compound_mac
,
1361 EAP_TEAP_COMPOUND_MAC_LEN
) != 0) {
1362 wpa_hexdump(MSG_DEBUG
,
1363 "EAP-TEAP: Calculated EMSK Compound MAC",
1365 EAP_TEAP_COMPOUND_MAC_LEN
);
1366 wpa_printf(MSG_INFO
,
1367 "EAP-TEAP: EMSK Compound MAC did not match");
1372 if (flags
== TEAP_CRYPTO_BINDING_EMSK_CMAC
&&
1373 !data
->cmk_emsk_available
) {
1374 wpa_printf(MSG_INFO
,
1375 "EAP-TEAP: Peer included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
1383 static int eap_teap_pac_type(u8
*pac
, size_t len
, u16 type
)
1385 struct teap_attr_pac_type
*tlv
;
1387 if (!pac
|| len
!= sizeof(*tlv
))
1390 tlv
= (struct teap_attr_pac_type
*) pac
;
1392 return be_to_host16(tlv
->type
) == PAC_TYPE_PAC_TYPE
&&
1393 be_to_host16(tlv
->length
) == 2 &&
1394 be_to_host16(tlv
->pac_type
) == type
;
1398 static void eap_teap_process_phase2_tlvs(struct eap_sm
*sm
,
1399 struct eap_teap_data
*data
,
1400 struct wpabuf
*in_data
)
1402 struct eap_teap_tlv_parse tlv
;
1403 int check_crypto_binding
= data
->state
== CRYPTO_BINDING
;
1405 if (eap_teap_parse_tlvs(in_data
, &tlv
) < 0) {
1406 wpa_printf(MSG_DEBUG
,
1407 "EAP-TEAP: Failed to parse received Phase 2 TLVs");
1411 if (tlv
.result
== TEAP_STATUS_FAILURE
) {
1412 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Result TLV indicated failure");
1413 eap_teap_state(data
, FAILURE
);
1418 wpa_printf(MSG_DEBUG
,
1419 "EAP-TEAP: Peer NAK'ed Vendor-Id %u NAK-Type %u",
1420 WPA_GET_BE32(tlv
.nak
), WPA_GET_BE16(tlv
.nak
+ 4));
1421 eap_teap_state(data
, FAILURE_SEND_RESULT
);
1425 if (data
->state
== REQUEST_PAC
) {
1428 if (!tlv
.pac
|| tlv
.pac_len
< 6) {
1429 wpa_printf(MSG_DEBUG
,
1430 "EAP-TEAP: No PAC Acknowledgement received");
1431 eap_teap_state(data
, FAILURE
);
1435 type
= WPA_GET_BE16(tlv
.pac
);
1436 len
= WPA_GET_BE16(tlv
.pac
+ 2);
1437 res
= WPA_GET_BE16(tlv
.pac
+ 4);
1439 if (type
!= PAC_TYPE_PAC_ACKNOWLEDGEMENT
|| len
!= 2 ||
1440 res
!= TEAP_STATUS_SUCCESS
) {
1441 wpa_printf(MSG_DEBUG
,
1442 "EAP-TEAP: PAC TLV did not contain acknowledgement");
1443 eap_teap_state(data
, FAILURE
);
1447 wpa_printf(MSG_DEBUG
,
1448 "EAP-TEAP: PAC-Acknowledgement received - PAC provisioning succeeded");
1449 eap_teap_state(data
, SUCCESS
);
1453 if (check_crypto_binding
) {
1454 if (!tlv
.crypto_binding
) {
1455 wpa_printf(MSG_DEBUG
,
1456 "EAP-TEAP: No Crypto-Binding TLV received");
1457 eap_teap_state(data
, FAILURE
);
1461 if (data
->final_result
&&
1462 tlv
.result
!= TEAP_STATUS_SUCCESS
) {
1463 wpa_printf(MSG_DEBUG
,
1464 "EAP-TEAP: Crypto-Binding TLV without Success Result");
1465 eap_teap_state(data
, FAILURE
);
1469 if (sm
->cfg
->eap_teap_auth
!= 1 &&
1470 tlv
.iresult
!= TEAP_STATUS_SUCCESS
) {
1471 wpa_printf(MSG_DEBUG
,
1472 "EAP-TEAP: Crypto-Binding TLV without intermediate Success Result");
1473 eap_teap_state(data
, FAILURE
);
1477 if (eap_teap_validate_crypto_binding(data
, tlv
.crypto_binding
,
1478 tlv
.crypto_binding_len
)) {
1479 eap_teap_state(data
, FAILURE
);
1483 wpa_printf(MSG_DEBUG
,
1484 "EAP-TEAP: Valid Crypto-Binding TLV received");
1485 if (data
->final_result
) {
1486 wpa_printf(MSG_DEBUG
,
1487 "EAP-TEAP: Authentication completed successfully");
1490 if (data
->anon_provisioning
&&
1491 sm
->cfg
->eap_fast_prov
!= ANON_PROV
&&
1492 sm
->cfg
->eap_fast_prov
!= BOTH_PROV
) {
1493 wpa_printf(MSG_DEBUG
,
1494 "EAP-TEAP: Client is trying to use unauthenticated provisioning which is disabled");
1495 eap_teap_state(data
, FAILURE
);
1499 if (sm
->cfg
->eap_fast_prov
!= AUTH_PROV
&&
1500 sm
->cfg
->eap_fast_prov
!= BOTH_PROV
&&
1501 tlv
.request_action
== TEAP_REQUEST_ACTION_PROCESS_TLV
&&
1502 eap_teap_pac_type(tlv
.pac
, tlv
.pac_len
,
1503 PAC_TYPE_TUNNEL_PAC
)) {
1504 wpa_printf(MSG_DEBUG
,
1505 "EAP-TEAP: Client is trying to use authenticated provisioning which is disabled");
1506 eap_teap_state(data
, FAILURE
);
1510 if (data
->anon_provisioning
||
1511 (tlv
.request_action
== TEAP_REQUEST_ACTION_PROCESS_TLV
&&
1512 eap_teap_pac_type(tlv
.pac
, tlv
.pac_len
,
1513 PAC_TYPE_TUNNEL_PAC
))) {
1514 wpa_printf(MSG_DEBUG
,
1515 "EAP-TEAP: Requested a new Tunnel PAC");
1516 eap_teap_state(data
, REQUEST_PAC
);
1517 } else if (data
->send_new_pac
) {
1518 wpa_printf(MSG_DEBUG
,
1519 "EAP-TEAP: Server triggered re-keying of Tunnel PAC");
1520 eap_teap_state(data
, REQUEST_PAC
);
1521 } else if (data
->final_result
) {
1522 eap_teap_state(data
, SUCCESS
);
1523 } else if (sm
->cfg
->eap_teap_separate_result
) {
1524 eap_teap_state(data
, SUCCESS_SEND_RESULT
);
1528 if (tlv
.basic_auth_resp
) {
1529 if (sm
->cfg
->eap_teap_auth
!= 1) {
1530 wpa_printf(MSG_DEBUG
,
1531 "EAP-TEAP: Unexpected Basic-Password-Auth-Resp when trying to use inner EAP");
1532 eap_teap_state(data
, FAILURE
);
1535 eap_teap_process_basic_auth_resp(sm
, data
, tlv
.basic_auth_resp
,
1536 tlv
.basic_auth_resp_len
);
1539 if (tlv
.eap_payload_tlv
) {
1540 if (sm
->cfg
->eap_teap_auth
== 1) {
1541 wpa_printf(MSG_DEBUG
,
1542 "EAP-TEAP: Unexpected EAP Payload TLV when trying to use Basic-Password-Auth");
1543 eap_teap_state(data
, FAILURE
);
1546 eap_teap_process_phase2_eap(sm
, data
, tlv
.eap_payload_tlv
,
1547 tlv
.eap_payload_tlv_len
);
1550 if (data
->state
== SUCCESS_SEND_RESULT
&&
1551 tlv
.result
== TEAP_STATUS_SUCCESS
) {
1552 wpa_printf(MSG_DEBUG
,
1553 "EAP-TEAP: Peer agreed with final success - authentication completed");
1554 eap_teap_state(data
, SUCCESS
);
1559 static void eap_teap_process_phase2(struct eap_sm
*sm
,
1560 struct eap_teap_data
*data
,
1561 struct wpabuf
*in_buf
)
1563 struct wpabuf
*in_decrypted
;
1565 wpa_printf(MSG_DEBUG
,
1566 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1567 (unsigned long) wpabuf_len(in_buf
));
1569 if (data
->pending_phase2_resp
) {
1570 wpa_printf(MSG_DEBUG
,
1571 "EAP-TEAP: Pending Phase 2 response - skip decryption and use old data");
1572 eap_teap_process_phase2_tlvs(sm
, data
,
1573 data
->pending_phase2_resp
);
1574 wpabuf_free(data
->pending_phase2_resp
);
1575 data
->pending_phase2_resp
= NULL
;
1579 in_decrypted
= tls_connection_decrypt(sm
->cfg
->ssl_ctx
, data
->ssl
.conn
,
1581 if (!in_decrypted
) {
1582 wpa_printf(MSG_INFO
,
1583 "EAP-TEAP: Failed to decrypt Phase 2 data");
1584 eap_teap_state(data
, FAILURE
);
1588 wpa_hexdump_buf_key(MSG_DEBUG
, "EAP-TEAP: Decrypted Phase 2 TLVs",
1591 eap_teap_process_phase2_tlvs(sm
, data
, in_decrypted
);
1593 if (sm
->method_pending
== METHOD_PENDING_WAIT
) {
1594 wpa_printf(MSG_DEBUG
,
1595 "EAP-TEAP: Phase 2 method is in pending wait state - save decrypted response");
1596 wpabuf_free(data
->pending_phase2_resp
);
1597 data
->pending_phase2_resp
= in_decrypted
;
1601 wpabuf_free(in_decrypted
);
1605 static int eap_teap_process_version(struct eap_sm
*sm
, void *priv
,
1608 struct eap_teap_data
*data
= priv
;
1610 if (peer_version
< 1) {
1611 /* Version 1 was the first defined version, so reject 0 */
1612 wpa_printf(MSG_INFO
,
1613 "EAP-TEAP: Peer used unknown TEAP version %u",
1618 if (peer_version
< data
->teap_version
) {
1619 wpa_printf(MSG_DEBUG
, "EAP-TEAP: peer ver=%u, own ver=%u; "
1621 peer_version
, data
->teap_version
, peer_version
);
1622 data
->teap_version
= peer_version
;
1625 data
->peer_version
= peer_version
;
1631 static int eap_teap_process_phase1(struct eap_sm
*sm
,
1632 struct eap_teap_data
*data
)
1634 if (eap_server_tls_phase1(sm
, &data
->ssl
) < 0) {
1635 wpa_printf(MSG_INFO
, "EAP-TEAP: TLS processing failed");
1636 eap_teap_state(data
, FAILURE
);
1640 if (!tls_connection_established(sm
->cfg
->ssl_ctx
, data
->ssl
.conn
) ||
1641 wpabuf_len(data
->ssl
.tls_out
) > 0)
1645 * Phase 1 was completed with the received message (e.g., when using
1646 * abbreviated handshake), so Phase 2 can be started immediately
1647 * without having to send through an empty message to the peer.
1650 return eap_teap_phase1_done(sm
, data
);
1654 static int eap_teap_process_phase2_start(struct eap_sm
*sm
,
1655 struct eap_teap_data
*data
)
1658 enum eap_type next_type
;
1660 if (data
->identity
) {
1661 /* Used PAC and identity is from PAC-Opaque */
1662 os_free(sm
->identity
);
1663 sm
->identity
= data
->identity
;
1664 data
->identity
= NULL
;
1665 sm
->identity_len
= data
->identity_len
;
1666 data
->identity_len
= 0;
1667 if (eap_user_get(sm
, sm
->identity
, sm
->identity_len
, 1) != 0) {
1668 wpa_hexdump_ascii(MSG_DEBUG
,
1669 "EAP-TEAP: Phase 2 Identity not found in the user database",
1670 sm
->identity
, sm
->identity_len
);
1671 next_vendor
= EAP_VENDOR_IETF
;
1672 next_type
= EAP_TYPE_NONE
;
1673 eap_teap_state(data
, PHASE2_METHOD
);
1674 } else if (sm
->cfg
->eap_teap_pac_no_inner
) {
1675 wpa_printf(MSG_DEBUG
,
1676 "EAP-TEAP: Used PAC and identity already known - skip inner auth");
1677 /* FIX: Need to derive CMK here. However, how is that
1678 * supposed to be done? RFC 7170 does not tell that for
1679 * the no-inner-auth case. */
1680 eap_teap_derive_cmk_basic_pw_auth(data
->tls_cs
,
1683 eap_teap_state(data
, CRYPTO_BINDING
);
1685 } else if (sm
->cfg
->eap_teap_auth
== 1) {
1686 eap_teap_state(data
, PHASE2_BASIC_AUTH
);
1689 wpa_printf(MSG_DEBUG
,
1690 "EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
1691 next_vendor
= sm
->user
->methods
[0].vendor
;
1692 next_type
= sm
->user
->methods
[0].method
;
1693 sm
->user_eap_method_index
= 1;
1694 eap_teap_state(data
, PHASE2_METHOD
);
1697 } else if (sm
->cfg
->eap_teap_auth
== 1) {
1698 eap_teap_state(data
, PHASE2_BASIC_AUTH
);
1701 eap_teap_state(data
, PHASE2_ID
);
1702 next_vendor
= EAP_VENDOR_IETF
;
1703 next_type
= EAP_TYPE_IDENTITY
;
1706 return eap_teap_phase2_init(sm
, data
, next_vendor
, next_type
);
1710 static void eap_teap_process_msg(struct eap_sm
*sm
, void *priv
,
1711 const struct wpabuf
*respData
)
1713 struct eap_teap_data
*data
= priv
;
1715 switch (data
->state
) {
1718 if (eap_teap_process_phase1(sm
, data
))
1723 eap_teap_process_phase2_start(sm
, data
);
1726 case PHASE2_BASIC_AUTH
:
1728 case CRYPTO_BINDING
:
1730 case SUCCESS_SEND_RESULT
:
1731 eap_teap_process_phase2(sm
, data
, data
->ssl
.tls_in
);
1733 case FAILURE_SEND_RESULT
:
1734 /* Protected failure result indication completed. Ignore the
1735 * received message (which is supposed to include Result TLV
1736 * indicating failure) and terminate exchange with cleartext
1738 eap_teap_state(data
, FAILURE
);
1741 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Unexpected state %d in %s",
1742 data
->state
, __func__
);
1748 static void eap_teap_process(struct eap_sm
*sm
, void *priv
,
1749 struct wpabuf
*respData
)
1751 struct eap_teap_data
*data
= priv
;
1754 struct wpabuf
*resp
= respData
;
1757 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_TEAP
, respData
, &len
);
1758 if (!pos
|| len
< 1)
1764 if (flags
& EAP_TEAP_FLAGS_OUTER_TLV_LEN
) {
1765 /* Extract Outer TLVs from the message before common TLS
1767 u32 message_len
= 0, outer_tlv_len
;
1770 if (data
->state
!= PHASE1
) {
1771 wpa_printf(MSG_INFO
,
1772 "EAP-TEAP: Unexpected Outer TLVs in a message that is not the first message from the peer");
1776 if (flags
& EAP_TLS_FLAGS_LENGTH_INCLUDED
) {
1778 wpa_printf(MSG_INFO
,
1779 "EAP-TEAP: Too short message to include Message Length field");
1783 message_len
= WPA_GET_BE32(pos
);
1786 if (message_len
< 4) {
1787 wpa_printf(MSG_INFO
,
1788 "EAP-TEAP: Message Length field has too msall value to include Outer TLV Length field");
1794 wpa_printf(MSG_INFO
,
1795 "EAP-TEAP: Too short message to include Outer TLVs Length field");
1799 outer_tlv_len
= WPA_GET_BE32(pos
);
1803 wpa_printf(MSG_DEBUG
,
1804 "EAP-TEAP: Message Length %u Outer TLV Length %u",
1805 message_len
, outer_tlv_len
);
1806 if (len
< outer_tlv_len
) {
1807 wpa_printf(MSG_INFO
,
1808 "EAP-TEAP: Too short message to include Outer TLVs field");
1813 (message_len
< outer_tlv_len
||
1814 message_len
< 4 + outer_tlv_len
)) {
1815 wpa_printf(MSG_INFO
,
1816 "EAP-TEAP: Message Length field has too small value to include Outer TLVs");
1820 if (wpabuf_len(respData
) < 4 + outer_tlv_len
||
1821 len
< outer_tlv_len
)
1823 resp
= wpabuf_alloc(wpabuf_len(respData
) - 4 - outer_tlv_len
);
1826 hdr
= wpabuf_head(respData
);
1827 wpabuf_put_u8(resp
, *hdr
++); /* Code */
1828 wpabuf_put_u8(resp
, *hdr
++); /* Identifier */
1829 wpabuf_put_be16(resp
, WPA_GET_BE16(hdr
) - 4 - outer_tlv_len
);
1831 wpabuf_put_u8(resp
, *hdr
++); /* Type */
1833 wpabuf_put_u8(resp
, flags
& ~EAP_TEAP_FLAGS_OUTER_TLV_LEN
);
1835 if (flags
& EAP_TLS_FLAGS_LENGTH_INCLUDED
)
1836 wpabuf_put_be32(resp
, message_len
- 4 - outer_tlv_len
);
1838 wpabuf_put_data(resp
, pos
, len
- outer_tlv_len
);
1839 pos
+= len
- outer_tlv_len
;
1840 wpabuf_free(data
->peer_outer_tlvs
);
1841 data
->peer_outer_tlvs
= wpabuf_alloc_copy(pos
, outer_tlv_len
);
1842 if (!data
->peer_outer_tlvs
)
1844 wpa_hexdump_buf(MSG_DEBUG
, "EAP-TEAP: Outer TLVs",
1845 data
->peer_outer_tlvs
);
1847 wpa_hexdump_buf(MSG_DEBUG
,
1848 "EAP-TEAP: TLS Data message after Outer TLV removal",
1850 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_TEAP
, resp
,
1852 if (!pos
|| len
< 1) {
1853 wpa_printf(MSG_INFO
,
1854 "EAP-TEAP: Invalid frame after Outer TLV removal");
1859 if (data
->state
== PHASE1
)
1860 eap_teap_state(data
, PHASE1B
);
1862 if (eap_server_tls_process(sm
, &data
->ssl
, resp
, data
,
1863 EAP_TYPE_TEAP
, eap_teap_process_version
,
1864 eap_teap_process_msg
) < 0)
1865 eap_teap_state(data
, FAILURE
);
1867 if (resp
!= respData
)
1872 static Boolean
eap_teap_isDone(struct eap_sm
*sm
, void *priv
)
1874 struct eap_teap_data
*data
= priv
;
1876 return data
->state
== SUCCESS
|| data
->state
== FAILURE
;
1880 static u8
* eap_teap_getKey(struct eap_sm
*sm
, void *priv
, size_t *len
)
1882 struct eap_teap_data
*data
= priv
;
1885 if (data
->state
!= SUCCESS
)
1888 eapKeyData
= os_malloc(EAP_TEAP_KEY_LEN
);
1892 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
1893 * is used in this derivation */
1894 if (eap_teap_derive_eap_msk(data
->tls_cs
, data
->simck_msk
,
1896 os_free(eapKeyData
);
1899 *len
= EAP_TEAP_KEY_LEN
;
1905 static u8
* eap_teap_get_emsk(struct eap_sm
*sm
, void *priv
, size_t *len
)
1907 struct eap_teap_data
*data
= priv
;
1910 if (data
->state
!= SUCCESS
)
1913 eapKeyData
= os_malloc(EAP_EMSK_LEN
);
1917 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
1918 * is used in this derivation */
1919 if (eap_teap_derive_eap_emsk(data
->tls_cs
, data
->simck_msk
,
1921 os_free(eapKeyData
);
1924 *len
= EAP_EMSK_LEN
;
1930 static Boolean
eap_teap_isSuccess(struct eap_sm
*sm
, void *priv
)
1932 struct eap_teap_data
*data
= priv
;
1934 return data
->state
== SUCCESS
;
1938 static u8
* eap_teap_get_session_id(struct eap_sm
*sm
, void *priv
, size_t *len
)
1940 struct eap_teap_data
*data
= priv
;
1941 const size_t max_id_len
= 100;
1945 if (data
->state
!= SUCCESS
)
1948 id
= os_malloc(max_id_len
);
1952 id
[0] = EAP_TYPE_TEAP
;
1953 res
= tls_get_tls_unique(data
->ssl
.conn
, id
+ 1, max_id_len
- 1);
1956 wpa_printf(MSG_ERROR
, "EAP-TEAP: Failed to derive Session-Id");
1961 wpa_hexdump(MSG_DEBUG
, "EAP-TEAP: Derived Session-Id", id
, *len
);
1966 int eap_server_teap_register(void)
1968 struct eap_method
*eap
;
1970 eap
= eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION
,
1971 EAP_VENDOR_IETF
, EAP_TYPE_TEAP
, "TEAP");
1975 eap
->init
= eap_teap_init
;
1976 eap
->reset
= eap_teap_reset
;
1977 eap
->buildReq
= eap_teap_buildReq
;
1978 eap
->check
= eap_teap_check
;
1979 eap
->process
= eap_teap_process
;
1980 eap
->isDone
= eap_teap_isDone
;
1981 eap
->getKey
= eap_teap_getKey
;
1982 eap
->get_emsk
= eap_teap_get_emsk
;
1983 eap
->isSuccess
= eap_teap_isSuccess
;
1984 eap
->getSessionId
= eap_teap_get_session_id
;
1986 return eap_server_method_register(eap
);