eap_teap.c revision 351611
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
24static void eap_teap_deinit(struct eap_sm *sm, void *priv);
25
26
27struct 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
77static 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
118static 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
153static 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
232static 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
251static 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
276static 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
288static 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
308static 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
326static 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
374static 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
461static 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
481static 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
503static 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
542static 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
583static int
584eap_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
622static 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
671static 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
730static 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
757static 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
870static 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
903static 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
944static 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
1023static 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
1068static 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
1095static 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
1149static 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
1181static 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
1331done:
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
1365send_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
1382static 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
1425continue_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
1446static 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
1464static 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
1497static 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
1510static 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
1651static 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
1717static 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 */
1885static 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
1893static 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
1904static 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
1928static 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
1947static 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
1955static 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
1973static 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
1991static 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
2009int 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