xref: /freebsd/contrib/wpa/src/eap_peer/eap_teap.c (revision 6966ac055c3b7a39266fb982493330df7a097997)
1 /*
2  * EAP peer method: EAP-TEAP (RFC 7170)
3  * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "crypto/tls.h"
13 #include "eap_common/eap_teap_common.h"
14 #include "eap_i.h"
15 #include "eap_tls_common.h"
16 #include "eap_config.h"
17 #include "eap_teap_pac.h"
18 
19 #ifdef EAP_TEAP_DYNAMIC
20 #include "eap_teap_pac.c"
21 #endif /* EAP_TEAP_DYNAMIC */
22 
23 
24 static void eap_teap_deinit(struct eap_sm *sm, void *priv);
25 
26 
27 struct eap_teap_data {
28 	struct eap_ssl_data ssl;
29 
30 	u8 teap_version; /* Negotiated version */
31 	u8 received_version; /* Version number received during negotiation */
32 	u16 tls_cs;
33 
34 	const struct eap_method *phase2_method;
35 	void *phase2_priv;
36 	int phase2_success;
37 	int inner_method_done;
38 	int result_success_done;
39 	int on_tx_completion;
40 
41 	struct eap_method_type phase2_type;
42 	struct eap_method_type *phase2_types;
43 	size_t num_phase2_types;
44 	int resuming; /* starting a resumed session */
45 #define EAP_TEAP_PROV_UNAUTH 1
46 #define EAP_TEAP_PROV_AUTH 2
47 	int provisioning_allowed; /* Allowed PAC provisioning modes */
48 	int provisioning; /* doing PAC provisioning (not the normal auth) */
49 	int anon_provisioning; /* doing anonymous (unauthenticated)
50 				* provisioning */
51 	int session_ticket_used;
52 	int test_outer_tlvs;
53 
54 	u8 key_data[EAP_TEAP_KEY_LEN];
55 	u8 *session_id;
56 	size_t id_len;
57 	u8 emsk[EAP_EMSK_LEN];
58 	int success;
59 
60 	struct eap_teap_pac *pac;
61 	struct eap_teap_pac *current_pac;
62 	size_t max_pac_list_len;
63 	int use_pac_binary_format;
64 
65 	u8 simck_msk[EAP_TEAP_SIMCK_LEN];
66 	u8 simck_emsk[EAP_TEAP_SIMCK_LEN];
67 	int simck_idx;
68 	int cmk_emsk_available;
69 
70 	struct wpabuf *pending_phase2_req;
71 	struct wpabuf *pending_resp;
72 	struct wpabuf *server_outer_tlvs;
73 	struct wpabuf *peer_outer_tlvs;
74 };
75 
76 
77 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
78 				      const u8 *client_random,
79 				      const u8 *server_random,
80 				      u8 *master_secret)
81 {
82 	struct eap_teap_data *data = ctx;
83 
84 	wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");
85 
86 	if (!master_secret) {
87 		wpa_printf(MSG_DEBUG,
88 			   "EAP-TEAP: SessionTicket failed - fall back to full TLS handshake");
89 		data->session_ticket_used = 0;
90 		if (data->provisioning_allowed) {
91 			wpa_printf(MSG_DEBUG,
92 				   "EAP-TEAP: Try to provision a new PAC-Key");
93 			data->provisioning = 1;
94 			data->current_pac = NULL;
95 		}
96 		return 0;
97 	}
98 
99 	wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket", ticket, len);
100 
101 	if (!data->current_pac) {
102 		wpa_printf(MSG_DEBUG,
103 			   "EAP-TEAP: No PAC-Key available for using SessionTicket");
104 		data->session_ticket_used = 0;
105 		return 0;
106 	}
107 
108 	/* EAP-TEAP uses PAC-Key as the TLS master_secret */
109 	os_memcpy(master_secret, data->current_pac->pac_key,
110 		  EAP_TEAP_PAC_KEY_LEN);
111 
112 	data->session_ticket_used = 1;
113 
114 	return 1;
115 }
116 
117 
118 static void eap_teap_parse_phase1(struct eap_teap_data *data,
119 				  const char *phase1)
120 {
121 	const char *pos;
122 
123 	pos = os_strstr(phase1, "teap_provisioning=");
124 	if (pos) {
125 		data->provisioning_allowed = atoi(pos + 18);
126 		wpa_printf(MSG_DEBUG,
127 			   "EAP-TEAP: Automatic PAC provisioning mode: %d",
128 			   data->provisioning_allowed);
129 	}
130 
131 	pos = os_strstr(phase1, "teap_max_pac_list_len=");
132 	if (pos) {
133 		data->max_pac_list_len = atoi(pos + 22);
134 		if (data->max_pac_list_len == 0)
135 			data->max_pac_list_len = 1;
136 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Maximum PAC list length: %lu",
137 			   (unsigned long) data->max_pac_list_len);
138 	}
139 
140 	if (os_strstr(phase1, "teap_pac_format=binary")) {
141 		data->use_pac_binary_format = 1;
142 		wpa_printf(MSG_DEBUG,
143 			   "EAP-TEAP: Using binary format for PAC list");
144 	}
145 
146 #ifdef CONFIG_TESTING_OPTIONS
147 	if (os_strstr(phase1, "teap_test_outer_tlvs=1"))
148 		data->test_outer_tlvs = 1;
149 #endif /* CONFIG_TESTING_OPTIONS */
150 }
151 
152 
153 static void * eap_teap_init(struct eap_sm *sm)
154 {
155 	struct eap_teap_data *data;
156 	struct eap_peer_config *config = eap_get_config(sm);
157 
158 	if (!config)
159 		return NULL;
160 
161 	data = os_zalloc(sizeof(*data));
162 	if (!data)
163 		return NULL;
164 	data->teap_version = EAP_TEAP_VERSION;
165 	data->max_pac_list_len = 10;
166 
167 	if (config->phase1)
168 		eap_teap_parse_phase1(data, config->phase1);
169 
170 	if ((data->provisioning_allowed & EAP_TEAP_PROV_AUTH) &&
171 	    !config->ca_cert && !config->ca_path) {
172 		/* Prevent PAC provisioning without mutual authentication
173 		 * (either by validating server certificate or by suitable
174 		 * inner EAP method). */
175 		wpa_printf(MSG_INFO,
176 			   "EAP-TEAP: Disable authenticated provisioning due to no ca_cert/ca_path");
177 		data->provisioning_allowed &= ~EAP_TEAP_PROV_AUTH;
178 	}
179 
180 	if (eap_peer_select_phase2_methods(config, "auth=",
181 					   &data->phase2_types,
182 					   &data->num_phase2_types) < 0) {
183 		eap_teap_deinit(sm, data);
184 		return NULL;
185 	}
186 
187 	data->phase2_type.vendor = EAP_VENDOR_IETF;
188 	data->phase2_type.method = EAP_TYPE_NONE;
189 
190 	config->teap_anon_dh = !!(data->provisioning_allowed &
191 				  EAP_TEAP_PROV_UNAUTH);
192 	if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TEAP)) {
193 		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL");
194 		eap_teap_deinit(sm, data);
195 		return NULL;
196 	}
197 
198 	if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
199 						 eap_teap_session_ticket_cb,
200 						 data) < 0) {
201 		wpa_printf(MSG_INFO,
202 			   "EAP-TEAP: Failed to set SessionTicket callback");
203 		eap_teap_deinit(sm, data);
204 		return NULL;
205 	}
206 
207 	if (!config->pac_file) {
208 		wpa_printf(MSG_INFO, "EAP-TEAP: No PAC file configured");
209 		eap_teap_deinit(sm, data);
210 		return NULL;
211 	}
212 
213 	if (data->use_pac_binary_format &&
214 	    eap_teap_load_pac_bin(sm, &data->pac, config->pac_file) < 0) {
215 		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
216 		eap_teap_deinit(sm, data);
217 		return NULL;
218 	}
219 
220 	if (!data->use_pac_binary_format &&
221 	    eap_teap_load_pac(sm, &data->pac, config->pac_file) < 0) {
222 		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to load PAC file");
223 		eap_teap_deinit(sm, data);
224 		return NULL;
225 	}
226 	eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
227 
228 	return data;
229 }
230 
231 
232 static void eap_teap_clear(struct eap_teap_data *data)
233 {
234 	forced_memzero(data->key_data, EAP_TEAP_KEY_LEN);
235 	forced_memzero(data->emsk, EAP_EMSK_LEN);
236 	os_free(data->session_id);
237 	data->session_id = NULL;
238 	wpabuf_free(data->pending_phase2_req);
239 	data->pending_phase2_req = NULL;
240 	wpabuf_free(data->pending_resp);
241 	data->pending_resp = NULL;
242 	wpabuf_free(data->server_outer_tlvs);
243 	data->server_outer_tlvs = NULL;
244 	wpabuf_free(data->peer_outer_tlvs);
245 	data->peer_outer_tlvs = NULL;
246 	forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
247 	forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
248 }
249 
250 
251 static void eap_teap_deinit(struct eap_sm *sm, void *priv)
252 {
253 	struct eap_teap_data *data = priv;
254 	struct eap_teap_pac *pac, *prev;
255 
256 	if (!data)
257 		return;
258 	if (data->phase2_priv && data->phase2_method)
259 		data->phase2_method->deinit(sm, data->phase2_priv);
260 	eap_teap_clear(data);
261 	os_free(data->phase2_types);
262 	eap_peer_tls_ssl_deinit(sm, &data->ssl);
263 
264 	pac = data->pac;
265 	prev = NULL;
266 	while (pac) {
267 		prev = pac;
268 		pac = pac->next;
269 		eap_teap_free_pac(prev);
270 	}
271 
272 	os_free(data);
273 }
274 
275 
276 static int eap_teap_derive_msk(struct eap_teap_data *data)
277 {
278 	/* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
279 	 * is used in this derivation */
280 	if (eap_teap_derive_eap_msk(data->simck_msk, data->key_data) < 0 ||
281 	    eap_teap_derive_eap_emsk(data->simck_msk, data->emsk) < 0)
282 		return -1;
283 	data->success = 1;
284 	return 0;
285 }
286 
287 
288 static int eap_teap_derive_key_auth(struct eap_sm *sm,
289 				    struct eap_teap_data *data)
290 {
291 	int res;
292 
293 	/* RFC 7170, Section 5.1 */
294 	res = tls_connection_export_key(sm->ssl_ctx, data->ssl.conn,
295 					TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
296 					data->simck_msk, EAP_TEAP_SIMCK_LEN);
297 	if (res)
298 		return res;
299 	wpa_hexdump_key(MSG_DEBUG,
300 			"EAP-TEAP: session_key_seed (S-IMCK[0])",
301 			data->simck_msk, EAP_TEAP_SIMCK_LEN);
302 	os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN);
303 	data->simck_idx = 0;
304 	return 0;
305 }
306 
307 
308 static int eap_teap_init_phase2_method(struct eap_sm *sm,
309 				       struct eap_teap_data *data)
310 {
311 	data->inner_method_done = 0;
312 	data->phase2_method =
313 		eap_peer_get_eap_method(data->phase2_type.vendor,
314 					data->phase2_type.method);
315 	if (!data->phase2_method)
316 		return -1;
317 
318 	sm->init_phase2 = 1;
319 	data->phase2_priv = data->phase2_method->init(sm);
320 	sm->init_phase2 = 0;
321 
322 	return data->phase2_priv == NULL ? -1 : 0;
323 }
324 
325 
326 static int eap_teap_select_phase2_method(struct eap_teap_data *data, u8 type)
327 {
328 	size_t i;
329 
330 	/* TODO: TNC with anonymous provisioning; need to require both
331 	 * completed inner EAP authentication (EAP-pwd or EAP-EKE) and TNC */
332 
333 	if (data->anon_provisioning &&
334 	    !eap_teap_allowed_anon_prov_phase2_method(type)) {
335 		wpa_printf(MSG_INFO,
336 			   "EAP-TEAP: EAP type %u not allowed during unauthenticated provisioning",
337 			   type);
338 		return -1;
339 	}
340 
341 #ifdef EAP_TNC
342 	if (type == EAP_TYPE_TNC) {
343 		data->phase2_type.vendor = EAP_VENDOR_IETF;
344 		data->phase2_type.method = EAP_TYPE_TNC;
345 		wpa_printf(MSG_DEBUG,
346 			   "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d for TNC",
347 			   data->phase2_type.vendor,
348 			   data->phase2_type.method);
349 		return 0;
350 	}
351 #endif /* EAP_TNC */
352 
353 	for (i = 0; i < data->num_phase2_types; i++) {
354 		if (data->phase2_types[i].vendor != EAP_VENDOR_IETF ||
355 		    data->phase2_types[i].method != type)
356 			continue;
357 
358 		data->phase2_type.vendor = data->phase2_types[i].vendor;
359 		data->phase2_type.method = data->phase2_types[i].method;
360 		wpa_printf(MSG_DEBUG,
361 			   "EAP-TEAP: Selected Phase 2 EAP vendor %d method %d",
362 			   data->phase2_type.vendor,
363 			   data->phase2_type.method);
364 		break;
365 	}
366 
367 	if (type != data->phase2_type.method || type == EAP_TYPE_NONE)
368 		return -1;
369 
370 	return 0;
371 }
372 
373 
374 static int eap_teap_phase2_request(struct eap_sm *sm,
375 				   struct eap_teap_data *data,
376 				   struct eap_method_ret *ret,
377 				   struct eap_hdr *hdr,
378 				   struct wpabuf **resp)
379 {
380 	size_t len = be_to_host16(hdr->length);
381 	u8 *pos;
382 	struct eap_method_ret iret;
383 	struct eap_peer_config *config = eap_get_config(sm);
384 	struct wpabuf msg;
385 
386 	if (len <= sizeof(struct eap_hdr)) {
387 		wpa_printf(MSG_INFO,
388 			   "EAP-TEAP: too short Phase 2 request (len=%lu)",
389 			   (unsigned long) len);
390 		return -1;
391 	}
392 	pos = (u8 *) (hdr + 1);
393 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 Request: type=%d", *pos);
394 	if (*pos == EAP_TYPE_IDENTITY) {
395 		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
396 		return 0;
397 	}
398 
399 	if (data->phase2_priv && data->phase2_method &&
400 	    *pos != data->phase2_type.method) {
401 		wpa_printf(MSG_DEBUG,
402 			   "EAP-TEAP: Phase 2 EAP sequence - deinitialize previous method");
403 		data->phase2_method->deinit(sm, data->phase2_priv);
404 		data->phase2_method = NULL;
405 		data->phase2_priv = NULL;
406 		data->phase2_type.vendor = EAP_VENDOR_IETF;
407 		data->phase2_type.method = EAP_TYPE_NONE;
408 	}
409 
410 	if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
411 	    data->phase2_type.method == EAP_TYPE_NONE &&
412 	    eap_teap_select_phase2_method(data, *pos) < 0) {
413 		if (eap_peer_tls_phase2_nak(data->phase2_types,
414 					    data->num_phase2_types,
415 					    hdr, resp))
416 			return -1;
417 		return 0;
418 	}
419 
420 	if ((!data->phase2_priv && eap_teap_init_phase2_method(sm, data) < 0) ||
421 	    !data->phase2_method) {
422 		wpa_printf(MSG_INFO,
423 			   "EAP-TEAP: Failed to initialize Phase 2 EAP method %d",
424 			   *pos);
425 		ret->methodState = METHOD_DONE;
426 		ret->decision = DECISION_FAIL;
427 		return -1;
428 	}
429 
430 	os_memset(&iret, 0, sizeof(iret));
431 	wpabuf_set(&msg, hdr, len);
432 	*resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
433 					     &msg);
434 	if (iret.methodState == METHOD_DONE)
435 		data->inner_method_done = 1;
436 	if (!(*resp) ||
437 	    (iret.methodState == METHOD_DONE &&
438 	     iret.decision == DECISION_FAIL)) {
439 		ret->methodState = METHOD_DONE;
440 		ret->decision = DECISION_FAIL;
441 	} else if ((iret.methodState == METHOD_DONE ||
442 		    iret.methodState == METHOD_MAY_CONT) &&
443 		   (iret.decision == DECISION_UNCOND_SUCC ||
444 		    iret.decision == DECISION_COND_SUCC)) {
445 		data->phase2_success = 1;
446 	}
447 
448 	if (!(*resp) && config &&
449 	    (config->pending_req_identity || config->pending_req_password ||
450 	     config->pending_req_otp || config->pending_req_new_password ||
451 	     config->pending_req_sim)) {
452 		wpabuf_free(data->pending_phase2_req);
453 		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
454 	} else if (!(*resp))
455 		return -1;
456 
457 	return 0;
458 }
459 
460 
461 static struct wpabuf * eap_teap_tlv_nak(int vendor_id, int tlv_type)
462 {
463 	struct wpabuf *buf;
464 	struct teap_tlv_nak *nak;
465 
466 	wpa_printf(MSG_DEBUG,
467 		   "EAP-TEAP: Add NAK TLV (Vendor-Id %u NAK-Type %u)",
468 		   vendor_id, tlv_type);
469 	buf = wpabuf_alloc(sizeof(*nak));
470 	if (!buf)
471 		return NULL;
472 	nak = wpabuf_put(buf, sizeof(*nak));
473 	nak->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_NAK);
474 	nak->length = host_to_be16(6);
475 	nak->vendor_id = host_to_be32(vendor_id);
476 	nak->nak_type = host_to_be16(tlv_type);
477 	return buf;
478 }
479 
480 
481 static struct wpabuf * eap_teap_tlv_pac_ack(void)
482 {
483 	struct wpabuf *buf;
484 	struct teap_tlv_result *res;
485 	struct teap_tlv_pac_ack *ack;
486 
487 	buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack));
488 	if (!buf)
489 		return NULL;
490 
491 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (ack)");
492 	ack = wpabuf_put(buf, sizeof(*ack));
493 	ack->tlv_type = host_to_be16(TEAP_TLV_PAC | TEAP_TLV_MANDATORY);
494 	ack->length = host_to_be16(sizeof(*ack) - sizeof(struct teap_tlv_hdr));
495 	ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
496 	ack->pac_len = host_to_be16(2);
497 	ack->result = host_to_be16(TEAP_STATUS_SUCCESS);
498 
499 	return buf;
500 }
501 
502 
503 static struct wpabuf * eap_teap_process_eap_payload_tlv(
504 	struct eap_sm *sm, struct eap_teap_data *data,
505 	struct eap_method_ret *ret,
506 	u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
507 {
508 	struct eap_hdr *hdr;
509 	struct wpabuf *resp = NULL;
510 
511 	if (eap_payload_tlv_len < sizeof(*hdr)) {
512 		wpa_printf(MSG_DEBUG,
513 			   "EAP-TEAP: too short EAP Payload TLV (len=%lu)",
514 			   (unsigned long) eap_payload_tlv_len);
515 		return NULL;
516 	}
517 
518 	hdr = (struct eap_hdr *) eap_payload_tlv;
519 	if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
520 		wpa_printf(MSG_DEBUG,
521 			   "EAP-TEAP: EAP packet overflow in EAP Payload TLV");
522 		return NULL;
523 	}
524 
525 	if (hdr->code != EAP_CODE_REQUEST) {
526 		wpa_printf(MSG_INFO,
527 			   "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
528 			   hdr->code);
529 		return NULL;
530 	}
531 
532 	if (eap_teap_phase2_request(sm, data, ret, hdr, &resp)) {
533 		wpa_printf(MSG_INFO,
534 			   "EAP-TEAP: Phase 2 Request processing failed");
535 		return NULL;
536 	}
537 
538 	return eap_teap_tlv_eap_payload(resp);
539 }
540 
541 
542 static struct wpabuf * eap_teap_process_basic_auth_req(
543 	struct eap_sm *sm, struct eap_teap_data *data,
544 	u8 *basic_auth_req, size_t basic_auth_req_len)
545 {
546 	const u8 *identity, *password;
547 	size_t identity_len, password_len, plen;
548 	struct wpabuf *resp;
549 
550 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Req prompt",
551 			  basic_auth_req, basic_auth_req_len);
552 	/* TODO: send over control interface */
553 
554 	identity = eap_get_config_identity(sm, &identity_len);
555 	password = eap_get_config_password(sm, &password_len);
556 	if (!identity || !password ||
557 	    identity_len > 255 || password_len > 255) {
558 		wpa_printf(MSG_DEBUG,
559 			   "EAP-TEAP: No username/password suitable for Basic-Password-Auth");
560 		return eap_teap_tlv_nak(0, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ);
561 	}
562 
563 	plen = 1 + identity_len + 1 + password_len;
564 	resp = wpabuf_alloc(sizeof(struct teap_tlv_hdr) + plen);
565 	if (!resp)
566 		return NULL;
567 	eap_teap_put_tlv_hdr(resp, TEAP_TLV_BASIC_PASSWORD_AUTH_RESP, plen);
568 	wpabuf_put_u8(resp, identity_len);
569 	wpabuf_put_data(resp, identity, identity_len);
570 	wpabuf_put_u8(resp, password_len);
571 	wpabuf_put_data(resp, password, password_len);
572 	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Basic-Password-Auth-Resp",
573 			    resp);
574 
575 	/* Assume this succeeds so that Result TLV(Success) from the server can
576 	 * be used to terminate TEAP. */
577 	data->phase2_success = 1;
578 
579 	return resp;
580 }
581 
582 
583 static int
584 eap_teap_validate_crypto_binding(struct eap_teap_data *data,
585 				 const struct teap_tlv_crypto_binding *cb)
586 {
587 	u8 flags, subtype;
588 
589 	subtype = cb->subtype & 0x0f;
590 	flags = cb->subtype >> 4;
591 
592 	wpa_printf(MSG_DEBUG,
593 		   "EAP-TEAP: Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
594 		   cb->version, cb->received_version, flags, subtype);
595 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
596 		    cb->nonce, sizeof(cb->nonce));
597 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
598 		    cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
599 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
600 		    cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
601 
602 	if (cb->version != EAP_TEAP_VERSION ||
603 	    cb->received_version != data->received_version ||
604 	    subtype != TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST ||
605 	    flags < 1 || flags > 3) {
606 		wpa_printf(MSG_INFO,
607 			   "EAP-TEAP: Invalid Version/Flags/Sub-Type in Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
608 			   cb->version, cb->received_version, flags, subtype);
609 		return -1;
610 	}
611 
612 	if (cb->nonce[EAP_TEAP_NONCE_LEN - 1] & 0x01) {
613 		wpa_printf(MSG_INFO,
614 			   "EAP-TEAP: Invalid Crypto-Binding TLV Nonce in request");
615 		return -1;
616 	}
617 
618 	return 0;
619 }
620 
621 
622 static int eap_teap_write_crypto_binding(
623 	struct eap_teap_data *data,
624 	struct teap_tlv_crypto_binding *rbind,
625 	const struct teap_tlv_crypto_binding *cb,
626 	const u8 *cmk_msk, const u8 *cmk_emsk)
627 {
628 	u8 subtype, flags;
629 
630 	rbind->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
631 				       TEAP_TLV_CRYPTO_BINDING);
632 	rbind->length = host_to_be16(sizeof(*rbind) -
633 				     sizeof(struct teap_tlv_hdr));
634 	rbind->version = EAP_TEAP_VERSION;
635 	rbind->received_version = data->received_version;
636 	/* FIX: RFC 7170 is not clear on which Flags value to use when
637 	 * Crypto-Binding TLV is used with Basic-Password-Auth */
638 	flags = cmk_emsk ? TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
639 		TEAP_CRYPTO_BINDING_MSK_CMAC;
640 	subtype = TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE;
641 	rbind->subtype = (flags << 4) | subtype;
642 	os_memcpy(rbind->nonce, cb->nonce, sizeof(cb->nonce));
643 	inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
644 	os_memset(rbind->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
645 	os_memset(rbind->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
646 
647 	if (eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
648 				  data->peer_outer_tlvs, cmk_msk,
649 				  rbind->msk_compound_mac) < 0)
650 		return -1;
651 	if (cmk_emsk &&
652 	    eap_teap_compound_mac(data->tls_cs, rbind, data->server_outer_tlvs,
653 				  data->peer_outer_tlvs, cmk_emsk,
654 				  rbind->emsk_compound_mac) < 0)
655 		return -1;
656 
657 	wpa_printf(MSG_DEBUG,
658 		   "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u SubType %u",
659 		   rbind->version, rbind->received_version, flags, subtype);
660 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
661 		    rbind->nonce, sizeof(rbind->nonce));
662 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
663 		    rbind->emsk_compound_mac, sizeof(rbind->emsk_compound_mac));
664 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
665 		    rbind->msk_compound_mac, sizeof(rbind->msk_compound_mac));
666 
667 	return 0;
668 }
669 
670 
671 static int eap_teap_get_cmk(struct eap_sm *sm, struct eap_teap_data *data,
672 			    u8 *cmk_msk, u8 *cmk_emsk)
673 {
674 	u8 *msk = NULL, *emsk = NULL;
675 	size_t msk_len = 0, emsk_len = 0;
676 	int res;
677 
678 	wpa_printf(MSG_DEBUG,
679 		   "EAP-TEAP: Determining CMK[%d] for Compound MAC calculation",
680 		   data->simck_idx + 1);
681 
682 	if (!data->phase2_method)
683 		return eap_teap_derive_cmk_basic_pw_auth(data->simck_msk,
684 							 cmk_msk);
685 
686 	if (!data->phase2_method || !data->phase2_priv) {
687 		wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
688 		return -1;
689 	}
690 
691 	if (data->phase2_method->isKeyAvailable &&
692 	    !data->phase2_method->isKeyAvailable(sm, data->phase2_priv)) {
693 		wpa_printf(MSG_INFO,
694 			   "EAP-TEAP: Phase 2 key material not available");
695 		return -1;
696 	}
697 
698 	if (data->phase2_method->isKeyAvailable &&
699 	    data->phase2_method->getKey) {
700 		msk = data->phase2_method->getKey(sm, data->phase2_priv,
701 						  &msk_len);
702 		if (!msk) {
703 			wpa_printf(MSG_INFO,
704 				   "EAP-TEAP: Could not fetch Phase 2 MSK");
705 			return -1;
706 		}
707 	}
708 
709 	if (data->phase2_method->isKeyAvailable &&
710 	    data->phase2_method->get_emsk) {
711 		emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
712 						     &emsk_len);
713 	}
714 
715 	res = eap_teap_derive_imck(data->simck_msk, data->simck_emsk,
716 				   msk, msk_len, emsk, emsk_len,
717 				   data->simck_msk, cmk_msk,
718 				   data->simck_emsk, cmk_emsk);
719 	bin_clear_free(msk, msk_len);
720 	bin_clear_free(emsk, emsk_len);
721 	if (res == 0) {
722 		data->simck_idx++;
723 		if (emsk)
724 			data->cmk_emsk_available = 1;
725 	}
726 	return res;
727 }
728 
729 
730 static int eap_teap_session_id(struct eap_teap_data *data)
731 {
732 	const size_t max_id_len = 100;
733 	int res;
734 
735 	os_free(data->session_id);
736 	data->session_id = os_malloc(max_id_len);
737 	if (!data->session_id)
738 		return -1;
739 
740 	data->session_id[0] = EAP_TYPE_TEAP;
741 	res = tls_get_tls_unique(data->ssl.conn, data->session_id + 1,
742 				 max_id_len - 1);
743 	if (res < 0) {
744 		os_free(data->session_id);
745 		data->session_id = NULL;
746 		wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
747 		return -1;
748 	}
749 
750 	data->id_len = 1 + res;
751 	wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id",
752 		    data->session_id, data->id_len);
753 	return 0;
754 }
755 
756 
757 static struct wpabuf * eap_teap_process_crypto_binding(
758 	struct eap_sm *sm, struct eap_teap_data *data,
759 	struct eap_method_ret *ret,
760 	const struct teap_tlv_crypto_binding *cb, size_t bind_len)
761 {
762 	struct wpabuf *resp;
763 	u8 *pos;
764 	u8 cmk_msk[EAP_TEAP_CMK_LEN];
765 	u8 cmk_emsk[EAP_TEAP_CMK_LEN];
766 	const u8 *cmk_emsk_ptr = NULL;
767 	int res;
768 	size_t len;
769 	u8 flags;
770 
771 	if (eap_teap_validate_crypto_binding(data, cb) < 0 ||
772 	    eap_teap_get_cmk(sm, data, cmk_msk, cmk_emsk) < 0)
773 		return NULL;
774 
775 	/* Validate received MSK/EMSK Compound MAC */
776 	flags = cb->subtype >> 4;
777 
778 	if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
779 	    flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
780 		u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
781 
782 		if (eap_teap_compound_mac(data->tls_cs, cb,
783 					  data->server_outer_tlvs,
784 					  data->peer_outer_tlvs, cmk_msk,
785 					  msk_compound_mac) < 0)
786 			return NULL;
787 		res = os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
788 				      EAP_TEAP_COMPOUND_MAC_LEN);
789 		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received MSK Compound MAC",
790 			    cb->msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
791 		wpa_hexdump(MSG_MSGDUMP,
792 			    "EAP-TEAP: Calculated MSK Compound MAC",
793 			    msk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
794 		if (res != 0) {
795 			wpa_printf(MSG_INFO,
796 				   "EAP-TEAP: MSK Compound MAC did not match");
797 			return NULL;
798 		}
799 	}
800 
801 	if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
802 	     flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
803 	    data->cmk_emsk_available) {
804 		u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
805 
806 		if (eap_teap_compound_mac(data->tls_cs, cb,
807 					  data->server_outer_tlvs,
808 					  data->peer_outer_tlvs, cmk_emsk,
809 					  emsk_compound_mac) < 0)
810 			return NULL;
811 		res = os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
812 				      EAP_TEAP_COMPOUND_MAC_LEN);
813 		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Received EMSK Compound MAC",
814 			    cb->emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
815 		wpa_hexdump(MSG_MSGDUMP,
816 			    "EAP-TEAP: Calculated EMSK Compound MAC",
817 			    emsk_compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
818 		if (res != 0) {
819 			wpa_printf(MSG_INFO,
820 				   "EAP-TEAP: EMSK Compound MAC did not match");
821 			return NULL;
822 		}
823 
824 		cmk_emsk_ptr = cmk_emsk;
825 	}
826 
827 	if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
828 	    !data->cmk_emsk_available) {
829 		wpa_printf(MSG_INFO,
830 			   "EAP-TEAP: Server included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
831 		return NULL;
832 	}
833 
834 	/*
835 	 * Compound MAC was valid, so authentication succeeded. Reply with
836 	 * crypto binding to allow server to complete authentication.
837 	 */
838 
839 	len = sizeof(struct teap_tlv_crypto_binding);
840 	resp = wpabuf_alloc(len);
841 	if (!resp)
842 		return NULL;
843 
844 	if (data->phase2_success && eap_teap_derive_msk(data) < 0) {
845 		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to generate MSK");
846 		ret->methodState = METHOD_DONE;
847 		ret->decision = DECISION_FAIL;
848 		data->phase2_success = 0;
849 		wpabuf_free(resp);
850 		return NULL;
851 	}
852 
853 	if (data->phase2_success && eap_teap_session_id(data) < 0) {
854 		wpabuf_free(resp);
855 		return NULL;
856 	}
857 
858 	pos = wpabuf_put(resp, sizeof(struct teap_tlv_crypto_binding));
859 	if (eap_teap_write_crypto_binding(
860 		    data, (struct teap_tlv_crypto_binding *) pos,
861 		    cb, cmk_msk, cmk_emsk_ptr) < 0) {
862 		wpabuf_free(resp);
863 		return NULL;
864 	}
865 
866 	return resp;
867 }
868 
869 
870 static void eap_teap_parse_pac_tlv(struct eap_teap_pac *entry, int type,
871 				   u8 *pos, size_t len, int *pac_key_found)
872 {
873 	switch (type & 0x7fff) {
874 	case PAC_TYPE_PAC_KEY:
875 		wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: PAC-Key", pos, len);
876 		if (len != EAP_TEAP_PAC_KEY_LEN) {
877 			wpa_printf(MSG_DEBUG,
878 				   "EAP-TEAP: Invalid PAC-Key length %lu",
879 				   (unsigned long) len);
880 			break;
881 		}
882 		*pac_key_found = 1;
883 		os_memcpy(entry->pac_key, pos, len);
884 		break;
885 	case PAC_TYPE_PAC_OPAQUE:
886 		wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pos, len);
887 		entry->pac_opaque = pos;
888 		entry->pac_opaque_len = len;
889 		break;
890 	case PAC_TYPE_PAC_INFO:
891 		wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Info", pos, len);
892 		entry->pac_info = pos;
893 		entry->pac_info_len = len;
894 		break;
895 	default:
896 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignored unknown PAC type %d",
897 			   type);
898 		break;
899 	}
900 }
901 
902 
903 static int eap_teap_process_pac_tlv(struct eap_teap_pac *entry,
904 				    u8 *pac, size_t pac_len)
905 {
906 	struct pac_attr_hdr *hdr;
907 	u8 *pos;
908 	size_t left, len;
909 	int type, pac_key_found = 0;
910 
911 	pos = pac;
912 	left = pac_len;
913 
914 	while (left > sizeof(*hdr)) {
915 		hdr = (struct pac_attr_hdr *) pos;
916 		type = be_to_host16(hdr->type);
917 		len = be_to_host16(hdr->len);
918 		pos += sizeof(*hdr);
919 		left -= sizeof(*hdr);
920 		if (len > left) {
921 			wpa_printf(MSG_DEBUG,
922 				   "EAP-TEAP: PAC TLV overrun (type=%d len=%lu left=%lu)",
923 				   type, (unsigned long) len,
924 				   (unsigned long) left);
925 			return -1;
926 		}
927 
928 		eap_teap_parse_pac_tlv(entry, type, pos, len, &pac_key_found);
929 
930 		pos += len;
931 		left -= len;
932 	}
933 
934 	if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) {
935 		wpa_printf(MSG_DEBUG,
936 			   "EAP-TEAP: PAC TLV does not include all the required fields");
937 		return -1;
938 	}
939 
940 	return 0;
941 }
942 
943 
944 static int eap_teap_parse_pac_info(struct eap_teap_pac *entry, int type,
945 				   u8 *pos, size_t len)
946 {
947 	u16 pac_type;
948 	u32 lifetime;
949 	struct os_time now;
950 
951 	switch (type & 0x7fff) {
952 	case PAC_TYPE_CRED_LIFETIME:
953 		if (len != 4) {
954 			wpa_hexdump(MSG_DEBUG,
955 				    "EAP-TEAP: PAC-Info - Invalid CRED_LIFETIME length - ignored",
956 				    pos, len);
957 			return 0;
958 		}
959 
960 		/*
961 		 * This is not currently saved separately in PAC files since
962 		 * the server can automatically initiate PAC update when
963 		 * needed. Anyway, the information is available from PAC-Info
964 		 * dump if it is needed for something in the future.
965 		 */
966 		lifetime = WPA_GET_BE32(pos);
967 		os_get_time(&now);
968 		wpa_printf(MSG_DEBUG,
969 			   "EAP-TEAP: PAC-Info - CRED_LIFETIME %d (%d days)",
970 			   lifetime, (lifetime - (u32) now.sec) / 86400);
971 		break;
972 	case PAC_TYPE_A_ID:
973 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID",
974 				  pos, len);
975 		entry->a_id = pos;
976 		entry->a_id_len = len;
977 		break;
978 	case PAC_TYPE_I_ID:
979 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - I-ID",
980 				  pos, len);
981 		entry->i_id = pos;
982 		entry->i_id_len = len;
983 		break;
984 	case PAC_TYPE_A_ID_INFO:
985 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Info - A-ID-Info",
986 				  pos, len);
987 		entry->a_id_info = pos;
988 		entry->a_id_info_len = len;
989 		break;
990 	case PAC_TYPE_PAC_TYPE:
991 		/* RFC 7170, Section 4.2.12.6 - PAC-Type TLV */
992 		if (len != 2) {
993 			wpa_printf(MSG_INFO,
994 				   "EAP-TEAP: Invalid PAC-Type length %lu (expected 2)",
995 				   (unsigned long) len);
996 			wpa_hexdump_ascii(MSG_DEBUG,
997 					  "EAP-TEAP: PAC-Info - PAC-Type",
998 					  pos, len);
999 			return -1;
1000 		}
1001 		pac_type = WPA_GET_BE16(pos);
1002 		if (pac_type != PAC_TYPE_TUNNEL_PAC) {
1003 			wpa_printf(MSG_INFO,
1004 				   "EAP-TEAP: Unsupported PAC Type %d",
1005 				   pac_type);
1006 			return -1;
1007 		}
1008 
1009 		wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Info - PAC-Type %d",
1010 			   pac_type);
1011 		entry->pac_type = pac_type;
1012 		break;
1013 	default:
1014 		wpa_printf(MSG_DEBUG,
1015 			   "EAP-TEAP: Ignored unknown PAC-Info type %d", type);
1016 		break;
1017 	}
1018 
1019 	return 0;
1020 }
1021 
1022 
1023 static int eap_teap_process_pac_info(struct eap_teap_pac *entry)
1024 {
1025 	struct pac_attr_hdr *hdr;
1026 	u8 *pos;
1027 	size_t left, len;
1028 	int type;
1029 
1030 	/* RFC 7170, Section 4.2.12.4 */
1031 
1032 	/* PAC-Type defaults to Tunnel PAC (Type 1) */
1033 	entry->pac_type = PAC_TYPE_TUNNEL_PAC;
1034 
1035 	pos = entry->pac_info;
1036 	left = entry->pac_info_len;
1037 	while (left > sizeof(*hdr)) {
1038 		hdr = (struct pac_attr_hdr *) pos;
1039 		type = be_to_host16(hdr->type);
1040 		len = be_to_host16(hdr->len);
1041 		pos += sizeof(*hdr);
1042 		left -= sizeof(*hdr);
1043 		if (len > left) {
1044 			wpa_printf(MSG_DEBUG,
1045 				   "EAP-TEAP: PAC-Info overrun (type=%d len=%lu left=%lu)",
1046 				   type, (unsigned long) len,
1047 				   (unsigned long) left);
1048 			return -1;
1049 		}
1050 
1051 		if (eap_teap_parse_pac_info(entry, type, pos, len) < 0)
1052 			return -1;
1053 
1054 		pos += len;
1055 		left -= len;
1056 	}
1057 
1058 	if (!entry->a_id || !entry->a_id_info) {
1059 		wpa_printf(MSG_DEBUG,
1060 			   "EAP-TEAP: PAC-Info does not include all the required fields");
1061 		return -1;
1062 	}
1063 
1064 	return 0;
1065 }
1066 
1067 
1068 static struct wpabuf * eap_teap_process_pac(struct eap_sm *sm,
1069 					    struct eap_teap_data *data,
1070 					    struct eap_method_ret *ret,
1071 					    u8 *pac, size_t pac_len)
1072 {
1073 	struct eap_peer_config *config = eap_get_config(sm);
1074 	struct eap_teap_pac entry;
1075 
1076 	os_memset(&entry, 0, sizeof(entry));
1077 	if (eap_teap_process_pac_tlv(&entry, pac, pac_len) ||
1078 	    eap_teap_process_pac_info(&entry))
1079 		return NULL;
1080 
1081 	eap_teap_add_pac(&data->pac, &data->current_pac, &entry);
1082 	eap_teap_pac_list_truncate(data->pac, data->max_pac_list_len);
1083 	if (data->use_pac_binary_format)
1084 		eap_teap_save_pac_bin(sm, data->pac, config->pac_file);
1085 	else
1086 		eap_teap_save_pac(sm, data->pac, config->pac_file);
1087 
1088 	wpa_printf(MSG_DEBUG,
1089 		   "EAP-TEAP: Send PAC-Acknowledgement - %s initiated provisioning completed successfully",
1090 		   data->provisioning ? "peer" : "server");
1091 	return eap_teap_tlv_pac_ack();
1092 }
1093 
1094 
1095 static int eap_teap_parse_decrypted(struct wpabuf *decrypted,
1096 				    struct eap_teap_tlv_parse *tlv,
1097 				    struct wpabuf **resp)
1098 {
1099 	u16 tlv_type;
1100 	int mandatory, res;
1101 	size_t len;
1102 	u8 *pos, *end;
1103 
1104 	os_memset(tlv, 0, sizeof(*tlv));
1105 
1106 	/* Parse TLVs from the decrypted Phase 2 data */
1107 	pos = wpabuf_mhead(decrypted);
1108 	end = pos + wpabuf_len(decrypted);
1109 	while (end - pos >= 4) {
1110 		mandatory = pos[0] & 0x80;
1111 		tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1112 		pos += 2;
1113 		len = WPA_GET_BE16(pos);
1114 		pos += 2;
1115 		if (len > (size_t) (end - pos)) {
1116 			wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1117 			return -1;
1118 		}
1119 		wpa_printf(MSG_DEBUG,
1120 			   "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1121 			   tlv_type, eap_teap_tlv_type_str(tlv_type),
1122 			   (unsigned int) len,
1123 			   mandatory ? " (mandatory)" : "");
1124 
1125 		res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
1126 		if (res == -2)
1127 			break;
1128 		if (res < 0) {
1129 			if (mandatory) {
1130 				wpa_printf(MSG_DEBUG,
1131 					   "EAP-TEAP: NAK unknown mandatory TLV type %u",
1132 					   tlv_type);
1133 				*resp = eap_teap_tlv_nak(0, tlv_type);
1134 				break;
1135 			}
1136 
1137 			wpa_printf(MSG_DEBUG,
1138 				   "EAP-TEAP: Ignore unknown optional TLV type %u",
1139 				   tlv_type);
1140 		}
1141 
1142 		pos += len;
1143 	}
1144 
1145 	return 0;
1146 }
1147 
1148 
1149 static struct wpabuf * eap_teap_pac_request(void)
1150 {
1151 	struct wpabuf *req;
1152 	struct teap_tlv_request_action *act;
1153 	struct teap_tlv_hdr *pac;
1154 	struct teap_attr_pac_type *type;
1155 
1156 	req = wpabuf_alloc(sizeof(*act) + sizeof(*pac) + sizeof(*type));
1157 	if (!req)
1158 		return NULL;
1159 
1160 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Request Action TLV (Process TLV)");
1161 	act = wpabuf_put(req, sizeof(*act));
1162 	act->tlv_type = host_to_be16(TEAP_TLV_REQUEST_ACTION);
1163 	act->length = host_to_be16(2);
1164 	act->status = TEAP_STATUS_SUCCESS;
1165 	act->action = TEAP_REQUEST_ACTION_PROCESS_TLV;
1166 
1167 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV (PAC-Type = Tunnel)");
1168 	pac = wpabuf_put(req, sizeof(*pac));
1169 	pac->tlv_type = host_to_be16(TEAP_TLV_PAC);
1170 	pac->length = host_to_be16(sizeof(*type));
1171 
1172 	type = wpabuf_put(req, sizeof(*type));
1173 	type->type = host_to_be16(PAC_TYPE_PAC_TYPE);
1174 	type->length = host_to_be16(2);
1175 	type->pac_type = host_to_be16(PAC_TYPE_TUNNEL_PAC);
1176 
1177 	return req;
1178 }
1179 
1180 
1181 static int eap_teap_process_decrypted(struct eap_sm *sm,
1182 				      struct eap_teap_data *data,
1183 				      struct eap_method_ret *ret,
1184 				      u8 identifier,
1185 				      struct wpabuf *decrypted,
1186 				      struct wpabuf **out_data)
1187 {
1188 	struct wpabuf *resp = NULL, *tmp;
1189 	struct eap_teap_tlv_parse tlv;
1190 	int failed = 0;
1191 	enum teap_error_codes error = 0;
1192 
1193 	if (eap_teap_parse_decrypted(decrypted, &tlv, &resp) < 0) {
1194 		/* Parsing failed - no response available */
1195 		return 0;
1196 	}
1197 
1198 	if (resp) {
1199 		/* Parsing rejected the message - send out an error response */
1200 		goto send_resp;
1201 	}
1202 
1203 	if (tlv.result == TEAP_STATUS_FAILURE) {
1204 		/* Server indicated failure - respond similarly per
1205 		 * RFC 7170, 3.6.3. This authentication exchange cannot succeed
1206 		 * and will be terminated with a cleartext EAP Failure. */
1207 		wpa_printf(MSG_DEBUG,
1208 			   "EAP-TEAP: Server rejected authentication");
1209 		resp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
1210 		ret->methodState = METHOD_DONE;
1211 		ret->decision = DECISION_FAIL;
1212 		goto send_resp;
1213 	}
1214 
1215 	if ((tlv.iresult == TEAP_STATUS_SUCCESS ||
1216 	     (!data->result_success_done &&
1217 	      tlv.result == TEAP_STATUS_SUCCESS)) &&
1218 	    !tlv.crypto_binding) {
1219 		/* Result TLV or Intermediate-Result TLV indicating success,
1220 		 * but no Crypto-Binding TLV */
1221 		wpa_printf(MSG_DEBUG,
1222 			   "EAP-TEAP: Result TLV or Intermediate-Result TLV indicating success, but no Crypto-Binding TLV");
1223 		failed = 1;
1224 		error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1225 		goto done;
1226 	}
1227 
1228 	if (tlv.iresult != TEAP_STATUS_SUCCESS &&
1229 	    tlv.iresult != TEAP_STATUS_FAILURE &&
1230 	    data->inner_method_done) {
1231 		wpa_printf(MSG_DEBUG,
1232 			   "EAP-TEAP: Inner EAP method exchange completed, but no Intermediate-Result TLV included");
1233 		failed = 1;
1234 		error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1235 		goto done;
1236 	}
1237 
1238 	if (tlv.basic_auth_req) {
1239 		tmp = eap_teap_process_basic_auth_req(sm, data,
1240 						      tlv.basic_auth_req,
1241 						      tlv.basic_auth_req_len);
1242 		if (!tmp)
1243 			failed = 1;
1244 		resp = wpabuf_concat(resp, tmp);
1245 	} else if (tlv.eap_payload_tlv) {
1246 		tmp = eap_teap_process_eap_payload_tlv(sm, data, ret,
1247 						       tlv.eap_payload_tlv,
1248 						       tlv.eap_payload_tlv_len);
1249 		if (!tmp)
1250 			failed = 1;
1251 		resp = wpabuf_concat(resp, tmp);
1252 
1253 		if (tlv.iresult == TEAP_STATUS_SUCCESS ||
1254 		    tlv.iresult == TEAP_STATUS_FAILURE) {
1255 			tmp = eap_teap_tlv_result(failed ?
1256 						  TEAP_STATUS_FAILURE :
1257 						  TEAP_STATUS_SUCCESS, 1);
1258 			resp = wpabuf_concat(resp, tmp);
1259 			if (tlv.iresult == TEAP_STATUS_FAILURE)
1260 				failed = 1;
1261 		}
1262 	}
1263 
1264 	if (tlv.crypto_binding) {
1265 		if (tlv.iresult != TEAP_STATUS_SUCCESS &&
1266 		    tlv.result != TEAP_STATUS_SUCCESS) {
1267 			wpa_printf(MSG_DEBUG,
1268 				   "EAP-TEAP: Unexpected Crypto-Binding TLV without Result TLV or Intermediate-Result TLV indicating success");
1269 			failed = 1;
1270 			error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
1271 			goto done;
1272 		}
1273 
1274 		tmp = eap_teap_process_crypto_binding(sm, data, ret,
1275 						      tlv.crypto_binding,
1276 						      tlv.crypto_binding_len);
1277 		if (!tmp) {
1278 			failed = 1;
1279 			error = TEAP_ERROR_TUNNEL_COMPROMISE_ERROR;
1280 		} else {
1281 			resp = wpabuf_concat(resp, tmp);
1282 			if (tlv.result == TEAP_STATUS_SUCCESS && !failed)
1283 				data->result_success_done = 1;
1284 			if (tlv.iresult == TEAP_STATUS_SUCCESS && !failed)
1285 				data->inner_method_done = 0;
1286 		}
1287 	}
1288 
1289 	if (data->result_success_done && data->session_ticket_used &&
1290 	    eap_teap_derive_msk(data) == 0) {
1291 		/* Assume the server might accept authentication without going
1292 		 * through inner authentication. */
1293 		wpa_printf(MSG_DEBUG,
1294 			   "EAP-TEAP: PAC used - server may decide to skip inner authentication");
1295 		ret->methodState = METHOD_MAY_CONT;
1296 		ret->decision = DECISION_COND_SUCC;
1297 	}
1298 
1299 	if (tlv.pac) {
1300 		if (tlv.result == TEAP_STATUS_SUCCESS) {
1301 			tmp = eap_teap_process_pac(sm, data, ret,
1302 						   tlv.pac, tlv.pac_len);
1303 			resp = wpabuf_concat(resp, tmp);
1304 		} else {
1305 			wpa_printf(MSG_DEBUG,
1306 				   "EAP-TEAP: PAC TLV without Result TLV acknowledging success");
1307 			failed = 1;
1308 			error = TEAP_ERROR_UNEXPECTED_TLVS_EXCHANGED;
1309 		}
1310 	}
1311 
1312 	if (!data->current_pac && data->provisioning && !failed && !tlv.pac &&
1313 	    tlv.crypto_binding &&
1314 	    (!data->anon_provisioning ||
1315 	     (data->phase2_success && data->phase2_method &&
1316 	      data->phase2_method->vendor == 0 &&
1317 	      eap_teap_allowed_anon_prov_cipher_suite(data->tls_cs) &&
1318 	      eap_teap_allowed_anon_prov_phase2_method(
1319 		      data->phase2_method->method))) &&
1320 	    (tlv.iresult == TEAP_STATUS_SUCCESS ||
1321 	     tlv.result == TEAP_STATUS_SUCCESS)) {
1322 		/*
1323 		 * Need to request Tunnel PAC when using authenticated
1324 		 * provisioning.
1325 		 */
1326 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Request Tunnel PAC");
1327 		tmp = eap_teap_pac_request();
1328 		resp = wpabuf_concat(resp, tmp);
1329 	}
1330 
1331 done:
1332 	if (failed) {
1333 		tmp = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
1334 		resp = wpabuf_concat(tmp, resp);
1335 
1336 		if (error != 0) {
1337 			tmp = eap_teap_tlv_error(error);
1338 			resp = wpabuf_concat(tmp, resp);
1339 		}
1340 
1341 		ret->methodState = METHOD_DONE;
1342 		ret->decision = DECISION_FAIL;
1343 	} else if (tlv.result == TEAP_STATUS_SUCCESS) {
1344 		tmp = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0);
1345 		resp = wpabuf_concat(tmp, resp);
1346 	}
1347 
1348 	if (resp && tlv.result == TEAP_STATUS_SUCCESS && !failed &&
1349 	    tlv.crypto_binding && data->phase2_success) {
1350 		/* Successfully completed Phase 2 */
1351 		wpa_printf(MSG_DEBUG,
1352 			   "EAP-TEAP: Authentication completed successfully");
1353 		ret->methodState = METHOD_MAY_CONT;
1354 		data->on_tx_completion = data->provisioning ?
1355 			METHOD_MAY_CONT : METHOD_DONE;
1356 		ret->decision = DECISION_UNCOND_SUCC;
1357 	}
1358 
1359 	if (!resp) {
1360 		wpa_printf(MSG_DEBUG,
1361 			   "EAP-TEAP: No recognized TLVs - send empty response packet");
1362 		resp = wpabuf_alloc(1);
1363 	}
1364 
1365 send_resp:
1366 	if (!resp)
1367 		return 0;
1368 
1369 	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 data", resp);
1370 	if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1371 				 data->teap_version, identifier,
1372 				 resp, out_data)) {
1373 		wpa_printf(MSG_INFO,
1374 			   "EAP-TEAP: Failed to encrypt a Phase 2 frame");
1375 	}
1376 	wpabuf_free(resp);
1377 
1378 	return 0;
1379 }
1380 
1381 
1382 static int eap_teap_decrypt(struct eap_sm *sm, struct eap_teap_data *data,
1383 			    struct eap_method_ret *ret, u8 identifier,
1384 			    const struct wpabuf *in_data,
1385 			    struct wpabuf **out_data)
1386 {
1387 	struct wpabuf *in_decrypted;
1388 	int res;
1389 
1390 	wpa_printf(MSG_DEBUG,
1391 		   "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1392 		   (unsigned long) wpabuf_len(in_data));
1393 
1394 	if (data->pending_phase2_req) {
1395 		wpa_printf(MSG_DEBUG,
1396 			   "EAP-TEAP: Pending Phase 2 request - skip decryption and use old data");
1397 		/* Clear TLS reassembly state. */
1398 		eap_peer_tls_reset_input(&data->ssl);
1399 
1400 		in_decrypted = data->pending_phase2_req;
1401 		data->pending_phase2_req = NULL;
1402 		goto continue_req;
1403 	}
1404 
1405 	if (wpabuf_len(in_data) == 0) {
1406 		/* Received TLS ACK - requesting more fragments */
1407 		res = eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TEAP,
1408 					   data->teap_version,
1409 					   identifier, NULL, out_data);
1410 		if (res == 0 && !data->ssl.tls_out &&
1411 		    data->on_tx_completion) {
1412 			wpa_printf(MSG_DEBUG,
1413 				   "EAP-TEAP: Mark authentication completed at full TX of fragments");
1414 			ret->methodState = data->on_tx_completion;
1415 			data->on_tx_completion = 0;
1416 			ret->decision = DECISION_UNCOND_SUCC;
1417 		}
1418 		return res;
1419 	}
1420 
1421 	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
1422 	if (res)
1423 		return res;
1424 
1425 continue_req:
1426 	wpa_hexdump_buf(MSG_MSGDUMP, "EAP-TEAP: Decrypted Phase 2 TLV(s)",
1427 			in_decrypted);
1428 
1429 	if (wpabuf_len(in_decrypted) < 4) {
1430 		wpa_printf(MSG_INFO,
1431 			   "EAP-TEAP: Too short Phase 2 TLV frame (len=%lu)",
1432 			   (unsigned long) wpabuf_len(in_decrypted));
1433 		wpabuf_free(in_decrypted);
1434 		return -1;
1435 	}
1436 
1437 	res = eap_teap_process_decrypted(sm, data, ret, identifier,
1438 					 in_decrypted, out_data);
1439 
1440 	wpabuf_free(in_decrypted);
1441 
1442 	return res;
1443 }
1444 
1445 
1446 static void eap_teap_select_pac(struct eap_teap_data *data,
1447 				const u8 *a_id, size_t a_id_len)
1448 {
1449 	if (!a_id)
1450 		return;
1451 	data->current_pac = eap_teap_get_pac(data->pac, a_id, a_id_len,
1452 					     PAC_TYPE_TUNNEL_PAC);
1453 	if (data->current_pac) {
1454 		wpa_printf(MSG_DEBUG,
1455 			   "EAP-TEAP: PAC found for this A-ID (PAC-Type %d)",
1456 			   data->current_pac->pac_type);
1457 		wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TEAP: A-ID-Info",
1458 				  data->current_pac->a_id_info,
1459 				  data->current_pac->a_id_info_len);
1460 	}
1461 }
1462 
1463 
1464 static int eap_teap_use_pac_opaque(struct eap_sm *sm,
1465 				   struct eap_teap_data *data,
1466 				   struct eap_teap_pac *pac)
1467 {
1468 	u8 *tlv;
1469 	size_t tlv_len, olen;
1470 	struct teap_tlv_hdr *ehdr;
1471 
1472 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC-Opaque TLS extension");
1473 	olen = pac->pac_opaque_len;
1474 	tlv_len = sizeof(*ehdr) + olen;
1475 	tlv = os_malloc(tlv_len);
1476 	if (tlv) {
1477 		ehdr = (struct teap_tlv_hdr *) tlv;
1478 		ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
1479 		ehdr->length = host_to_be16(olen);
1480 		os_memcpy(ehdr + 1, pac->pac_opaque, olen);
1481 	}
1482 	if (!tlv ||
1483 	    tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1484 					    TLS_EXT_PAC_OPAQUE,
1485 					    tlv, tlv_len) < 0) {
1486 		wpa_printf(MSG_DEBUG,
1487 			   "EAP-TEAP: Failed to add PAC-Opaque TLS extension");
1488 		os_free(tlv);
1489 		return -1;
1490 	}
1491 	os_free(tlv);
1492 
1493 	return 0;
1494 }
1495 
1496 
1497 static int eap_teap_clear_pac_opaque_ext(struct eap_sm *sm,
1498 					 struct eap_teap_data *data)
1499 {
1500 	if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
1501 					    TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
1502 		wpa_printf(MSG_DEBUG,
1503 			   "EAP-TEAP: Failed to remove PAC-Opaque TLS extension");
1504 		return -1;
1505 	}
1506 	return 0;
1507 }
1508 
1509 
1510 static int eap_teap_process_start(struct eap_sm *sm,
1511 				  struct eap_teap_data *data, u8 flags,
1512 				  const u8 *pos, size_t left)
1513 {
1514 	const u8 *a_id = NULL;
1515 	size_t a_id_len = 0;
1516 
1517 	/* TODO: Support (mostly theoretical) case of TEAP/Start request being
1518 	 * fragmented */
1519 
1520 	/* EAP-TEAP version negotiation (RFC 7170, Section 3.2) */
1521 	data->received_version = flags & EAP_TLS_VERSION_MASK;
1522 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Start (server ver=%u, own ver=%u)",
1523 		   data->received_version, data->teap_version);
1524 	if (data->received_version < 1) {
1525 		/* Version 1 was the first defined version, so reject 0 */
1526 		wpa_printf(MSG_INFO,
1527 			   "EAP-TEAP: Server used unknown TEAP version %u",
1528 			   data->received_version);
1529 		return -1;
1530 	}
1531 	if (data->received_version < data->teap_version)
1532 		data->teap_version = data->received_version;
1533 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Using TEAP version %d",
1534 		   data->teap_version);
1535 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message payload", pos, left);
1536 
1537 	/* Parse Authority-ID TLV from Outer TLVs, if present */
1538 	if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1539 		const u8 *outer_pos, *outer_end;
1540 		u32 outer_tlv_len;
1541 
1542 		if (left < 4) {
1543 			wpa_printf(MSG_INFO,
1544 				   "EAP-TEAP: Not enough room for the Outer TLV Length field");
1545 			return -1;
1546 		}
1547 
1548 		outer_tlv_len = WPA_GET_BE32(pos);
1549 		pos += 4;
1550 		left -= 4;
1551 
1552 		if (outer_tlv_len > left) {
1553 			wpa_printf(MSG_INFO,
1554 				   "EAP-TEAP: Truncated Outer TLVs field (Outer TLV Length: %u; remaining buffer: %u)",
1555 				   outer_tlv_len, (unsigned int) left);
1556 			return -1;
1557 		}
1558 
1559 		outer_pos = pos + left - outer_tlv_len;
1560 		outer_end = outer_pos + outer_tlv_len;
1561 		wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Start message Outer TLVs",
1562 			    outer_pos, outer_tlv_len);
1563 		wpabuf_free(data->server_outer_tlvs);
1564 		data->server_outer_tlvs = wpabuf_alloc_copy(outer_pos,
1565 							    outer_tlv_len);
1566 		if (!data->server_outer_tlvs)
1567 			return -1;
1568 		left -= outer_tlv_len;
1569 		if (left > 0) {
1570 			wpa_hexdump(MSG_INFO,
1571 				    "EAP-TEAP: Unexpected TLS Data in Start message",
1572 				    pos, left);
1573 			return -1;
1574 		}
1575 
1576 		while (outer_pos < outer_end) {
1577 			u16 tlv_type, tlv_len;
1578 
1579 			if (outer_end - outer_pos < 4) {
1580 				wpa_printf(MSG_INFO,
1581 					   "EAP-TEAP: Truncated Outer TLV header");
1582 				return -1;
1583 			}
1584 			tlv_type = WPA_GET_BE16(outer_pos);
1585 			outer_pos += 2;
1586 			tlv_len = WPA_GET_BE16(outer_pos);
1587 			outer_pos += 2;
1588 			/* Outer TLVs are required to be optional, so no need to
1589 			 * check the M flag */
1590 			tlv_type &= TEAP_TLV_TYPE_MASK;
1591 			wpa_printf(MSG_DEBUG,
1592 				   "EAP-TEAP: Outer TLV: Type=%u Length=%u",
1593 				   tlv_type, tlv_len);
1594 			if (outer_end - outer_pos < tlv_len) {
1595 				wpa_printf(MSG_INFO,
1596 					   "EAP-TEAP: Truncated Outer TLV (Type %u)",
1597 					   tlv_type);
1598 				return -1;
1599 			}
1600 			if (tlv_type == TEAP_TLV_AUTHORITY_ID) {
1601 				wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Authority-ID",
1602 					    outer_pos, tlv_len);
1603 				if (a_id) {
1604 					wpa_printf(MSG_INFO,
1605 						   "EAP-TEAP: Multiple Authority-ID TLVs in TEAP/Start");
1606 					return -1;
1607 				}
1608 				a_id = outer_pos;
1609 				a_id_len = tlv_len;
1610 			} else {
1611 				wpa_printf(MSG_DEBUG,
1612 					   "EAP-TEAP: Ignore unknown Outer TLV (Type %u)",
1613 					   tlv_type);
1614 			}
1615 			outer_pos += tlv_len;
1616 		}
1617 	} else if (left > 0) {
1618 		wpa_hexdump(MSG_INFO,
1619 			    "EAP-TEAP: Unexpected TLS Data in Start message",
1620 			    pos, left);
1621 		return -1;
1622 	}
1623 
1624 	eap_teap_select_pac(data, a_id, a_id_len);
1625 
1626 	if (data->resuming && data->current_pac) {
1627 		wpa_printf(MSG_DEBUG,
1628 			   "EAP-TEAP: Trying to resume session - do not add PAC-Opaque to TLS ClientHello");
1629 		if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
1630 			return -1;
1631 	} else if (data->current_pac) {
1632 		/*
1633 		 * PAC found for the A-ID and we are not resuming an old
1634 		 * session, so add PAC-Opaque extension to ClientHello.
1635 		 */
1636 		if (eap_teap_use_pac_opaque(sm, data, data->current_pac) < 0)
1637 			return -1;
1638 	} else if (data->provisioning_allowed) {
1639 		wpa_printf(MSG_DEBUG,
1640 			   "EAP-TEAP: No PAC found - starting provisioning");
1641 		if (eap_teap_clear_pac_opaque_ext(sm, data) < 0)
1642 			return -1;
1643 		data->provisioning = 1;
1644 	}
1645 
1646 	return 0;
1647 }
1648 
1649 
1650 #ifdef CONFIG_TESTING_OPTIONS
1651 static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
1652 						     struct wpabuf *resp)
1653 {
1654 	struct wpabuf *resp2;
1655 	u16 len;
1656 	const u8 *pos;
1657 	u8 flags;
1658 
1659 	wpabuf_free(data->peer_outer_tlvs);
1660 	data->peer_outer_tlvs = wpabuf_alloc(4 + 4);
1661 	if (!data->peer_outer_tlvs) {
1662 		wpabuf_free(resp);
1663 		return NULL;
1664 	}
1665 
1666 	/* Outer TLVs (dummy Vendor-Specific TLV for testing) */
1667 	wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
1668 	wpabuf_put_be16(data->peer_outer_tlvs, 4);
1669 	wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
1670 	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs",
1671 			data->peer_outer_tlvs);
1672 
1673 	wpa_hexdump_buf(MSG_DEBUG,
1674 			"EAP-TEAP: TEAP/Start response before modification",
1675 			resp);
1676 	resp2 = wpabuf_alloc(wpabuf_len(resp) + 4 +
1677 			     wpabuf_len(data->peer_outer_tlvs));
1678 	if (!resp2) {
1679 		wpabuf_free(resp);
1680 		return NULL;
1681 	}
1682 
1683 	pos = wpabuf_head(resp);
1684 	wpabuf_put_u8(resp2, *pos++); /* Code */
1685 	wpabuf_put_u8(resp2, *pos++); /* Identifier */
1686 	len = WPA_GET_BE16(pos);
1687 	pos += 2;
1688 	wpabuf_put_be16(resp2, len + 4 + wpabuf_len(data->peer_outer_tlvs));
1689 	wpabuf_put_u8(resp2, *pos++); /* Type */
1690 	/* Flags | Ver (with Outer TLV length included flag set to 1) */
1691 	flags = *pos++;
1692 	if (flags & (EAP_TEAP_FLAGS_OUTER_TLV_LEN |
1693 		     EAP_TLS_FLAGS_LENGTH_INCLUDED)) {
1694 		wpa_printf(MSG_INFO,
1695 			   "EAP-TEAP: Cannot add Outer TLVs for testing");
1696 		wpabuf_free(resp);
1697 		wpabuf_free(resp2);
1698 		return NULL;
1699 	}
1700 	flags |= EAP_TEAP_FLAGS_OUTER_TLV_LEN;
1701 	wpabuf_put_u8(resp2, flags);
1702 	/* Outer TLV Length */
1703 	wpabuf_put_be32(resp2, wpabuf_len(data->peer_outer_tlvs));
1704 	/* TLS Data */
1705 	wpabuf_put_data(resp2, pos, wpabuf_len(resp) - 6);
1706 	wpabuf_put_buf(resp2, data->peer_outer_tlvs); /* Outer TLVs */
1707 
1708 	wpabuf_free(resp);
1709 	wpa_hexdump_buf(MSG_DEBUG,
1710 			"EAP-TEAP: TEAP/Start response after modification",
1711 			resp2);
1712 	return resp2;
1713 }
1714 #endif /* CONFIG_TESTING_OPTIONS */
1715 
1716 
1717 static struct wpabuf * eap_teap_process(struct eap_sm *sm, void *priv,
1718 					struct eap_method_ret *ret,
1719 					const struct wpabuf *reqData)
1720 {
1721 	const struct eap_hdr *req;
1722 	size_t left;
1723 	int res;
1724 	u8 flags, id;
1725 	struct wpabuf *resp;
1726 	const u8 *pos;
1727 	struct eap_teap_data *data = priv;
1728 	struct wpabuf msg;
1729 
1730 	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TEAP, ret,
1731 					reqData, &left, &flags);
1732 	if (!pos)
1733 		return NULL;
1734 
1735 	req = wpabuf_head(reqData);
1736 	id = req->identifier;
1737 
1738 	if (flags & EAP_TLS_FLAGS_START) {
1739 		if (eap_teap_process_start(sm, data, flags, pos, left) < 0)
1740 			return NULL;
1741 
1742 		/* Outer TLVs are not used in further packet processing and
1743 		 * there cannot be TLS Data in this TEAP/Start message, so
1744 		 * enforce that by ignoring whatever data might remain in the
1745 		 * buffer. */
1746 		left = 0;
1747 	} else if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1748 		/* TODO: RFC 7170, Section 4.3.1 indicates that the unexpected
1749 		 * Outer TLVs MUST be ignored instead of ignoring the full
1750 		 * message. */
1751 		wpa_printf(MSG_INFO,
1752 			   "EAP-TEAP: Outer TLVs present in non-Start message -> ignore message");
1753 		return NULL;
1754 	}
1755 
1756 	wpabuf_set(&msg, pos, left);
1757 
1758 	resp = NULL;
1759 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
1760 	    !data->resuming) {
1761 		/* Process tunneled (encrypted) phase 2 data. */
1762 		res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
1763 		if (res < 0) {
1764 			ret->methodState = METHOD_DONE;
1765 			ret->decision = DECISION_FAIL;
1766 			/*
1767 			 * Ack possible Alert that may have caused failure in
1768 			 * decryption.
1769 			 */
1770 			res = 1;
1771 		}
1772 	} else {
1773 		if (sm->waiting_ext_cert_check && data->pending_resp) {
1774 			struct eap_peer_config *config = eap_get_config(sm);
1775 
1776 			if (config->pending_ext_cert_check ==
1777 			    EXT_CERT_CHECK_GOOD) {
1778 				wpa_printf(MSG_DEBUG,
1779 					   "EAP-TEAP: External certificate check succeeded - continue handshake");
1780 				resp = data->pending_resp;
1781 				data->pending_resp = NULL;
1782 				sm->waiting_ext_cert_check = 0;
1783 				return resp;
1784 			}
1785 
1786 			if (config->pending_ext_cert_check ==
1787 			    EXT_CERT_CHECK_BAD) {
1788 				wpa_printf(MSG_DEBUG,
1789 					   "EAP-TEAP: External certificate check failed - force authentication failure");
1790 				ret->methodState = METHOD_DONE;
1791 				ret->decision = DECISION_FAIL;
1792 				sm->waiting_ext_cert_check = 0;
1793 				return NULL;
1794 			}
1795 
1796 			wpa_printf(MSG_DEBUG,
1797 				   "EAP-TEAP: Continuing to wait external server certificate validation");
1798 			return NULL;
1799 		}
1800 
1801 		/* Continue processing TLS handshake (phase 1). */
1802 		res = eap_peer_tls_process_helper(sm, &data->ssl,
1803 						  EAP_TYPE_TEAP,
1804 						  data->teap_version, id, &msg,
1805 						  &resp);
1806 		if (res < 0) {
1807 			wpa_printf(MSG_DEBUG,
1808 				   "EAP-TEAP: TLS processing failed");
1809 			ret->methodState = METHOD_DONE;
1810 			ret->decision = DECISION_FAIL;
1811 			return resp;
1812 		}
1813 
1814 		if (sm->waiting_ext_cert_check) {
1815 			wpa_printf(MSG_DEBUG,
1816 				   "EAP-TEAP: Waiting external server certificate validation");
1817 			wpabuf_free(data->pending_resp);
1818 			data->pending_resp = resp;
1819 			return NULL;
1820 		}
1821 
1822 		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
1823 			char cipher[80];
1824 
1825 			wpa_printf(MSG_DEBUG,
1826 				   "EAP-TEAP: TLS done, proceed to Phase 2");
1827 			data->tls_cs =
1828 				tls_connection_get_cipher_suite(data->ssl.conn);
1829 			wpa_printf(MSG_DEBUG,
1830 				   "EAP-TEAP: TLS cipher suite 0x%04x",
1831 				   data->tls_cs);
1832 
1833 			if (data->provisioning &&
1834 			    (!(data->provisioning_allowed &
1835 			       EAP_TEAP_PROV_AUTH) ||
1836 			     tls_get_cipher(sm->ssl_ctx, data->ssl.conn,
1837 					    cipher, sizeof(cipher)) < 0 ||
1838 			     os_strstr(cipher, "ADH-") ||
1839 			     os_strstr(cipher, "anon"))) {
1840 				wpa_printf(MSG_DEBUG,
1841 					   "EAP-TEAP: Using anonymous (unauthenticated) provisioning");
1842 				data->anon_provisioning = 1;
1843 			} else {
1844 				data->anon_provisioning = 0;
1845 			}
1846 			data->resuming = 0;
1847 			if (eap_teap_derive_key_auth(sm, data) < 0) {
1848 				wpa_printf(MSG_DEBUG,
1849 					   "EAP-TEAP: Could not derive keys");
1850 				ret->methodState = METHOD_DONE;
1851 				ret->decision = DECISION_FAIL;
1852 				wpabuf_free(resp);
1853 				return NULL;
1854 			}
1855 		}
1856 
1857 		if (res == 2) {
1858 			/*
1859 			 * Application data included in the handshake message.
1860 			 */
1861 			wpabuf_free(data->pending_phase2_req);
1862 			data->pending_phase2_req = resp;
1863 			resp = NULL;
1864 			res = eap_teap_decrypt(sm, data, ret, id, &msg, &resp);
1865 		}
1866 	}
1867 
1868 	if (res == 1) {
1869 		wpabuf_free(resp);
1870 		return eap_peer_tls_build_ack(id, EAP_TYPE_TEAP,
1871 					      data->teap_version);
1872 	}
1873 
1874 #ifdef CONFIG_TESTING_OPTIONS
1875 	if (data->test_outer_tlvs && res == 0 && resp &&
1876 	    (flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6)
1877 		resp = eap_teap_add_dummy_outer_tlvs(data, resp);
1878 #endif /* CONFIG_TESTING_OPTIONS */
1879 
1880 	return resp;
1881 }
1882 
1883 
1884 #if 0 /* TODO */
1885 static Boolean eap_teap_has_reauth_data(struct eap_sm *sm, void *priv)
1886 {
1887 	struct eap_teap_data *data = priv;
1888 
1889 	return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
1890 }
1891 
1892 
1893 static void eap_teap_deinit_for_reauth(struct eap_sm *sm, void *priv)
1894 {
1895 	struct eap_teap_data *data = priv;
1896 
1897 	if (data->phase2_priv && data->phase2_method &&
1898 	    data->phase2_method->deinit_for_reauth)
1899 		data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
1900 	eap_teap_clear(data);
1901 }
1902 
1903 
1904 static void * eap_teap_init_for_reauth(struct eap_sm *sm, void *priv)
1905 {
1906 	struct eap_teap_data *data = priv;
1907 
1908 	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
1909 		eap_teap_deinit(sm, data);
1910 		return NULL;
1911 	}
1912 	if (data->phase2_priv && data->phase2_method &&
1913 	    data->phase2_method->init_for_reauth)
1914 		data->phase2_method->init_for_reauth(sm, data->phase2_priv);
1915 	data->phase2_success = 0;
1916 	data->inner_method_done = 0;
1917 	data->result_success_done = 0;
1918 	data->done_on_tx_completion = 0;
1919 	data->resuming = 1;
1920 	data->provisioning = 0;
1921 	data->anon_provisioning = 0;
1922 	data->simck_idx = 0;
1923 	return priv;
1924 }
1925 #endif
1926 
1927 
1928 static int eap_teap_get_status(struct eap_sm *sm, void *priv, char *buf,
1929 			       size_t buflen, int verbose)
1930 {
1931 	struct eap_teap_data *data = priv;
1932 	int len, ret;
1933 
1934 	len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
1935 	if (data->phase2_method) {
1936 		ret = os_snprintf(buf + len, buflen - len,
1937 				  "EAP-TEAP Phase 2 method=%s\n",
1938 				  data->phase2_method->name);
1939 		if (os_snprintf_error(buflen - len, ret))
1940 			return len;
1941 		len += ret;
1942 	}
1943 	return len;
1944 }
1945 
1946 
1947 static Boolean eap_teap_isKeyAvailable(struct eap_sm *sm, void *priv)
1948 {
1949 	struct eap_teap_data *data = priv;
1950 
1951 	return data->success;
1952 }
1953 
1954 
1955 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
1956 {
1957 	struct eap_teap_data *data = priv;
1958 	u8 *key;
1959 
1960 	if (!data->success)
1961 		return NULL;
1962 
1963 	key = os_memdup(data->key_data, EAP_TEAP_KEY_LEN);
1964 	if (!key)
1965 		return NULL;
1966 
1967 	*len = EAP_TEAP_KEY_LEN;
1968 
1969 	return key;
1970 }
1971 
1972 
1973 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1974 {
1975 	struct eap_teap_data *data = priv;
1976 	u8 *id;
1977 
1978 	if (!data->success || !data->session_id)
1979 		return NULL;
1980 
1981 	id = os_memdup(data->session_id, data->id_len);
1982 	if (!id)
1983 		return NULL;
1984 
1985 	*len = data->id_len;
1986 
1987 	return id;
1988 }
1989 
1990 
1991 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1992 {
1993 	struct eap_teap_data *data = priv;
1994 	u8 *key;
1995 
1996 	if (!data->success)
1997 		return NULL;
1998 
1999 	key = os_memdup(data->emsk, EAP_EMSK_LEN);
2000 	if (!key)
2001 		return NULL;
2002 
2003 	*len = EAP_EMSK_LEN;
2004 
2005 	return key;
2006 }
2007 
2008 
2009 int eap_peer_teap_register(void)
2010 {
2011 	struct eap_method *eap;
2012 
2013 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
2014 				    EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
2015 	if (!eap)
2016 		return -1;
2017 
2018 	eap->init = eap_teap_init;
2019 	eap->deinit = eap_teap_deinit;
2020 	eap->process = eap_teap_process;
2021 	eap->isKeyAvailable = eap_teap_isKeyAvailable;
2022 	eap->getKey = eap_teap_getKey;
2023 	eap->getSessionId = eap_teap_get_session_id;
2024 	eap->get_status = eap_teap_get_status;
2025 #if 0 /* TODO */
2026 	eap->has_reauth_data = eap_teap_has_reauth_data;
2027 	eap->deinit_for_reauth = eap_teap_deinit_for_reauth;
2028 	eap->init_for_reauth = eap_teap_init_for_reauth;
2029 #endif
2030 	eap->get_emsk = eap_teap_get_emsk;
2031 
2032 	return eap_peer_method_register(eap);
2033 }
2034