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, 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";
113 static void eap_teap_state(struct eap_teap_data *data, int state)
115 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s -> %s",
116 eap_teap_state_txt(data->state),
117 eap_teap_state_txt(state));
122 static EapType eap_teap_req_failure(struct eap_teap_data *data,
123 enum teap_error_codes error)
125 eap_teap_state(data, FAILURE_SEND_RESULT);
126 return EAP_TYPE_NONE;
130 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
131 const u8 *client_random,
132 const u8 *server_random,
135 struct eap_teap_data *data = ctx;
136 const u8 *pac_opaque;
137 size_t pac_opaque_len;
138 u8 *buf, *pos, *end, *pac_key = NULL;
139 os_time_t lifetime = 0;
142 size_t identity_len = 0;
144 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");
145 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket (PAC-Opaque)",
148 if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) {
149 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignore invalid SessionTicket");
153 pac_opaque_len = WPA_GET_BE16(ticket + 2);
154 pac_opaque = ticket + 4;
155 if (pac_opaque_len < 8 || pac_opaque_len % 8 ||
156 pac_opaque_len > len - 4) {
157 wpa_printf(MSG_DEBUG,
158 "EAP-TEAP: Ignore invalid PAC-Opaque (len=%lu left=%lu)",
159 (unsigned long) pac_opaque_len,
160 (unsigned long) len);
163 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Received PAC-Opaque",
164 pac_opaque, pac_opaque_len);
166 buf = os_malloc(pac_opaque_len - 8);
168 wpa_printf(MSG_DEBUG,
169 "EAP-TEAP: Failed to allocate memory for decrypting PAC-Opaque");
173 if (aes_unwrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
174 (pac_opaque_len - 8) / 8, pac_opaque, buf) < 0) {
175 wpa_printf(MSG_DEBUG, "EAP-TEAP: Failed to decrypt PAC-Opaque");
178 * This may have been caused by server changing the PAC-Opaque
179 * encryption key, so just ignore this PAC-Opaque instead of
180 * failing the authentication completely. Provisioning can now
181 * be used to provision a new PAC.
186 end = buf + pac_opaque_len - 8;
187 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Decrypted PAC-Opaque",
191 while (end - pos > 1) {
196 if (elen > end - pos)
200 case PAC_OPAQUE_TYPE_PAD:
202 case PAC_OPAQUE_TYPE_KEY:
203 if (elen != EAP_TEAP_PAC_KEY_LEN) {
204 wpa_printf(MSG_DEBUG,
205 "EAP-TEAP: Invalid PAC-Key length %d",
211 wpa_hexdump_key(MSG_DEBUG,
212 "EAP-TEAP: PAC-Key from decrypted PAC-Opaque",
213 pac_key, EAP_TEAP_PAC_KEY_LEN);
215 case PAC_OPAQUE_TYPE_LIFETIME:
217 wpa_printf(MSG_DEBUG,
218 "EAP-TEAP: Invalid PAC-Key lifetime length %d",
223 lifetime = WPA_GET_BE32(pos);
225 case PAC_OPAQUE_TYPE_IDENTITY:
236 wpa_printf(MSG_DEBUG,
237 "EAP-TEAP: No PAC-Key included in PAC-Opaque");
243 wpa_hexdump_ascii(MSG_DEBUG,
244 "EAP-TEAP: Identity from PAC-Opaque",
245 identity, identity_len);
246 os_free(data->identity);
247 data->identity = os_malloc(identity_len);
248 if (data->identity) {
249 os_memcpy(data->identity, identity, identity_len);
250 data->identity_len = identity_len;
254 if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) {
255 wpa_printf(MSG_DEBUG,
256 "EAP-TEAP: PAC-Key not valid anymore (lifetime=%ld now=%ld)",
258 data->send_new_pac = 2;
260 * Allow PAC to be used to allow a PAC update with some level
261 * of server authentication (i.e., do not fall back to full TLS
262 * handshake since we cannot be sure that the peer would be
263 * able to validate server certificate now). However, reject
264 * the authentication since the PAC was not valid anymore. Peer
265 * can connect again with the newly provisioned PAC after this.
267 } else if (lifetime - now.sec < data->pac_key_refresh_time) {
268 wpa_printf(MSG_DEBUG,
269 "EAP-TEAP: PAC-Key soft timeout; send an update if authentication succeeds");
270 data->send_new_pac = 1;
273 /* EAP-TEAP uses PAC-Key as the TLS master_secret */
274 os_memcpy(master_secret, pac_key, EAP_TEAP_PAC_KEY_LEN);
282 static int eap_teap_derive_key_auth(struct eap_sm *sm,
283 struct eap_teap_data *data)
287 /* RFC 7170, Section 5.1 */
288 res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn,
289 TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
290 data->simck_msk, EAP_TEAP_SIMCK_LEN);
293 wpa_hexdump_key(MSG_DEBUG,
294 "EAP-TEAP: session_key_seed (S-IMCK[0])",
295 data->simck_msk, EAP_TEAP_SIMCK_LEN);
296 os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN);
302 static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data)
304 u8 *msk = NULL, *emsk = NULL;
305 size_t msk_len = 0, emsk_len = 0;
308 wpa_printf(MSG_DEBUG, "EAP-TEAP: Deriving ICMK[%d] (S-IMCK and CMK)",
309 data->simck_idx + 1);
311 if (sm->eap_teap_auth == 1)
312 return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk,
315 if (!data->phase2_method || !data->phase2_priv) {
316 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
320 if (data->phase2_method->getKey) {
321 msk = data->phase2_method->getKey(sm, data->phase2_priv,
325 "EAP-TEAP: Could not fetch Phase 2 MSK");
330 if (data->phase2_method->get_emsk) {
331 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
335 res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk,
336 msk, msk_len, emsk, emsk_len,
337 data->simck_msk, data->cmk_msk,
338 data->simck_emsk, data->cmk_emsk);
339 bin_clear_free(msk, msk_len);
340 bin_clear_free(emsk, emsk_len);
344 data->cmk_emsk_available = 1;
350 static void * eap_teap_init(struct eap_sm *sm)
352 struct eap_teap_data *data;
354 data = os_zalloc(sizeof(*data));
357 data->teap_version = EAP_TEAP_VERSION;
360 if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TEAP)) {
361 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL.");
362 eap_teap_reset(sm, data);
366 /* TODO: Add anon-DH TLS cipher suites (and if one is negotiated,
367 * enforce inner EAP with mutual authentication to be used) */
369 if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
370 eap_teap_session_ticket_cb,
373 "EAP-TEAP: Failed to set SessionTicket callback");
374 eap_teap_reset(sm, data);
378 if (!sm->pac_opaque_encr_key) {
380 "EAP-TEAP: No PAC-Opaque encryption key configured");
381 eap_teap_reset(sm, data);
384 os_memcpy(data->pac_opaque_encr, sm->pac_opaque_encr_key,
385 sizeof(data->pac_opaque_encr));
387 if (!sm->eap_fast_a_id) {
388 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID configured");
389 eap_teap_reset(sm, data);
392 data->srv_id = os_malloc(sm->eap_fast_a_id_len);
394 eap_teap_reset(sm, data);
397 os_memcpy(data->srv_id, sm->eap_fast_a_id, sm->eap_fast_a_id_len);
398 data->srv_id_len = sm->eap_fast_a_id_len;
400 if (!sm->eap_fast_a_id_info) {
401 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID-Info configured");
402 eap_teap_reset(sm, data);
405 data->srv_id_info = os_strdup(sm->eap_fast_a_id_info);
406 if (!data->srv_id_info) {
407 eap_teap_reset(sm, data);
411 /* PAC-Key lifetime in seconds (hard limit) */
412 data->pac_key_lifetime = sm->pac_key_lifetime;
415 * PAC-Key refresh time in seconds (soft limit on remaining hard
416 * limit). The server will generate a new PAC-Key when this number of
417 * seconds (or fewer) of the lifetime remains.
419 data->pac_key_refresh_time = sm->pac_key_refresh_time;
425 static void eap_teap_reset(struct eap_sm *sm, void *priv)
427 struct eap_teap_data *data = priv;
431 if (data->phase2_priv && data->phase2_method)
432 data->phase2_method->reset(sm, data->phase2_priv);
433 eap_server_tls_ssl_deinit(sm, &data->ssl);
434 os_free(data->srv_id);
435 os_free(data->srv_id_info);
436 wpabuf_free(data->pending_phase2_resp);
437 wpabuf_free(data->server_outer_tlvs);
438 wpabuf_free(data->peer_outer_tlvs);
439 os_free(data->identity);
440 forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
441 forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
442 forced_memzero(data->cmk_msk, EAP_TEAP_CMK_LEN);
443 forced_memzero(data->cmk_emsk, EAP_TEAP_CMK_LEN);
444 forced_memzero(data->pac_opaque_encr, sizeof(data->pac_opaque_encr));
445 bin_clear_free(data, sizeof(*data));
449 static struct wpabuf * eap_teap_build_start(struct eap_sm *sm,
450 struct eap_teap_data *data, u8 id)
453 size_t outer_tlv_len = sizeof(struct teap_tlv_hdr) + data->srv_id_len;
454 const u8 *start, *end;
456 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TEAP,
457 1 + 4 + outer_tlv_len, EAP_CODE_REQUEST, id);
459 wpa_printf(MSG_ERROR,
460 "EAP-TEAP: Failed to allocate memory for request");
461 eap_teap_state(data, FAILURE);
465 wpabuf_put_u8(req, EAP_TLS_FLAGS_START | EAP_TEAP_FLAGS_OUTER_TLV_LEN |
467 wpabuf_put_be32(req, outer_tlv_len);
469 start = wpabuf_put(req, 0);
471 /* RFC 7170, Section 4.2.2: Authority-ID TLV */
472 eap_teap_put_tlv(req, TEAP_TLV_AUTHORITY_ID,
473 data->srv_id, data->srv_id_len);
475 end = wpabuf_put(req, 0);
476 wpabuf_free(data->server_outer_tlvs);
477 data->server_outer_tlvs = wpabuf_alloc_copy(start, end - start);
478 if (!data->server_outer_tlvs) {
479 eap_teap_state(data, FAILURE);
483 eap_teap_state(data, PHASE1);
489 static int eap_teap_phase1_done(struct eap_sm *sm, struct eap_teap_data *data)
493 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2");
495 data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn);
496 wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x",
499 if (tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher))
501 wpa_printf(MSG_DEBUG,
502 "EAP-TEAP: Failed to get cipher information");
503 eap_teap_state(data, FAILURE);
506 data->anon_provisioning = os_strstr(cipher, "ADH") != NULL;
508 if (data->anon_provisioning)
509 wpa_printf(MSG_DEBUG, "EAP-TEAP: Anonymous provisioning");
511 if (eap_teap_derive_key_auth(sm, data) < 0) {
512 eap_teap_state(data, FAILURE);
516 eap_teap_state(data, PHASE2_START);
522 static struct wpabuf * eap_teap_build_phase2_req(struct eap_sm *sm,
523 struct eap_teap_data *data,
528 if (sm->eap_teap_auth == 1) {
529 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate Basic-Password-Auth");
530 req = wpabuf_alloc(sizeof(struct teap_tlv_hdr));
533 eap_teap_put_tlv_hdr(req, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ, 0);
537 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate inner EAP method");
538 if (!data->phase2_priv) {
539 wpa_printf(MSG_DEBUG,
540 "EAP-TEAP: Phase 2 method not initialized");
544 req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
548 wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-TEAP: Phase 2 EAP-Request", req);
549 return eap_teap_tlv_eap_payload(req);
553 static struct wpabuf * eap_teap_build_crypto_binding(
554 struct eap_sm *sm, struct eap_teap_data *data)
557 struct teap_tlv_result *result;
558 struct teap_tlv_crypto_binding *cb;
561 buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*cb));
565 if (data->send_new_pac || data->anon_provisioning ||
567 data->final_result = 0;
569 data->final_result = 1;
571 if (!data->final_result || data->eap_seq > 0) {
572 /* Intermediate-Result */
573 wpa_printf(MSG_DEBUG,
574 "EAP-TEAP: Add Intermediate-Result TLV (status=SUCCESS)");
575 result = wpabuf_put(buf, sizeof(*result));
576 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
577 TEAP_TLV_INTERMEDIATE_RESULT);
578 result->length = host_to_be16(2);
579 result->status = host_to_be16(TEAP_STATUS_SUCCESS);
582 if (data->final_result) {
584 wpa_printf(MSG_DEBUG,
585 "EAP-TEAP: Add Result TLV (status=SUCCESS)");
586 result = wpabuf_put(buf, sizeof(*result));
587 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
589 result->length = host_to_be16(2);
590 result->status = host_to_be16(TEAP_STATUS_SUCCESS);
593 /* Crypto-Binding TLV */
594 cb = wpabuf_put(buf, sizeof(*cb));
595 cb->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
596 TEAP_TLV_CRYPTO_BINDING);
597 cb->length = host_to_be16(sizeof(*cb) - sizeof(struct teap_tlv_hdr));
598 cb->version = EAP_TEAP_VERSION;
599 cb->received_version = data->peer_version;
600 /* FIX: RFC 7170 is not clear on which Flags value to use when
601 * Crypto-Binding TLV is used with Basic-Password-Auth */
602 flags = data->cmk_emsk_available ?
603 TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
604 TEAP_CRYPTO_BINDING_MSK_CMAC;
605 subtype = TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST;
606 cb->subtype = (flags << 4) | subtype;
607 if (random_get_bytes(cb->nonce, sizeof(cb->nonce)) < 0) {
613 * RFC 7170, Section 4.2.13:
614 * The nonce in a request MUST have its least significant bit set to 0.
616 cb->nonce[sizeof(cb->nonce) - 1] &= ~0x01;
618 os_memcpy(data->crypto_binding_nonce, cb->nonce, sizeof(cb->nonce));
620 if (eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
621 data->peer_outer_tlvs, data->cmk_msk,
622 cb->msk_compound_mac) < 0) {
627 if (data->cmk_emsk_available &&
628 eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
629 data->peer_outer_tlvs, data->cmk_emsk,
630 cb->emsk_compound_mac) < 0) {
635 wpa_printf(MSG_DEBUG,
636 "EAP-TEAP: Add Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
637 cb->version, cb->received_version, flags, subtype);
638 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
639 cb->nonce, sizeof(cb->nonce));
640 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
641 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
642 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
643 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
649 static struct wpabuf * eap_teap_build_pac(struct eap_sm *sm,
650 struct eap_teap_data *data)
652 u8 pac_key[EAP_TEAP_PAC_KEY_LEN];
653 u8 *pac_buf, *pac_opaque;
656 size_t buf_len, srv_id_info_len, pac_len;
657 struct teap_tlv_hdr *pac_tlv;
658 struct pac_attr_hdr *pac_info;
659 struct teap_tlv_result *result;
662 wpa_printf(MSG_DEBUG, "EAP-TEAP: Build a new PAC");
664 if (random_get_bytes(pac_key, EAP_TEAP_PAC_KEY_LEN) < 0 ||
665 os_get_time(&now) < 0)
667 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Generated PAC-Key",
668 pac_key, EAP_TEAP_PAC_KEY_LEN);
670 pac_len = (2 + EAP_TEAP_PAC_KEY_LEN) + (2 + 4) +
671 (2 + sm->identity_len) + 8;
672 pac_buf = os_malloc(pac_len);
676 srv_id_info_len = os_strlen(data->srv_id_info);
679 *pos++ = PAC_OPAQUE_TYPE_KEY;
680 *pos++ = EAP_TEAP_PAC_KEY_LEN;
681 os_memcpy(pos, pac_key, EAP_TEAP_PAC_KEY_LEN);
682 pos += EAP_TEAP_PAC_KEY_LEN;
684 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Key lifetime: %u seconds",
685 data->pac_key_lifetime);
686 *pos++ = PAC_OPAQUE_TYPE_LIFETIME;
688 WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime);
692 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Opaque Identity",
693 sm->identity, sm->identity_len);
694 *pos++ = PAC_OPAQUE_TYPE_IDENTITY;
695 *pos++ = sm->identity_len;
696 os_memcpy(pos, sm->identity, sm->identity_len);
697 pos += sm->identity_len;
700 pac_len = pos - pac_buf;
701 while (pac_len % 8) {
702 *pos++ = PAC_OPAQUE_TYPE_PAD;
706 pac_opaque = os_malloc(pac_len + 8);
711 if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
712 pac_len / 8, pac_buf, pac_opaque) < 0) {
720 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pac_opaque, pac_len);
722 buf_len = sizeof(*pac_tlv) +
723 sizeof(struct pac_attr_hdr) + EAP_TEAP_PAC_KEY_LEN +
724 sizeof(struct pac_attr_hdr) + pac_len +
725 data->srv_id_len + srv_id_info_len + 100 + sizeof(*result);
726 buf = wpabuf_alloc(buf_len);
733 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Result TLV (status=SUCCESS)");
734 result = wpabuf_put(buf, sizeof(*result));
735 WPA_PUT_BE16((u8 *) &result->tlv_type,
736 TEAP_TLV_MANDATORY | TEAP_TLV_RESULT);
737 WPA_PUT_BE16((u8 *) &result->length, 2);
738 WPA_PUT_BE16((u8 *) &result->status, TEAP_STATUS_SUCCESS);
741 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV");
742 pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
743 pac_tlv->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_PAC);
746 eap_teap_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_TEAP_PAC_KEY_LEN);
749 eap_teap_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
753 pac_info = wpabuf_put(buf, sizeof(*pac_info));
754 pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
756 /* PAC-Lifetime (inside PAC-Info) */
757 eap_teap_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
758 wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime);
760 /* A-ID (inside PAC-Info) */
761 eap_teap_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
763 /* Note: headers may be misaligned after A-ID */
766 eap_teap_put_tlv(buf, PAC_TYPE_I_ID, sm->identity,
770 /* A-ID-Info (inside PAC-Info) */
771 eap_teap_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
774 /* PAC-Type (inside PAC-Info) */
775 eap_teap_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
776 wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
778 /* Update PAC-Info and PAC TLV Length fields */
779 pos = wpabuf_put(buf, 0);
780 pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
781 pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));
787 static int eap_teap_encrypt_phase2(struct eap_sm *sm,
788 struct eap_teap_data *data,
789 struct wpabuf *plain, int piggyback)
793 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 TLVs",
795 encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
801 if (data->ssl.tls_out && piggyback) {
802 wpa_printf(MSG_DEBUG,
803 "EAP-TEAP: Piggyback Phase 2 data (len=%d) with last Phase 1 Message (len=%d used=%d)",
804 (int) wpabuf_len(encr),
805 (int) wpabuf_len(data->ssl.tls_out),
806 (int) data->ssl.tls_out_pos);
807 if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
808 wpa_printf(MSG_WARNING,
809 "EAP-TEAP: Failed to resize output buffer");
813 wpabuf_put_buf(data->ssl.tls_out, encr);
816 wpabuf_free(data->ssl.tls_out);
817 data->ssl.tls_out_pos = 0;
818 data->ssl.tls_out = encr;
825 static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
827 struct eap_teap_data *data = priv;
828 struct wpabuf *req = NULL;
831 if (data->ssl.state == FRAG_ACK) {
832 return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
836 if (data->ssl.state == WAIT_FRAG_ACK) {
837 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
838 data->teap_version, id);
841 switch (data->state) {
843 return eap_teap_build_start(sm, data, id);
845 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
846 if (eap_teap_phase1_done(sm, data) < 0)
848 if (data->state == PHASE2_START) {
852 * Try to generate Phase 2 data to piggyback
853 * with the end of Phase 1 to avoid extra
856 wpa_printf(MSG_DEBUG,
857 "EAP-TEAP: Try to start Phase 2");
858 res = eap_teap_process_phase2_start(sm, data);
860 req = eap_teap_build_crypto_binding(
868 req = eap_teap_build_phase2_req(sm, data, id);
874 case PHASE2_BASIC_AUTH:
876 req = eap_teap_build_phase2_req(sm, data, id);
879 req = eap_teap_build_crypto_binding(sm, data);
880 if (data->phase2_method) {
882 * Include the start of the next EAP method in the
883 * sequence in the same message with Crypto-Binding to
888 eap = eap_teap_build_phase2_req(sm, data, id);
889 req = wpabuf_concat(req, eap);
890 eap_teap_state(data, PHASE2_METHOD);
894 req = eap_teap_build_pac(sm, data);
896 case FAILURE_SEND_RESULT:
897 req = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
898 if (data->error_code)
900 req, eap_teap_tlv_error(data->error_code));
903 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
904 __func__, data->state);
908 if (req && eap_teap_encrypt_phase2(sm, data, req, piggyback) < 0)
911 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
912 data->teap_version, id);
916 static Boolean eap_teap_check(struct eap_sm *sm, void *priv,
917 struct wpabuf *respData)
922 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
923 if (!pos || len < 1) {
924 wpa_printf(MSG_INFO, "EAP-TEAP: Invalid frame");
932 static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
935 if (data->phase2_priv && data->phase2_method) {
936 data->phase2_method->reset(sm, data->phase2_priv);
937 data->phase2_method = NULL;
938 data->phase2_priv = NULL;
940 data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
942 if (!data->phase2_method)
946 data->phase2_priv = data->phase2_method->init(sm);
949 return data->phase2_priv ? 0 : -1;
953 static void eap_teap_process_phase2_response(struct eap_sm *sm,
954 struct eap_teap_data *data,
955 u8 *in_data, size_t in_len)
957 u8 next_type = EAP_TYPE_NONE;
962 const struct eap_method *m = data->phase2_method;
963 void *priv = data->phase2_priv;
966 wpa_printf(MSG_DEBUG,
967 "EAP-TEAP: %s - Phase 2 not initialized?!",
972 hdr = (struct eap_hdr *) in_data;
973 pos = (u8 *) (hdr + 1);
975 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
976 left = in_len - sizeof(*hdr);
977 wpa_hexdump(MSG_DEBUG,
978 "EAP-TEAP: Phase 2 type Nak'ed; allowed types",
980 #ifdef EAP_SERVER_TNC
981 if (m && m->vendor == EAP_VENDOR_IETF &&
982 m->method == EAP_TYPE_TNC) {
983 wpa_printf(MSG_DEBUG,
984 "EAP-TEAP: Peer Nak'ed required TNC negotiation");
985 next_type = eap_teap_req_failure(data, 0);
986 eap_teap_phase2_init(sm, data, next_type);
989 #endif /* EAP_SERVER_TNC */
990 eap_sm_process_nak(sm, pos + 1, left - 1);
991 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
992 sm->user->methods[sm->user_eap_method_index].method !=
994 next_type = sm->user->methods[
995 sm->user_eap_method_index++].method;
996 wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %d",
999 next_type = eap_teap_req_failure(data, 0);
1001 eap_teap_phase2_init(sm, data, next_type);
1005 wpabuf_set(&buf, in_data, in_len);
1007 if (m->check(sm, priv, &buf)) {
1008 wpa_printf(MSG_DEBUG,
1009 "EAP-TEAP: Phase 2 check() asked to ignore the packet");
1010 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1014 m->process(sm, priv, &buf);
1016 if (!m->isDone(sm, priv))
1019 if (!m->isSuccess(sm, priv)) {
1020 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed");
1021 next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1022 eap_teap_phase2_init(sm, data, next_type);
1026 switch (data->state) {
1028 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1029 wpa_hexdump_ascii(MSG_DEBUG,
1030 "EAP-TEAP: Phase 2 Identity not found in the user database",
1031 sm->identity, sm->identity_len);
1032 next_type = eap_teap_req_failure(
1033 data, TEAP_ERROR_INNER_METHOD);
1037 eap_teap_state(data, PHASE2_METHOD);
1038 if (data->anon_provisioning) {
1039 /* TODO: Allow any inner EAP method that provides
1040 * mutual authentication and EMSK derivation (i.e.,
1041 * EAP-pwd or EAP-EKE). */
1042 next_type = EAP_TYPE_PWD;
1043 sm->user_eap_method_index = 0;
1045 next_type = sm->user->methods[0].method;
1046 sm->user_eap_method_index = 1;
1048 wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %d", next_type);
1051 case CRYPTO_BINDING:
1052 eap_teap_update_icmk(sm, data);
1053 eap_teap_state(data, CRYPTO_BINDING);
1055 next_type = EAP_TYPE_NONE;
1056 #ifdef EAP_SERVER_TNC
1057 if (sm->tnc && !data->tnc_started) {
1058 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC");
1059 next_type = EAP_TYPE_TNC;
1060 data->tnc_started = 1;
1062 #endif /* EAP_SERVER_TNC */
1067 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
1068 __func__, data->state);
1072 eap_teap_phase2_init(sm, data, next_type);
1076 static void eap_teap_process_phase2_eap(struct eap_sm *sm,
1077 struct eap_teap_data *data,
1078 u8 *in_data, size_t in_len)
1080 struct eap_hdr *hdr;
1083 hdr = (struct eap_hdr *) in_data;
1084 if (in_len < (int) sizeof(*hdr)) {
1085 wpa_printf(MSG_INFO,
1086 "EAP-TEAP: Too short Phase 2 EAP frame (len=%lu)",
1087 (unsigned long) in_len);
1088 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1091 len = be_to_host16(hdr->length);
1093 wpa_printf(MSG_INFO,
1094 "EAP-TEAP: Length mismatch in Phase 2 EAP frame (len=%lu hdr->length=%lu)",
1095 (unsigned long) in_len, (unsigned long) len);
1096 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1099 wpa_printf(MSG_DEBUG,
1100 "EAP-TEAP: Received Phase 2: code=%d identifier=%d length=%lu",
1101 hdr->code, hdr->identifier,
1102 (unsigned long) len);
1103 switch (hdr->code) {
1104 case EAP_CODE_RESPONSE:
1105 eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len);
1108 wpa_printf(MSG_INFO,
1109 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
1116 static void eap_teap_process_basic_auth_resp(struct eap_sm *sm,
1117 struct eap_teap_data *data,
1118 u8 *in_data, size_t in_len)
1120 u8 *pos, *end, *username, *password, *new_id;
1121 u8 userlen, passlen;
1126 if (end - pos < 1) {
1127 wpa_printf(MSG_DEBUG,
1128 "EAP-TEAP: No room for Basic-Password-Auth-Resp Userlen field");
1129 eap_teap_req_failure(data, 0);
1133 if (end - pos < userlen) {
1134 wpa_printf(MSG_DEBUG,
1135 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Username field");
1136 eap_teap_req_failure(data, 0);
1141 wpa_hexdump_ascii(MSG_DEBUG,
1142 "EAP-TEAP: Basic-Password-Auth-Resp Username",
1145 if (end - pos < 1) {
1146 wpa_printf(MSG_DEBUG,
1147 "EAP-TEAP: No room for Basic-Password-Auth-Resp Passlen field");
1148 eap_teap_req_failure(data, 0);
1152 if (end - pos < passlen) {
1153 wpa_printf(MSG_DEBUG,
1154 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Password field");
1155 eap_teap_req_failure(data, 0);
1160 wpa_hexdump_ascii_key(MSG_DEBUG,
1161 "EAP-TEAP: Basic-Password-Auth-Resp Password",
1165 wpa_printf(MSG_DEBUG,
1166 "EAP-TEAP: Unexpected %d extra octet(s) at the end of Basic-Password-Auth-Resp TLV",
1168 eap_teap_req_failure(data, 0);
1172 if (eap_user_get(sm, username, userlen, 1) != 0) {
1173 wpa_printf(MSG_DEBUG,
1174 "EAP-TEAP: Username not found in the user database");
1175 eap_teap_req_failure(data, 0);
1179 if (!sm->user || !sm->user->password || sm->user->password_hash) {
1180 wpa_printf(MSG_DEBUG,
1181 "EAP-TEAP: No plaintext user password configured");
1182 eap_teap_req_failure(data, 0);
1186 if (sm->user->password_len != passlen ||
1187 os_memcmp_const(sm->user->password, password, passlen) != 0) {
1188 wpa_printf(MSG_DEBUG, "EAP-TEAP: Invalid password");
1189 eap_teap_req_failure(data, 0);
1193 wpa_printf(MSG_DEBUG, "EAP-TEAP: Correct password");
1194 new_id = os_memdup(username, userlen);
1196 os_free(sm->identity);
1197 sm->identity = new_id;
1198 sm->identity_len = userlen;
1200 eap_teap_state(data, CRYPTO_BINDING);
1201 eap_teap_update_icmk(sm, data);
1205 static int eap_teap_parse_tlvs(struct wpabuf *data,
1206 struct eap_teap_tlv_parse *tlv)
1213 os_memset(tlv, 0, sizeof(*tlv));
1215 pos = wpabuf_mhead(data);
1216 end = pos + wpabuf_len(data);
1217 while (end - pos > 4) {
1218 mandatory = pos[0] & 0x80;
1219 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1221 len = WPA_GET_BE16(pos);
1223 if (len > (size_t) (end - pos)) {
1224 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1227 wpa_printf(MSG_DEBUG,
1228 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1229 tlv_type, eap_teap_tlv_type_str(tlv_type),
1231 mandatory ? " (mandatory)" : "");
1233 res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
1238 wpa_printf(MSG_DEBUG,
1239 "EAP-TEAP: NAK unknown mandatory TLV type %u",
1241 /* TODO: generate NAK TLV */
1245 wpa_printf(MSG_DEBUG,
1246 "EAP-TEAP: Ignore unknown optional TLV type %u",
1257 static int eap_teap_validate_crypto_binding(
1258 struct eap_teap_data *data, const struct teap_tlv_crypto_binding *cb,
1263 subtype = cb->subtype & 0x0f;
1264 flags = cb->subtype >> 4;
1266 wpa_printf(MSG_DEBUG,
1267 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
1268 cb->version, cb->received_version, flags, subtype);
1269 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
1270 cb->nonce, sizeof(cb->nonce));
1271 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
1272 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
1273 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
1274 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
1276 if (cb->version != EAP_TEAP_VERSION ||
1277 cb->received_version != data->peer_version) {
1278 wpa_printf(MSG_DEBUG,
1279 "EAP-TEAP: Unexpected version in Crypto-Binding: Version %u Received Version %u",
1280 cb->version, cb->received_version);
1284 if (flags < 1 || flags > 3) {
1285 wpa_printf(MSG_DEBUG,
1286 "EAP-TEAP: Unexpected Flags in Crypto-Binding: %u",
1291 if (subtype != TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
1292 wpa_printf(MSG_DEBUG,
1293 "EAP-TEAP: Unexpected Sub-Type in Crypto-Binding: %u",
1298 if (os_memcmp_const(data->crypto_binding_nonce, cb->nonce,
1299 EAP_TEAP_NONCE_LEN - 1) != 0 ||
1300 (data->crypto_binding_nonce[EAP_TEAP_NONCE_LEN - 1] | 1) !=
1301 cb->nonce[EAP_TEAP_NONCE_LEN - 1]) {
1302 wpa_printf(MSG_DEBUG,
1303 "EAP-TEAP: Invalid Nonce in Crypto-Binding");
1307 if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
1308 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
1309 u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
1311 if (eap_teap_compound_mac(data->tls_cs, cb,
1312 data->server_outer_tlvs,
1313 data->peer_outer_tlvs, data->cmk_msk,
1314 msk_compound_mac) < 0)
1316 if (os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
1317 EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1318 wpa_hexdump(MSG_DEBUG,
1319 "EAP-TEAP: Calculated MSK Compound MAC",
1321 EAP_TEAP_COMPOUND_MAC_LEN);
1322 wpa_printf(MSG_INFO,
1323 "EAP-TEAP: MSK Compound MAC did not match");
1328 if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
1329 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
1330 data->cmk_emsk_available) {
1331 u8 emsk_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_emsk,
1336 emsk_compound_mac) < 0)
1338 if (os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
1339 EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1340 wpa_hexdump(MSG_DEBUG,
1341 "EAP-TEAP: Calculated EMSK Compound MAC",
1343 EAP_TEAP_COMPOUND_MAC_LEN);
1344 wpa_printf(MSG_INFO,
1345 "EAP-TEAP: EMSK Compound MAC did not match");
1350 if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
1351 !data->cmk_emsk_available) {
1352 wpa_printf(MSG_INFO,
1353 "EAP-TEAP: Peer included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
1361 static int eap_teap_pac_type(u8 *pac, size_t len, u16 type)
1363 struct teap_attr_pac_type *tlv;
1365 if (!pac || len != sizeof(*tlv))
1368 tlv = (struct teap_attr_pac_type *) pac;
1370 return be_to_host16(tlv->type) == PAC_TYPE_PAC_TYPE &&
1371 be_to_host16(tlv->length) == 2 &&
1372 be_to_host16(tlv->pac_type) == type;
1376 static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
1377 struct eap_teap_data *data,
1378 struct wpabuf *in_data)
1380 struct eap_teap_tlv_parse tlv;
1381 int check_crypto_binding = data->state == CRYPTO_BINDING;
1383 if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
1384 wpa_printf(MSG_DEBUG,
1385 "EAP-TEAP: Failed to parse received Phase 2 TLVs");
1389 if (tlv.result == TEAP_STATUS_FAILURE) {
1390 wpa_printf(MSG_DEBUG, "EAP-TEAP: Result TLV indicated failure");
1391 eap_teap_state(data, FAILURE);
1396 wpa_printf(MSG_DEBUG,
1397 "EAP-TEAP: Peer NAK'ed Vendor-Id %u NAK-Type %u",
1398 WPA_GET_BE32(tlv.nak), WPA_GET_BE16(tlv.nak + 4));
1399 eap_teap_state(data, FAILURE_SEND_RESULT);
1403 if (data->state == REQUEST_PAC) {
1406 if (!tlv.pac || tlv.pac_len < 6) {
1407 wpa_printf(MSG_DEBUG,
1408 "EAP-TEAP: No PAC Acknowledgement received");
1409 eap_teap_state(data, FAILURE);
1413 type = WPA_GET_BE16(tlv.pac);
1414 len = WPA_GET_BE16(tlv.pac + 2);
1415 res = WPA_GET_BE16(tlv.pac + 4);
1417 if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||
1418 res != TEAP_STATUS_SUCCESS) {
1419 wpa_printf(MSG_DEBUG,
1420 "EAP-TEAP: PAC TLV did not contain acknowledgement");
1421 eap_teap_state(data, FAILURE);
1425 wpa_printf(MSG_DEBUG,
1426 "EAP-TEAP: PAC-Acknowledgement received - PAC provisioning succeeded");
1427 eap_teap_state(data, SUCCESS);
1431 if (check_crypto_binding) {
1432 if (!tlv.crypto_binding) {
1433 wpa_printf(MSG_DEBUG,
1434 "EAP-TEAP: No Crypto-Binding TLV received");
1435 eap_teap_state(data, FAILURE);
1439 if (data->final_result &&
1440 tlv.result != TEAP_STATUS_SUCCESS) {
1441 wpa_printf(MSG_DEBUG,
1442 "EAP-TEAP: Crypto-Binding TLV without Success Result");
1443 eap_teap_state(data, FAILURE);
1447 if (!data->final_result &&
1448 tlv.iresult != TEAP_STATUS_SUCCESS) {
1449 wpa_printf(MSG_DEBUG,
1450 "EAP-TEAP: Crypto-Binding TLV without intermediate Success Result");
1451 eap_teap_state(data, FAILURE);
1455 if (eap_teap_validate_crypto_binding(data, tlv.crypto_binding,
1456 tlv.crypto_binding_len)) {
1457 eap_teap_state(data, FAILURE);
1461 wpa_printf(MSG_DEBUG,
1462 "EAP-TEAP: Valid Crypto-Binding TLV received");
1463 if (data->final_result) {
1464 wpa_printf(MSG_DEBUG,
1465 "EAP-TEAP: Authentication completed successfully");
1468 if (data->anon_provisioning &&
1469 sm->eap_fast_prov != ANON_PROV &&
1470 sm->eap_fast_prov != BOTH_PROV) {
1471 wpa_printf(MSG_DEBUG,
1472 "EAP-TEAP: Client is trying to use unauthenticated provisioning which is disabled");
1473 eap_teap_state(data, FAILURE);
1477 if (sm->eap_fast_prov != AUTH_PROV &&
1478 sm->eap_fast_prov != BOTH_PROV &&
1479 tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV &&
1480 eap_teap_pac_type(tlv.pac, tlv.pac_len,
1481 PAC_TYPE_TUNNEL_PAC)) {
1482 wpa_printf(MSG_DEBUG,
1483 "EAP-TEAP: Client is trying to use authenticated provisioning which is disabled");
1484 eap_teap_state(data, FAILURE);
1488 if (data->anon_provisioning ||
1489 (tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV &&
1490 eap_teap_pac_type(tlv.pac, tlv.pac_len,
1491 PAC_TYPE_TUNNEL_PAC))) {
1492 wpa_printf(MSG_DEBUG,
1493 "EAP-TEAP: Requested a new Tunnel PAC");
1494 eap_teap_state(data, REQUEST_PAC);
1495 } else if (data->send_new_pac) {
1496 wpa_printf(MSG_DEBUG,
1497 "EAP-TEAP: Server triggered re-keying of Tunnel PAC");
1498 eap_teap_state(data, REQUEST_PAC);
1499 } else if (data->final_result)
1500 eap_teap_state(data, SUCCESS);
1503 if (tlv.basic_auth_resp) {
1504 if (sm->eap_teap_auth != 1) {
1505 wpa_printf(MSG_DEBUG,
1506 "EAP-TEAP: Unexpected Basic-Password-Auth-Resp when trying to use inner EAP");
1507 eap_teap_state(data, FAILURE);
1510 eap_teap_process_basic_auth_resp(sm, data, tlv.basic_auth_resp,
1511 tlv.basic_auth_resp_len);
1514 if (tlv.eap_payload_tlv) {
1515 if (sm->eap_teap_auth == 1) {
1516 wpa_printf(MSG_DEBUG,
1517 "EAP-TEAP: Unexpected EAP Payload TLV when trying to use Basic-Password-Auth");
1518 eap_teap_state(data, FAILURE);
1521 eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
1522 tlv.eap_payload_tlv_len);
1527 static void eap_teap_process_phase2(struct eap_sm *sm,
1528 struct eap_teap_data *data,
1529 struct wpabuf *in_buf)
1531 struct wpabuf *in_decrypted;
1533 wpa_printf(MSG_DEBUG,
1534 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1535 (unsigned long) wpabuf_len(in_buf));
1537 if (data->pending_phase2_resp) {
1538 wpa_printf(MSG_DEBUG,
1539 "EAP-TEAP: Pending Phase 2 response - skip decryption and use old data");
1540 eap_teap_process_phase2_tlvs(sm, data,
1541 data->pending_phase2_resp);
1542 wpabuf_free(data->pending_phase2_resp);
1543 data->pending_phase2_resp = NULL;
1547 in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
1549 if (!in_decrypted) {
1550 wpa_printf(MSG_INFO,
1551 "EAP-TEAP: Failed to decrypt Phase 2 data");
1552 eap_teap_state(data, FAILURE);
1556 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Decrypted Phase 2 TLVs",
1559 eap_teap_process_phase2_tlvs(sm, data, in_decrypted);
1561 if (sm->method_pending == METHOD_PENDING_WAIT) {
1562 wpa_printf(MSG_DEBUG,
1563 "EAP-TEAP: Phase 2 method is in pending wait state - save decrypted response");
1564 wpabuf_free(data->pending_phase2_resp);
1565 data->pending_phase2_resp = in_decrypted;
1569 wpabuf_free(in_decrypted);
1573 static int eap_teap_process_version(struct eap_sm *sm, void *priv,
1576 struct eap_teap_data *data = priv;
1578 if (peer_version < 1) {
1579 /* Version 1 was the first defined version, so reject 0 */
1580 wpa_printf(MSG_INFO,
1581 "EAP-TEAP: Peer used unknown TEAP version %u",
1586 if (peer_version < data->teap_version) {
1587 wpa_printf(MSG_DEBUG, "EAP-TEAP: peer ver=%u, own ver=%u; "
1589 peer_version, data->teap_version, peer_version);
1590 data->teap_version = peer_version;
1593 data->peer_version = peer_version;
1599 static int eap_teap_process_phase1(struct eap_sm *sm,
1600 struct eap_teap_data *data)
1602 if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
1603 wpa_printf(MSG_INFO, "EAP-TEAP: TLS processing failed");
1604 eap_teap_state(data, FAILURE);
1608 if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
1609 wpabuf_len(data->ssl.tls_out) > 0)
1613 * Phase 1 was completed with the received message (e.g., when using
1614 * abbreviated handshake), so Phase 2 can be started immediately
1615 * without having to send through an empty message to the peer.
1618 return eap_teap_phase1_done(sm, data);
1622 static int eap_teap_process_phase2_start(struct eap_sm *sm,
1623 struct eap_teap_data *data)
1627 if (data->identity) {
1628 /* Used PAC and identity is from PAC-Opaque */
1629 os_free(sm->identity);
1630 sm->identity = data->identity;
1631 data->identity = NULL;
1632 sm->identity_len = data->identity_len;
1633 data->identity_len = 0;
1634 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1635 wpa_hexdump_ascii(MSG_DEBUG,
1636 "EAP-TEAP: Phase 2 Identity not found in the user database",
1637 sm->identity, sm->identity_len);
1638 next_type = EAP_TYPE_NONE;
1639 eap_teap_state(data, PHASE2_METHOD);
1640 } else if (sm->eap_teap_pac_no_inner) {
1641 wpa_printf(MSG_DEBUG,
1642 "EAP-TEAP: Used PAC and identity already known - skip inner auth");
1643 /* FIX: Need to derive CMK here. However, how is that
1644 * supposed to be done? RFC 7170 does not tell that for
1645 * the no-inner-auth case. */
1646 eap_teap_derive_cmk_basic_pw_auth(data->simck_msk,
1648 eap_teap_state(data, CRYPTO_BINDING);
1650 } else if (sm->eap_teap_auth == 1) {
1651 eap_teap_state(data, PHASE2_BASIC_AUTH);
1654 wpa_printf(MSG_DEBUG,
1655 "EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
1656 next_type = sm->user->methods[0].method;
1657 sm->user_eap_method_index = 1;
1658 eap_teap_state(data, PHASE2_METHOD);
1661 } else if (sm->eap_teap_auth == 1) {
1662 eap_teap_state(data, PHASE2_BASIC_AUTH);
1665 eap_teap_state(data, PHASE2_ID);
1666 next_type = EAP_TYPE_IDENTITY;
1669 return eap_teap_phase2_init(sm, data, next_type);
1673 static void eap_teap_process_msg(struct eap_sm *sm, void *priv,
1674 const struct wpabuf *respData)
1676 struct eap_teap_data *data = priv;
1678 switch (data->state) {
1681 if (eap_teap_process_phase1(sm, data))
1686 eap_teap_process_phase2_start(sm, data);
1689 case PHASE2_BASIC_AUTH:
1691 case CRYPTO_BINDING:
1693 eap_teap_process_phase2(sm, data, data->ssl.tls_in);
1695 case FAILURE_SEND_RESULT:
1696 /* Protected failure result indication completed. Ignore the
1697 * received message (which is supposed to include Result TLV
1698 * indicating failure) and terminate exchange with cleartext
1700 eap_teap_state(data, FAILURE);
1703 wpa_printf(MSG_DEBUG, "EAP-TEAP: Unexpected state %d in %s",
1704 data->state, __func__);
1710 static void eap_teap_process(struct eap_sm *sm, void *priv,
1711 struct wpabuf *respData)
1713 struct eap_teap_data *data = priv;
1716 struct wpabuf *resp = respData;
1719 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
1720 if (!pos || len < 1)
1726 if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1727 /* Extract Outer TLVs from the message before common TLS
1729 u32 message_len = 0, outer_tlv_len;
1732 if (data->state != PHASE1) {
1733 wpa_printf(MSG_INFO,
1734 "EAP-TEAP: Unexpected Outer TLVs in a message that is not the first message from the peer");
1738 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1740 wpa_printf(MSG_INFO,
1741 "EAP-TEAP: Too short message to include Message Length field");
1745 message_len = WPA_GET_BE32(pos);
1748 if (message_len < 4) {
1749 wpa_printf(MSG_INFO,
1750 "EAP-TEAP: Message Length field has too msall value to include Outer TLV Length field");
1756 wpa_printf(MSG_INFO,
1757 "EAP-TEAP: Too short message to include Outer TLVs Length field");
1761 outer_tlv_len = WPA_GET_BE32(pos);
1765 wpa_printf(MSG_DEBUG,
1766 "EAP-TEAP: Message Length %u Outer TLV Length %u",
1767 message_len, outer_tlv_len);
1768 if (len < outer_tlv_len) {
1769 wpa_printf(MSG_INFO,
1770 "EAP-TEAP: Too short message to include Outer TLVs field");
1775 (message_len < outer_tlv_len ||
1776 message_len < 4 + outer_tlv_len)) {
1777 wpa_printf(MSG_INFO,
1778 "EAP-TEAP: Message Length field has too small value to include Outer TLVs");
1782 if (wpabuf_len(respData) < 4 + outer_tlv_len ||
1783 len < outer_tlv_len)
1785 resp = wpabuf_alloc(wpabuf_len(respData) - 4 - outer_tlv_len);
1788 hdr = wpabuf_head(respData);
1789 wpabuf_put_u8(resp, *hdr++); /* Code */
1790 wpabuf_put_u8(resp, *hdr++); /* Identifier */
1791 wpabuf_put_be16(resp, WPA_GET_BE16(hdr) - 4 - outer_tlv_len);
1793 wpabuf_put_u8(resp, *hdr++); /* Type */
1795 wpabuf_put_u8(resp, flags & ~EAP_TEAP_FLAGS_OUTER_TLV_LEN);
1797 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)
1798 wpabuf_put_be32(resp, message_len - 4 - outer_tlv_len);
1800 wpabuf_put_data(resp, pos, len - outer_tlv_len);
1801 pos += len - outer_tlv_len;
1802 wpabuf_free(data->peer_outer_tlvs);
1803 data->peer_outer_tlvs = wpabuf_alloc_copy(pos, outer_tlv_len);
1804 if (!data->peer_outer_tlvs)
1806 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Outer TLVs",
1807 data->peer_outer_tlvs);
1809 wpa_hexdump_buf(MSG_DEBUG,
1810 "EAP-TEAP: TLS Data message after Outer TLV removal",
1812 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, resp,
1814 if (!pos || len < 1) {
1815 wpa_printf(MSG_INFO,
1816 "EAP-TEAP: Invalid frame after Outer TLV removal");
1821 if (data->state == PHASE1)
1822 eap_teap_state(data, PHASE1B);
1824 if (eap_server_tls_process(sm, &data->ssl, resp, data,
1825 EAP_TYPE_TEAP, eap_teap_process_version,
1826 eap_teap_process_msg) < 0)
1827 eap_teap_state(data, FAILURE);
1829 if (resp != respData)
1834 static Boolean eap_teap_isDone(struct eap_sm *sm, void *priv)
1836 struct eap_teap_data *data = priv;
1838 return data->state == SUCCESS || data->state == FAILURE;
1842 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
1844 struct eap_teap_data *data = priv;
1847 if (data->state != SUCCESS)
1850 eapKeyData = os_malloc(EAP_TEAP_KEY_LEN);
1854 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
1855 * is used in this derivation */
1856 if (eap_teap_derive_eap_msk(data->simck_msk, eapKeyData) < 0) {
1857 os_free(eapKeyData);
1860 *len = EAP_TEAP_KEY_LEN;
1866 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1868 struct eap_teap_data *data = priv;
1871 if (data->state != SUCCESS)
1874 eapKeyData = os_malloc(EAP_EMSK_LEN);
1878 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
1879 * is used in this derivation */
1880 if (eap_teap_derive_eap_emsk(data->simck_msk, eapKeyData) < 0) {
1881 os_free(eapKeyData);
1884 *len = EAP_EMSK_LEN;
1890 static Boolean eap_teap_isSuccess(struct eap_sm *sm, void *priv)
1892 struct eap_teap_data *data = priv;
1894 return data->state == SUCCESS;
1898 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1900 struct eap_teap_data *data = priv;
1901 const size_t max_id_len = 100;
1905 if (data->state != SUCCESS)
1908 id = os_malloc(max_id_len);
1912 id[0] = EAP_TYPE_TEAP;
1913 res = tls_get_tls_unique(data->ssl.conn, id + 1, max_id_len - 1);
1916 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
1921 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id", id, *len);
1926 int eap_server_teap_register(void)
1928 struct eap_method *eap;
1930 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1931 EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
1935 eap->init = eap_teap_init;
1936 eap->reset = eap_teap_reset;
1937 eap->buildReq = eap_teap_buildReq;
1938 eap->check = eap_teap_check;
1939 eap->process = eap_teap_process;
1940 eap->isDone = eap_teap_isDone;
1941 eap->getKey = eap_teap_getKey;
1942 eap->get_emsk = eap_teap_get_emsk;
1943 eap->isSuccess = eap_teap_isSuccess;
1944 eap->getSessionId = eap_teap_get_session_id;
1946 return eap_server_method_register(eap);