1 /*
2  * EAP-TEAP server (RFC 7170)
3  * Copyright (c) 2004-2024, 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 "crypto/random.h"
14 #include "eap_common/eap_teap_common.h"
15 #include "eap_i.h"
16 #include "eap_tls_common.h"
17 
18 
19 static void eap_teap_reset(struct eap_sm *sm, void *priv);
20 
21 
22 struct eap_teap_data {
23 	struct eap_ssl_data ssl;
24 	enum {
25 		START, PHASE1, PHASE1B, PHASE2_START, PHASE2_ID,
26 		PHASE2_BASIC_AUTH, PHASE2_METHOD, CRYPTO_BINDING,
27 		FAILURE_SEND_RESULT, SUCCESS_SEND_RESULT, SUCCESS, FAILURE
28 	} state;
29 
30 	u8 teap_version;
31 	u8 peer_version;
32 	u16 tls_cs;
33 
34 	const struct eap_method *phase2_method;
35 	void *phase2_priv;
36 
37 	u8 crypto_binding_nonce[32];
38 	int final_result;
39 
40 	u8 simck[EAP_TEAP_SIMCK_LEN];
41 	u8 simck_msk[EAP_TEAP_SIMCK_LEN];
42 	u8 cmk_msk[EAP_TEAP_CMK_LEN];
43 	u8 simck_emsk[EAP_TEAP_SIMCK_LEN];
44 	u8 cmk_emsk[EAP_TEAP_CMK_LEN];
45 	int simck_idx;
46 	bool cmk_emsk_available;
47 
48 	u8 *srv_id;
49 	size_t srv_id_len;
50 	char *srv_id_info;
51 
52 	unsigned int basic_auth_not_done:1;
53 	unsigned int inner_eap_not_done:1;
54 	int skipped_inner_auth;
55 	struct wpabuf *pending_phase2_resp;
56 	struct wpabuf *server_outer_tlvs;
57 	struct wpabuf *peer_outer_tlvs;
58 	u8 *identity; /* from client certificate */
59 	size_t identity_len;
60 	int eap_seq;
61 	int tnc_started;
62 
63 	enum teap_error_codes error_code;
64 	enum teap_identity_types cur_id_type;
65 
66 	bool check_crypto_binding;
67 };
68 
69 
70 static int eap_teap_process_phase2_start(struct eap_sm *sm,
71 					 struct eap_teap_data *data);
72 static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
73 				int vendor, enum eap_type eap_type);
74 
75 
eap_teap_state_txt(int state)76 static const char * eap_teap_state_txt(int state)
77 {
78 	switch (state) {
79 	case START:
80 		return "START";
81 	case PHASE1:
82 		return "PHASE1";
83 	case PHASE1B:
84 		return "PHASE1B";
85 	case PHASE2_START:
86 		return "PHASE2_START";
87 	case PHASE2_ID:
88 		return "PHASE2_ID";
89 	case PHASE2_BASIC_AUTH:
90 		return "PHASE2_BASIC_AUTH";
91 	case PHASE2_METHOD:
92 		return "PHASE2_METHOD";
93 	case CRYPTO_BINDING:
94 		return "CRYPTO_BINDING";
95 	case FAILURE_SEND_RESULT:
96 		return "FAILURE_SEND_RESULT";
97 	case SUCCESS_SEND_RESULT:
98 		return "SUCCESS_SEND_RESULT";
99 	case SUCCESS:
100 		return "SUCCESS";
101 	case FAILURE:
102 		return "FAILURE";
103 	default:
104 		return "Unknown?!";
105 	}
106 }
107 
108 
eap_teap_state(struct eap_teap_data * data,int state)109 static void eap_teap_state(struct eap_teap_data *data, int state)
110 {
111 	wpa_printf(MSG_DEBUG, "EAP-TEAP: %s -> %s",
112 		   eap_teap_state_txt(data->state),
113 		   eap_teap_state_txt(state));
114 	data->state = state;
115 }
116 
117 
eap_teap_req_failure(struct eap_teap_data * data,enum teap_error_codes error)118 static enum eap_type eap_teap_req_failure(struct eap_teap_data *data,
119 					  enum teap_error_codes error)
120 {
121 	eap_teap_state(data, FAILURE_SEND_RESULT);
122 	return EAP_TYPE_NONE;
123 }
124 
125 
eap_teap_derive_key_auth(struct eap_sm * sm,struct eap_teap_data * data)126 static int eap_teap_derive_key_auth(struct eap_sm *sm,
127 				    struct eap_teap_data *data)
128 {
129 	int res;
130 
131 	/* RFC 7170, Section 5.1 */
132 	res = tls_connection_export_key(sm->cfg->ssl_ctx, data->ssl.conn,
133 					TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
134 					data->simck, EAP_TEAP_SIMCK_LEN);
135 	if (res)
136 		return res;
137 	wpa_hexdump_key(MSG_DEBUG,
138 			"EAP-TEAP: session_key_seed (S-IMCK[0])",
139 			data->simck, EAP_TEAP_SIMCK_LEN);
140 	os_memcpy(data->simck_msk, data->simck, EAP_TEAP_SIMCK_LEN);
141 	os_memcpy(data->simck_emsk, data->simck, EAP_TEAP_SIMCK_LEN);
142 	data->simck_idx = 0;
143 	return 0;
144 }
145 
146 
eap_teap_update_icmk(struct eap_sm * sm,struct eap_teap_data * data)147 static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data)
148 {
149 	u8 *msk = NULL, *emsk = NULL;
150 	size_t msk_len = 0, emsk_len = 0;
151 	int res;
152 
153 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Deriving ICMK[%d] (S-IMCK and CMK)",
154 		   data->simck_idx + 1);
155 
156 	if (sm->cfg->eap_teap_auth == 1)
157 		goto out; /* no MSK derived in Basic-Password-Auth */
158 
159 	if (!data->phase2_method || !data->phase2_priv) {
160 		wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
161 		return -1;
162 	}
163 
164 	if (data->phase2_method->getKey) {
165 		msk = data->phase2_method->getKey(sm, data->phase2_priv,
166 						  &msk_len);
167 		if (!msk) {
168 			wpa_printf(MSG_INFO,
169 				   "EAP-TEAP: Could not fetch Phase 2 MSK");
170 			return -1;
171 		}
172 	}
173 
174 	if (data->phase2_method->get_emsk) {
175 		emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
176 						     &emsk_len);
177 	}
178 
179 out:
180 	res = eap_teap_derive_imck(data->tls_cs, data->simck,
181 				   msk, msk_len, emsk, emsk_len,
182 				   data->simck_msk, data->cmk_msk,
183 				   data->simck_emsk, data->cmk_emsk);
184 	bin_clear_free(msk, msk_len);
185 	bin_clear_free(emsk, emsk_len);
186 	if (res == 0) {
187 		data->simck_idx++;
188 		data->cmk_emsk_available = emsk != NULL;
189 	}
190 	return 0;
191 }
192 
193 
eap_teap_init(struct eap_sm * sm)194 static void * eap_teap_init(struct eap_sm *sm)
195 {
196 	struct eap_teap_data *data;
197 
198 	data = os_zalloc(sizeof(*data));
199 	if (!data)
200 		return NULL;
201 	data->teap_version = EAP_TEAP_VERSION;
202 	data->state = START;
203 
204 	if (eap_server_tls_ssl_init(sm, &data->ssl,
205 				    sm->cfg->eap_teap_auth == 2 ? 2 : 0,
206 				    EAP_TYPE_TEAP)) {
207 		wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL.");
208 		eap_teap_reset(sm, data);
209 		return NULL;
210 	}
211 
212 	if (!sm->cfg->eap_fast_a_id) {
213 		wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID configured");
214 		eap_teap_reset(sm, data);
215 		return NULL;
216 	}
217 	data->srv_id = os_malloc(sm->cfg->eap_fast_a_id_len);
218 	if (!data->srv_id) {
219 		eap_teap_reset(sm, data);
220 		return NULL;
221 	}
222 	os_memcpy(data->srv_id, sm->cfg->eap_fast_a_id,
223 		  sm->cfg->eap_fast_a_id_len);
224 	data->srv_id_len = sm->cfg->eap_fast_a_id_len;
225 
226 	if (!sm->cfg->eap_fast_a_id_info) {
227 		wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID-Info configured");
228 		eap_teap_reset(sm, data);
229 		return NULL;
230 	}
231 	data->srv_id_info = os_strdup(sm->cfg->eap_fast_a_id_info);
232 	if (!data->srv_id_info) {
233 		eap_teap_reset(sm, data);
234 		return NULL;
235 	}
236 
237 	return data;
238 }
239 
240 
eap_teap_reset(struct eap_sm * sm,void * priv)241 static void eap_teap_reset(struct eap_sm *sm, void *priv)
242 {
243 	struct eap_teap_data *data = priv;
244 
245 	if (!data)
246 		return;
247 	if (data->phase2_priv && data->phase2_method)
248 		data->phase2_method->reset(sm, data->phase2_priv);
249 	eap_server_tls_ssl_deinit(sm, &data->ssl);
250 	os_free(data->srv_id);
251 	os_free(data->srv_id_info);
252 	wpabuf_free(data->pending_phase2_resp);
253 	wpabuf_free(data->server_outer_tlvs);
254 	wpabuf_free(data->peer_outer_tlvs);
255 	os_free(data->identity);
256 	forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
257 	forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
258 	forced_memzero(data->cmk_msk, EAP_TEAP_CMK_LEN);
259 	forced_memzero(data->cmk_emsk, EAP_TEAP_CMK_LEN);
260 	bin_clear_free(data, sizeof(*data));
261 }
262 
263 
eap_teap_build_start(struct eap_sm * sm,struct eap_teap_data * data,u8 id)264 static struct wpabuf * eap_teap_build_start(struct eap_sm *sm,
265 					    struct eap_teap_data *data, u8 id)
266 {
267 	struct wpabuf *req;
268 	size_t outer_tlv_len = sizeof(struct teap_tlv_hdr) + data->srv_id_len;
269 	const u8 *start, *end;
270 
271 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TEAP,
272 			    1 + 4 + outer_tlv_len, EAP_CODE_REQUEST, id);
273 	if (!req) {
274 		wpa_printf(MSG_ERROR,
275 			   "EAP-TEAP: Failed to allocate memory for request");
276 		eap_teap_state(data, FAILURE);
277 		return NULL;
278 	}
279 
280 	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | EAP_TEAP_FLAGS_OUTER_TLV_LEN |
281 		      data->teap_version);
282 	wpabuf_put_be32(req, outer_tlv_len);
283 
284 	start = wpabuf_put(req, 0);
285 
286 	/* RFC 7170, Section 4.2.2: Authority-ID TLV */
287 	eap_teap_put_tlv(req, TEAP_TLV_AUTHORITY_ID,
288 			 data->srv_id, data->srv_id_len);
289 
290 	end = wpabuf_put(req, 0);
291 	wpabuf_free(data->server_outer_tlvs);
292 	data->server_outer_tlvs = wpabuf_alloc_copy(start, end - start);
293 	if (!data->server_outer_tlvs) {
294 		eap_teap_state(data, FAILURE);
295 		return NULL;
296 	}
297 
298 	eap_teap_state(data, PHASE1);
299 
300 	return req;
301 }
302 
303 
eap_teap_phase1_done(struct eap_sm * sm,struct eap_teap_data * data)304 static int eap_teap_phase1_done(struct eap_sm *sm, struct eap_teap_data *data)
305 {
306 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2");
307 
308 	if (!data->identity && sm->cfg->eap_teap_auth == 2) {
309 		const char *subject;
310 
311 		subject = tls_connection_get_peer_subject(data->ssl.conn);
312 		if (subject) {
313 			wpa_printf(MSG_DEBUG,
314 				   "EAP-TEAP: Peer subject from Phase 1 client certificate: '%s'",
315 				   subject);
316 			data->identity = (u8 *) os_strdup(subject);
317 			data->identity_len = os_strlen(subject);
318 		}
319 	}
320 
321 	data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn);
322 	wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x",
323 		   data->tls_cs);
324 
325 	if (eap_teap_derive_key_auth(sm, data) < 0) {
326 		eap_teap_state(data, FAILURE);
327 		return -1;
328 	}
329 
330 	eap_teap_state(data, PHASE2_START);
331 
332 	return 0;
333 }
334 
335 
eap_teap_build_phase2_req(struct eap_sm * sm,struct eap_teap_data * data,u8 id)336 static struct wpabuf * eap_teap_build_phase2_req(struct eap_sm *sm,
337 						 struct eap_teap_data *data,
338 						 u8 id)
339 {
340 	struct wpabuf *req, *id_tlv = NULL;
341 
342 	if (sm->cfg->eap_teap_auth == 1 ||
343 	    (data->phase2_priv && data->phase2_method &&
344 	     data->phase2_method->vendor == EAP_VENDOR_IETF &&
345 	     data->phase2_method->method == EAP_TYPE_IDENTITY)) {
346 		switch (sm->cfg->eap_teap_id) {
347 		case EAP_TEAP_ID_ALLOW_ANY:
348 			break;
349 		case EAP_TEAP_ID_REQUIRE_USER:
350 		case EAP_TEAP_ID_REQUEST_USER_ACCEPT_MACHINE:
351 			data->cur_id_type = TEAP_IDENTITY_TYPE_USER;
352 			id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
353 			break;
354 		case EAP_TEAP_ID_REQUIRE_MACHINE:
355 		case EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER:
356 			data->cur_id_type = TEAP_IDENTITY_TYPE_MACHINE;
357 			id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
358 			break;
359 		case EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE:
360 			if (data->cur_id_type == TEAP_IDENTITY_TYPE_USER)
361 				data->cur_id_type = TEAP_IDENTITY_TYPE_MACHINE;
362 			else
363 				data->cur_id_type = TEAP_IDENTITY_TYPE_USER;
364 			id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
365 			break;
366 		}
367 	}
368 
369 	if (sm->cfg->eap_teap_auth == 1) {
370 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate Basic-Password-Auth");
371 		data->basic_auth_not_done = 1;
372 		req = wpabuf_alloc(sizeof(struct teap_tlv_hdr));
373 		if (!req) {
374 			wpabuf_free(id_tlv);
375 			return NULL;
376 		}
377 		eap_teap_put_tlv_hdr(req, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ, 0);
378 		return wpabuf_concat(req, id_tlv);
379 	}
380 
381 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate inner EAP method");
382 	data->inner_eap_not_done = 1;
383 	if (!data->phase2_priv) {
384 		wpa_printf(MSG_DEBUG,
385 			   "EAP-TEAP: Phase 2 method not initialized");
386 		wpabuf_free(id_tlv);
387 		return NULL;
388 	}
389 
390 	req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
391 	if (!req) {
392 		wpabuf_free(id_tlv);
393 		return NULL;
394 	}
395 
396 	wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-TEAP: Phase 2 EAP-Request", req);
397 
398 	return wpabuf_concat(eap_teap_tlv_eap_payload(req), id_tlv);
399 }
400 
401 
eap_teap_build_crypto_binding(struct eap_sm * sm,struct eap_teap_data * data)402 static struct wpabuf * eap_teap_build_crypto_binding(
403 	struct eap_sm *sm, struct eap_teap_data *data)
404 {
405 	struct wpabuf *buf;
406 	struct teap_tlv_result *result;
407 	struct teap_tlv_crypto_binding *cb;
408 	u8 subtype, flags;
409 
410 	buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*cb));
411 	if (!buf)
412 		return NULL;
413 
414 	if (data->basic_auth_not_done || data->inner_eap_not_done ||
415 	    data->phase2_method || sm->cfg->eap_teap_separate_result)
416 		data->final_result = 0;
417 	else
418 		data->final_result = 1;
419 
420 	if (!data->final_result || data->eap_seq > 0 ||
421 	    sm->cfg->eap_teap_auth == 1) {
422 		/* Intermediate-Result */
423 		wpa_printf(MSG_DEBUG,
424 			   "EAP-TEAP: Add Intermediate-Result TLV (status=SUCCESS)");
425 		result = wpabuf_put(buf, sizeof(*result));
426 		result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
427 						TEAP_TLV_INTERMEDIATE_RESULT);
428 		result->length = host_to_be16(2);
429 		result->status = host_to_be16(TEAP_STATUS_SUCCESS);
430 	}
431 
432 	if (data->final_result) {
433 		/* Result TLV */
434 		wpa_printf(MSG_DEBUG,
435 			   "EAP-TEAP: Add Result TLV (status=SUCCESS)");
436 		result = wpabuf_put(buf, sizeof(*result));
437 		result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
438 						TEAP_TLV_RESULT);
439 		result->length = host_to_be16(2);
440 		result->status = host_to_be16(TEAP_STATUS_SUCCESS);
441 	}
442 
443 	/* Crypto-Binding TLV */
444 	cb = wpabuf_put(buf, sizeof(*cb));
445 	cb->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
446 				    TEAP_TLV_CRYPTO_BINDING);
447 	cb->length = host_to_be16(sizeof(*cb) - sizeof(struct teap_tlv_hdr));
448 	cb->version = EAP_TEAP_VERSION;
449 	cb->received_version = data->peer_version;
450 	flags = data->cmk_emsk_available ?
451 		TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
452 		TEAP_CRYPTO_BINDING_MSK_CMAC;
453 	subtype = TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST;
454 	cb->subtype = (flags << 4) | subtype;
455 	if (random_get_bytes(cb->nonce, sizeof(cb->nonce)) < 0) {
456 		wpabuf_free(buf);
457 		return NULL;
458 	}
459 
460 	/*
461 	 * RFC 7170, Section 4.2.13:
462 	 * The nonce in a request MUST have its least significant bit set to 0.
463 	 */
464 	cb->nonce[sizeof(cb->nonce) - 1] &= ~0x01;
465 
466 	os_memcpy(data->crypto_binding_nonce, cb->nonce, sizeof(cb->nonce));
467 
468 	if (eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
469 				  data->peer_outer_tlvs, data->cmk_msk,
470 				  cb->msk_compound_mac) < 0) {
471 		wpabuf_free(buf);
472 		return NULL;
473 	}
474 
475 	if (data->cmk_emsk_available &&
476 	    eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
477 				  data->peer_outer_tlvs, data->cmk_emsk,
478 				  cb->emsk_compound_mac) < 0) {
479 		wpabuf_free(buf);
480 		return NULL;
481 	}
482 
483 	wpa_printf(MSG_DEBUG,
484 		   "EAP-TEAP: Add Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
485 		   cb->version, cb->received_version, flags, subtype);
486 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
487 		    cb->nonce, sizeof(cb->nonce));
488 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
489 		    cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
490 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
491 		    cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
492 
493 	data->check_crypto_binding = true;
494 
495 	return buf;
496 }
497 
498 
eap_teap_encrypt_phase2(struct eap_sm * sm,struct eap_teap_data * data,struct wpabuf * plain,int piggyback)499 static int eap_teap_encrypt_phase2(struct eap_sm *sm,
500 				   struct eap_teap_data *data,
501 				   struct wpabuf *plain, int piggyback)
502 {
503 	struct wpabuf *encr;
504 
505 	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 TLVs",
506 			    plain);
507 	encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
508 	wpabuf_free(plain);
509 
510 	if (!encr)
511 		return -1;
512 
513 	if (data->ssl.tls_out && piggyback) {
514 		wpa_printf(MSG_DEBUG,
515 			   "EAP-TEAP: Piggyback Phase 2 data (len=%d) with last Phase 1 Message (len=%d used=%d)",
516 			   (int) wpabuf_len(encr),
517 			   (int) wpabuf_len(data->ssl.tls_out),
518 			   (int) data->ssl.tls_out_pos);
519 		if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
520 			wpa_printf(MSG_WARNING,
521 				   "EAP-TEAP: Failed to resize output buffer");
522 			wpabuf_free(encr);
523 			return -1;
524 		}
525 		wpabuf_put_buf(data->ssl.tls_out, encr);
526 		wpabuf_free(encr);
527 	} else {
528 		wpabuf_free(data->ssl.tls_out);
529 		data->ssl.tls_out_pos = 0;
530 		data->ssl.tls_out = encr;
531 	}
532 
533 	return 0;
534 }
535 
536 
eap_teap_buildReq(struct eap_sm * sm,void * priv,u8 id)537 static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
538 {
539 	struct eap_teap_data *data = priv;
540 	struct wpabuf *req = NULL;
541 	int piggyback = 0;
542 	bool move_to_method = true;
543 
544 	if (data->ssl.state == FRAG_ACK) {
545 		return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
546 						data->teap_version);
547 	}
548 
549 	if (data->ssl.state == WAIT_FRAG_ACK) {
550 		return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
551 						data->teap_version, id);
552 	}
553 
554 	switch (data->state) {
555 	case START:
556 		return eap_teap_build_start(sm, data, id);
557 	case PHASE1B:
558 		if (tls_connection_established(sm->cfg->ssl_ctx,
559 					       data->ssl.conn)) {
560 			if (eap_teap_phase1_done(sm, data) < 0)
561 				return NULL;
562 			if (data->state == PHASE2_START) {
563 				int res;
564 
565 				/*
566 				 * Try to generate Phase 2 data to piggyback
567 				 * with the end of Phase 1 to avoid extra
568 				 * roundtrip.
569 				 */
570 				wpa_printf(MSG_DEBUG,
571 					   "EAP-TEAP: Try to start Phase 2");
572 				res = eap_teap_process_phase2_start(sm, data);
573 				if (res == 1) {
574 					req = eap_teap_build_crypto_binding(
575 						sm, data);
576 					piggyback = 1;
577 					break;
578 				}
579 
580 				if (res)
581 					break;
582 				req = eap_teap_build_phase2_req(sm, data, id);
583 				piggyback = 1;
584 			}
585 		}
586 		break;
587 	case PHASE2_ID:
588 	case PHASE2_BASIC_AUTH:
589 	case PHASE2_METHOD:
590 		req = eap_teap_build_phase2_req(sm, data, id);
591 		break;
592 	case CRYPTO_BINDING:
593 		req = eap_teap_build_crypto_binding(sm, data);
594 		if (req && sm->cfg->eap_teap_auth == 0 &&
595 		    data->inner_eap_not_done &&
596 		    !data->phase2_method &&
597 		    sm->cfg->eap_teap_method_sequence == 0) {
598 			wpa_printf(MSG_DEBUG,
599 				   "EAP-TEAP: Continue with inner EAP authentication for second credential (optimized)");
600 			eap_teap_state(data, PHASE2_ID);
601 			if (eap_teap_phase2_init(sm, data, EAP_VENDOR_IETF,
602 						 EAP_TYPE_IDENTITY) < 0) {
603 				eap_teap_state(data, FAILURE);
604 				wpabuf_free(req);
605 				return NULL;
606 			}
607 			move_to_method = false;
608 		}
609 		if (data->phase2_method) {
610 			/*
611 			 * Include the start of the next EAP method in the
612 			 * sequence in the same message with Crypto-Binding to
613 			 * save a round-trip.
614 			 */
615 			struct wpabuf *eap;
616 
617 			eap = eap_teap_build_phase2_req(sm, data, id);
618 			req = wpabuf_concat(req, eap);
619 			if (move_to_method)
620 				eap_teap_state(data, PHASE2_METHOD);
621 		}
622 		break;
623 	case FAILURE_SEND_RESULT:
624 		req = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
625 		if (data->error_code)
626 			req = wpabuf_concat(
627 				req, eap_teap_tlv_error(data->error_code));
628 		break;
629 	case SUCCESS_SEND_RESULT:
630 		req = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0);
631 		data->final_result = 1;
632 		break;
633 	default:
634 		wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
635 			   __func__, data->state);
636 		return NULL;
637 	}
638 
639 	if (req && eap_teap_encrypt_phase2(sm, data, req, piggyback) < 0)
640 		return NULL;
641 
642 	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
643 					data->teap_version, id);
644 }
645 
646 
eap_teap_check(struct eap_sm * sm,void * priv,struct wpabuf * respData)647 static bool eap_teap_check(struct eap_sm *sm, void *priv,
648 			   struct wpabuf *respData)
649 {
650 	const u8 *pos;
651 	size_t len;
652 
653 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
654 	if (!pos || len < 1) {
655 		wpa_printf(MSG_INFO, "EAP-TEAP: Invalid frame");
656 		return true;
657 	}
658 
659 	return false;
660 }
661 
662 
eap_teap_phase2_init(struct eap_sm * sm,struct eap_teap_data * data,int vendor,enum eap_type eap_type)663 static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
664 				int vendor, enum eap_type eap_type)
665 {
666 	if (data->phase2_priv && data->phase2_method) {
667 		data->phase2_method->reset(sm, data->phase2_priv);
668 		data->phase2_method = NULL;
669 		data->phase2_priv = NULL;
670 	}
671 	data->phase2_method = eap_server_get_eap_method(vendor, eap_type);
672 	if (!data->phase2_method)
673 		return -1;
674 
675 	/* While RFC 7170 does not describe this, EAP-TEAP has been deployed
676 	 * with implementations that use the EAP-FAST-MSCHAPv2, instead of the
677 	 * EAP-MSCHAPv2, way of deriving the MSK for IMSK. Use that design here
678 	 * to interoperate.
679 	 */
680 	sm->eap_fast_mschapv2 = true;
681 
682 	sm->init_phase2 = 1;
683 	data->phase2_priv = data->phase2_method->init(sm);
684 	sm->init_phase2 = 0;
685 
686 	return data->phase2_priv ? 0 : -1;
687 }
688 
689 
eap_teap_valid_id_type(struct eap_sm * sm,struct eap_teap_data * data,enum teap_identity_types id_type)690 static int eap_teap_valid_id_type(struct eap_sm *sm, struct eap_teap_data *data,
691 				  enum teap_identity_types id_type)
692 {
693 	if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_USER &&
694 	    id_type != TEAP_IDENTITY_TYPE_USER)
695 		return 0;
696 	if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_MACHINE &&
697 	    id_type != TEAP_IDENTITY_TYPE_MACHINE)
698 		return 0;
699 	if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE &&
700 	    id_type != data->cur_id_type)
701 		return 0;
702 	if (sm->cfg->eap_teap_id != EAP_TEAP_ID_ALLOW_ANY &&
703 	    id_type != TEAP_IDENTITY_TYPE_USER &&
704 	    id_type != TEAP_IDENTITY_TYPE_MACHINE)
705 		return 0;
706 	return 1;
707 }
708 
709 
eap_teap_process_phase2_response(struct eap_sm * sm,struct eap_teap_data * data,u8 * in_data,size_t in_len,enum teap_identity_types id_type)710 static void eap_teap_process_phase2_response(struct eap_sm *sm,
711 					     struct eap_teap_data *data,
712 					     u8 *in_data, size_t in_len,
713 					     enum teap_identity_types id_type)
714 {
715 	int next_vendor = EAP_VENDOR_IETF;
716 	enum eap_type next_type = EAP_TYPE_NONE;
717 	struct eap_hdr *hdr;
718 	u8 *pos;
719 	size_t left;
720 	struct wpabuf buf;
721 	const struct eap_method *m = data->phase2_method;
722 	void *priv = data->phase2_priv;
723 
724 	if (!priv) {
725 		wpa_printf(MSG_DEBUG,
726 			   "EAP-TEAP: %s - Phase 2 not initialized?!",
727 			   __func__);
728 		return;
729 	}
730 
731 	hdr = (struct eap_hdr *) in_data;
732 	pos = (u8 *) (hdr + 1);
733 
734 	if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
735 		left = in_len - sizeof(*hdr);
736 		wpa_hexdump(MSG_DEBUG,
737 			    "EAP-TEAP: Phase 2 type Nak'ed; allowed types",
738 			    pos + 1, left - 1);
739 #ifdef EAP_SERVER_TNC
740 		if (m && m->vendor == EAP_VENDOR_IETF &&
741 		    m->method == EAP_TYPE_TNC) {
742 			wpa_printf(MSG_DEBUG,
743 				   "EAP-TEAP: Peer Nak'ed required TNC negotiation");
744 			next_vendor = EAP_VENDOR_IETF;
745 			next_type = eap_teap_req_failure(data, 0);
746 			eap_teap_phase2_init(sm, data, next_vendor, next_type);
747 			return;
748 		}
749 #endif /* EAP_SERVER_TNC */
750 		eap_sm_process_nak(sm, pos + 1, left - 1);
751 		if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
752 		    sm->user->methods[sm->user_eap_method_index].method !=
753 		    EAP_TYPE_NONE) {
754 			next_vendor = sm->user->methods[
755 				sm->user_eap_method_index].vendor;
756 			next_type = sm->user->methods[
757 				sm->user_eap_method_index++].method;
758 			wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %u:%u",
759 				   next_vendor, next_type);
760 		} else {
761 			next_vendor = EAP_VENDOR_IETF;
762 			next_type = eap_teap_req_failure(data, 0);
763 		}
764 		eap_teap_phase2_init(sm, data, next_vendor, next_type);
765 		return;
766 	}
767 
768 	wpabuf_set(&buf, in_data, in_len);
769 
770 	if (m->check(sm, priv, &buf)) {
771 		wpa_printf(MSG_DEBUG,
772 			   "EAP-TEAP: Phase 2 check() asked to ignore the packet");
773 		eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
774 		return;
775 	}
776 
777 	m->process(sm, priv, &buf);
778 
779 	if (!m->isDone(sm, priv))
780 		return;
781 
782 	if (!m->isSuccess(sm, priv)) {
783 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed");
784 		next_vendor = EAP_VENDOR_IETF;
785 		next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
786 		eap_teap_phase2_init(sm, data, next_vendor, next_type);
787 		return;
788 	}
789 
790 	switch (data->state) {
791 	case PHASE2_ID:
792 		if (!eap_teap_valid_id_type(sm, data, id_type)) {
793 			wpa_printf(MSG_DEBUG,
794 				   "EAP-TEAP: Provided Identity-Type %u not allowed",
795 				   id_type);
796 			eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
797 			break;
798 		}
799 		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
800 			wpa_hexdump_ascii(MSG_DEBUG,
801 					  "EAP-TEAP: Phase 2 Identity not found in the user database",
802 					  sm->identity, sm->identity_len);
803 			next_vendor = EAP_VENDOR_IETF;
804 			next_type = eap_teap_req_failure(
805 				data, TEAP_ERROR_INNER_METHOD);
806 			break;
807 		}
808 
809 		eap_teap_state(data, PHASE2_METHOD);
810 		next_vendor = sm->user->methods[0].vendor;
811 		next_type = sm->user->methods[0].method;
812 		sm->user_eap_method_index = 1;
813 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %u:%u",
814 			   next_vendor, next_type);
815 		break;
816 	case PHASE2_METHOD:
817 	case CRYPTO_BINDING:
818 		eap_teap_update_icmk(sm, data);
819 		if (data->state == PHASE2_METHOD &&
820 		    (sm->cfg->eap_teap_id !=
821 		     EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE ||
822 		     data->cur_id_type == TEAP_IDENTITY_TYPE_MACHINE))
823 			data->inner_eap_not_done = 0;
824 		eap_teap_state(data, CRYPTO_BINDING);
825 		data->eap_seq++;
826 		next_vendor = EAP_VENDOR_IETF;
827 		next_type = EAP_TYPE_NONE;
828 #ifdef EAP_SERVER_TNC
829 		if (sm->cfg->tnc && !data->tnc_started) {
830 			wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC");
831 			next_vendor = EAP_VENDOR_IETF;
832 			next_type = EAP_TYPE_TNC;
833 			data->tnc_started = 1;
834 		}
835 #endif /* EAP_SERVER_TNC */
836 		break;
837 	case FAILURE:
838 		break;
839 	default:
840 		wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
841 			   __func__, data->state);
842 		break;
843 	}
844 
845 	eap_teap_phase2_init(sm, data, next_vendor, next_type);
846 }
847 
848 
eap_teap_process_phase2_eap(struct eap_sm * sm,struct eap_teap_data * data,u8 * in_data,size_t in_len,enum teap_identity_types id_type)849 static void eap_teap_process_phase2_eap(struct eap_sm *sm,
850 					struct eap_teap_data *data,
851 					u8 *in_data, size_t in_len,
852 					enum teap_identity_types id_type)
853 {
854 	struct eap_hdr *hdr;
855 	size_t len;
856 
857 	hdr = (struct eap_hdr *) in_data;
858 	if (in_len < (int) sizeof(*hdr)) {
859 		wpa_printf(MSG_INFO,
860 			   "EAP-TEAP: Too short Phase 2 EAP frame (len=%lu)",
861 			   (unsigned long) in_len);
862 		eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
863 		return;
864 	}
865 	len = be_to_host16(hdr->length);
866 	if (len > in_len) {
867 		wpa_printf(MSG_INFO,
868 			   "EAP-TEAP: Length mismatch in Phase 2 EAP frame (len=%lu hdr->length=%lu)",
869 			   (unsigned long) in_len, (unsigned long) len);
870 		eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
871 		return;
872 	}
873 	wpa_printf(MSG_DEBUG,
874 		   "EAP-TEAP: Received Phase 2: code=%d identifier=%d length=%lu",
875 		   hdr->code, hdr->identifier,
876 		   (unsigned long) len);
877 	switch (hdr->code) {
878 	case EAP_CODE_RESPONSE:
879 		eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len,
880 						 id_type);
881 		break;
882 	default:
883 		wpa_printf(MSG_INFO,
884 			   "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
885 			   hdr->code);
886 		break;
887 	}
888 }
889 
890 
eap_teap_process_basic_auth_resp(struct eap_sm * sm,struct eap_teap_data * data,u8 * in_data,size_t in_len,enum teap_identity_types id_type)891 static void eap_teap_process_basic_auth_resp(struct eap_sm *sm,
892 					     struct eap_teap_data *data,
893 					     u8 *in_data, size_t in_len,
894 					     enum teap_identity_types id_type)
895 {
896 	u8 *pos, *end, *username, *password, *new_id;
897 	u8 userlen, passlen;
898 
899 	if (!eap_teap_valid_id_type(sm, data, id_type)) {
900 		wpa_printf(MSG_DEBUG,
901 			   "EAP-TEAP: Provided Identity-Type %u not allowed",
902 			   id_type);
903 		eap_teap_req_failure(data, 0);
904 		return;
905 	}
906 
907 	pos = in_data;
908 	end = pos + in_len;
909 
910 	if (end - pos < 1) {
911 		wpa_printf(MSG_DEBUG,
912 			   "EAP-TEAP: No room for Basic-Password-Auth-Resp Userlen field");
913 		eap_teap_req_failure(data, 0);
914 		return;
915 	}
916 	userlen = *pos++;
917 	if (end - pos < userlen) {
918 		wpa_printf(MSG_DEBUG,
919 			   "EAP-TEAP: Truncated Basic-Password-Auth-Resp Username field");
920 		eap_teap_req_failure(data, 0);
921 		return;
922 	}
923 	username = pos;
924 	pos += userlen;
925 	wpa_hexdump_ascii(MSG_DEBUG,
926 			  "EAP-TEAP: Basic-Password-Auth-Resp Username",
927 			  username, userlen);
928 
929 	if (end - pos < 1) {
930 		wpa_printf(MSG_DEBUG,
931 			   "EAP-TEAP: No room for Basic-Password-Auth-Resp Passlen field");
932 		eap_teap_req_failure(data, 0);
933 		return;
934 	}
935 	passlen = *pos++;
936 	if (end - pos < passlen) {
937 		wpa_printf(MSG_DEBUG,
938 			   "EAP-TEAP: Truncated Basic-Password-Auth-Resp Password field");
939 		eap_teap_req_failure(data, 0);
940 		return;
941 	}
942 	password = pos;
943 	pos += passlen;
944 	wpa_hexdump_ascii_key(MSG_DEBUG,
945 			      "EAP-TEAP: Basic-Password-Auth-Resp Password",
946 			      password, passlen);
947 
948 	if (end > pos) {
949 		wpa_printf(MSG_DEBUG,
950 			   "EAP-TEAP: Unexpected %d extra octet(s) at the end of Basic-Password-Auth-Resp TLV",
951 			   (int) (end - pos));
952 		eap_teap_req_failure(data, 0);
953 		return;
954 	}
955 
956 	if (eap_user_get(sm, username, userlen, 1) != 0) {
957 		wpa_printf(MSG_DEBUG,
958 			   "EAP-TEAP: Username not found in the user database");
959 		eap_teap_req_failure(data, 0);
960 		return;
961 	}
962 
963 	if (!sm->user || !sm->user->password || sm->user->password_hash) {
964 		wpa_printf(MSG_DEBUG,
965 			   "EAP-TEAP: No plaintext user password configured");
966 		eap_teap_req_failure(data, 0);
967 		return;
968 	}
969 
970 	if (sm->user->password_len != passlen ||
971 	    os_memcmp_const(sm->user->password, password, passlen) != 0) {
972 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Invalid password");
973 		eap_teap_req_failure(data, 0);
974 		return;
975 	}
976 
977 	wpa_printf(MSG_DEBUG, "EAP-TEAP: Correct password");
978 	new_id = os_memdup(username, userlen);
979 	if (new_id) {
980 		os_free(sm->identity);
981 		sm->identity = new_id;
982 		sm->identity_len = userlen;
983 	}
984 	if (sm->cfg->eap_teap_id != EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE ||
985 	    data->cur_id_type == TEAP_IDENTITY_TYPE_MACHINE)
986 		data->basic_auth_not_done = 0;
987 	eap_teap_state(data, CRYPTO_BINDING);
988 	eap_teap_update_icmk(sm, data);
989 }
990 
991 
eap_teap_parse_tlvs(struct wpabuf * data,struct eap_teap_tlv_parse * tlv)992 static int eap_teap_parse_tlvs(struct wpabuf *data,
993 			       struct eap_teap_tlv_parse *tlv)
994 {
995 	u16 tlv_type;
996 	int mandatory, res;
997 	size_t len;
998 	u8 *pos, *end;
999 
1000 	os_memset(tlv, 0, sizeof(*tlv));
1001 
1002 	pos = wpabuf_mhead(data);
1003 	end = pos + wpabuf_len(data);
1004 	while (end - pos > 4) {
1005 		mandatory = pos[0] & 0x80;
1006 		tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1007 		pos += 2;
1008 		len = WPA_GET_BE16(pos);
1009 		pos += 2;
1010 		if (len > (size_t) (end - pos)) {
1011 			wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1012 			return -1;
1013 		}
1014 		wpa_printf(MSG_DEBUG,
1015 			   "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1016 			   tlv_type, eap_teap_tlv_type_str(tlv_type),
1017 			   (unsigned int) len,
1018 			   mandatory ? " (mandatory)" : "");
1019 
1020 		res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
1021 		if (res == -2)
1022 			break;
1023 		if (res < 0) {
1024 			if (mandatory) {
1025 				wpa_printf(MSG_DEBUG,
1026 					   "EAP-TEAP: NAK unknown mandatory TLV type %u",
1027 					   tlv_type);
1028 				/* TODO: generate NAK TLV */
1029 				break;
1030 			}
1031 
1032 			wpa_printf(MSG_DEBUG,
1033 				   "EAP-TEAP: Ignore unknown optional TLV type %u",
1034 				   tlv_type);
1035 		}
1036 
1037 		pos += len;
1038 	}
1039 
1040 	return 0;
1041 }
1042 
1043 
eap_teap_validate_crypto_binding(struct eap_teap_data * data,const struct teap_tlv_crypto_binding * cb,size_t bind_len)1044 static int eap_teap_validate_crypto_binding(
1045 	struct eap_teap_data *data, const struct teap_tlv_crypto_binding *cb,
1046 	size_t bind_len)
1047 {
1048 	u8 flags, subtype;
1049 
1050 	subtype = cb->subtype & 0x0f;
1051 	flags = cb->subtype >> 4;
1052 
1053 	wpa_printf(MSG_DEBUG,
1054 		   "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
1055 		   cb->version, cb->received_version, flags, subtype);
1056 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
1057 		    cb->nonce, sizeof(cb->nonce));
1058 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
1059 		    cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
1060 	wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
1061 		    cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
1062 
1063 	if (cb->version != EAP_TEAP_VERSION ||
1064 	    cb->received_version != data->peer_version) {
1065 		wpa_printf(MSG_DEBUG,
1066 			   "EAP-TEAP: Unexpected version in Crypto-Binding: Version %u Received Version %u",
1067 			   cb->version, cb->received_version);
1068 		return -1;
1069 	}
1070 
1071 	if (flags < 1 || flags > 3) {
1072 		wpa_printf(MSG_DEBUG,
1073 			   "EAP-TEAP: Unexpected Flags in Crypto-Binding: %u",
1074 			   flags);
1075 		return -1;
1076 	}
1077 
1078 	if (subtype != TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
1079 		wpa_printf(MSG_DEBUG,
1080 			   "EAP-TEAP: Unexpected Sub-Type in Crypto-Binding: %u",
1081 			   subtype);
1082 		return -1;
1083 	}
1084 
1085 	if (os_memcmp_const(data->crypto_binding_nonce, cb->nonce,
1086 			    EAP_TEAP_NONCE_LEN - 1) != 0 ||
1087 	    (data->crypto_binding_nonce[EAP_TEAP_NONCE_LEN - 1] | 1) !=
1088 	    cb->nonce[EAP_TEAP_NONCE_LEN - 1]) {
1089 		wpa_printf(MSG_DEBUG,
1090 			   "EAP-TEAP: Invalid Nonce in Crypto-Binding");
1091 		return -1;
1092 	}
1093 
1094 	if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
1095 	    flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
1096 		u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
1097 
1098 		if (eap_teap_compound_mac(data->tls_cs, cb,
1099 					  data->server_outer_tlvs,
1100 					  data->peer_outer_tlvs, data->cmk_msk,
1101 					  msk_compound_mac) < 0)
1102 			return -1;
1103 		if (os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
1104 				    EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1105 			wpa_hexdump(MSG_DEBUG,
1106 				    "EAP-TEAP: Calculated MSK Compound MAC",
1107 				    msk_compound_mac,
1108 				    EAP_TEAP_COMPOUND_MAC_LEN);
1109 			wpa_printf(MSG_INFO,
1110 				   "EAP-TEAP: MSK Compound MAC did not match");
1111 			return -1;
1112 		}
1113 	}
1114 
1115 	if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
1116 	     flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
1117 	    data->cmk_emsk_available) {
1118 		u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
1119 
1120 		if (eap_teap_compound_mac(data->tls_cs, cb,
1121 					  data->server_outer_tlvs,
1122 					  data->peer_outer_tlvs, data->cmk_emsk,
1123 					  emsk_compound_mac) < 0)
1124 			return -1;
1125 		if (os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
1126 				    EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1127 			wpa_hexdump(MSG_DEBUG,
1128 				    "EAP-TEAP: Calculated EMSK Compound MAC",
1129 				    emsk_compound_mac,
1130 				    EAP_TEAP_COMPOUND_MAC_LEN);
1131 			wpa_printf(MSG_INFO,
1132 				   "EAP-TEAP: EMSK Compound MAC did not match");
1133 			return -1;
1134 		}
1135 	}
1136 
1137 	if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
1138 	    !data->cmk_emsk_available) {
1139 		wpa_printf(MSG_INFO,
1140 			   "EAP-TEAP: Peer included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
1141 		return -1;
1142 	}
1143 
1144 	if (data->cmk_emsk_available &&
1145 	    (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
1146 	     flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC)) {
1147 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Selected S-IMCK_EMSK");
1148 		os_memcpy(data->simck, data->simck_emsk, EAP_TEAP_SIMCK_LEN);
1149 	} else if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
1150 		   flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
1151 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Selected S-IMCK_EMSK");
1152 		os_memcpy(data->simck, data->simck_msk, EAP_TEAP_SIMCK_LEN);
1153 	}
1154 	wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Selected S-IMCK[j]",
1155 			data->simck, EAP_TEAP_SIMCK_LEN);
1156 
1157 	return 0;
1158 }
1159 
1160 
eap_teap_process_phase2_tlvs(struct eap_sm * sm,struct eap_teap_data * data,struct wpabuf * in_data)1161 static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
1162 					 struct eap_teap_data *data,
1163 					 struct wpabuf *in_data)
1164 {
1165 	struct eap_teap_tlv_parse tlv;
1166 	bool check_crypto_binding = data->state == CRYPTO_BINDING ||
1167 		data->check_crypto_binding;
1168 
1169 	if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
1170 		wpa_printf(MSG_DEBUG,
1171 			   "EAP-TEAP: Failed to parse received Phase 2 TLVs");
1172 		return;
1173 	}
1174 
1175 	if (tlv.result == TEAP_STATUS_FAILURE) {
1176 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Result TLV indicated failure");
1177 		eap_teap_state(data, FAILURE);
1178 		return;
1179 	}
1180 
1181 	if (tlv.nak) {
1182 		wpa_printf(MSG_DEBUG,
1183 			   "EAP-TEAP: Peer NAK'ed Vendor-Id %u NAK-Type %u",
1184 			   WPA_GET_BE32(tlv.nak), WPA_GET_BE16(tlv.nak + 4));
1185 		eap_teap_state(data, FAILURE_SEND_RESULT);
1186 		return;
1187 	}
1188 
1189 	if (check_crypto_binding) {
1190 		if (!tlv.crypto_binding) {
1191 			wpa_printf(MSG_DEBUG,
1192 				   "EAP-TEAP: No Crypto-Binding TLV received");
1193 			eap_teap_state(data, FAILURE);
1194 			return;
1195 		}
1196 
1197 		if (data->final_result &&
1198 		    tlv.result != TEAP_STATUS_SUCCESS) {
1199 			wpa_printf(MSG_DEBUG,
1200 				   "EAP-TEAP: Crypto-Binding TLV without Success Result");
1201 			eap_teap_state(data, FAILURE);
1202 			return;
1203 		}
1204 
1205 		if (sm->cfg->eap_teap_auth != 1 &&
1206 		    !data->skipped_inner_auth &&
1207 		    tlv.iresult != TEAP_STATUS_SUCCESS) {
1208 			wpa_printf(MSG_DEBUG,
1209 				   "EAP-TEAP: Crypto-Binding TLV without intermediate Success Result");
1210 			eap_teap_state(data, FAILURE);
1211 			return;
1212 		}
1213 
1214 		if (eap_teap_validate_crypto_binding(data, tlv.crypto_binding,
1215 						     tlv.crypto_binding_len)) {
1216 			eap_teap_state(data, FAILURE);
1217 			return;
1218 		}
1219 
1220 		wpa_printf(MSG_DEBUG,
1221 			   "EAP-TEAP: Valid Crypto-Binding TLV received");
1222 		data->check_crypto_binding = false;
1223 		if (data->final_result) {
1224 			wpa_printf(MSG_DEBUG,
1225 				   "EAP-TEAP: Authentication completed successfully");
1226 		}
1227 
1228 		if (data->final_result)
1229 			eap_teap_state(data, SUCCESS);
1230 		else if (sm->cfg->eap_teap_separate_result)
1231 			eap_teap_state(data, SUCCESS_SEND_RESULT);
1232 	}
1233 
1234 	if (tlv.basic_auth_resp) {
1235 		if (sm->cfg->eap_teap_auth != 1) {
1236 			wpa_printf(MSG_DEBUG,
1237 				   "EAP-TEAP: Unexpected Basic-Password-Auth-Resp when trying to use inner EAP");
1238 			eap_teap_state(data, FAILURE);
1239 			return;
1240 		}
1241 		eap_teap_process_basic_auth_resp(sm, data, tlv.basic_auth_resp,
1242 						 tlv.basic_auth_resp_len,
1243 						 tlv.identity_type);
1244 	}
1245 
1246 	if (tlv.eap_payload_tlv) {
1247 		if (sm->cfg->eap_teap_auth == 1) {
1248 			wpa_printf(MSG_DEBUG,
1249 				   "EAP-TEAP: Unexpected EAP Payload TLV when trying to use Basic-Password-Auth");
1250 			eap_teap_state(data, FAILURE);
1251 			return;
1252 		}
1253 		eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
1254 					    tlv.eap_payload_tlv_len,
1255 					    tlv.identity_type);
1256 	}
1257 
1258 	if (data->state == SUCCESS_SEND_RESULT &&
1259 	    tlv.result == TEAP_STATUS_SUCCESS) {
1260 		wpa_printf(MSG_DEBUG,
1261 			   "EAP-TEAP: Peer agreed with final success - authentication completed");
1262 		eap_teap_state(data, SUCCESS);
1263 	} else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
1264 		   sm->cfg->eap_teap_auth == 1 && data->basic_auth_not_done) {
1265 		wpa_printf(MSG_DEBUG,
1266 			   "EAP-TEAP: Continue with basic password authentication for second credential");
1267 		eap_teap_state(data, PHASE2_BASIC_AUTH);
1268 	} else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
1269 		   sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done &&
1270 		   sm->cfg->eap_teap_method_sequence == 1) {
1271 		wpa_printf(MSG_DEBUG,
1272 			   "EAP-TEAP: Continue with inner EAP authentication for second credential");
1273 		eap_teap_state(data, PHASE2_ID);
1274 		if (eap_teap_phase2_init(sm, data, EAP_VENDOR_IETF,
1275 					 EAP_TYPE_IDENTITY) < 0)
1276 			eap_teap_state(data, FAILURE);
1277 	}
1278 }
1279 
1280 
eap_teap_process_phase2(struct eap_sm * sm,struct eap_teap_data * data,struct wpabuf * in_buf)1281 static void eap_teap_process_phase2(struct eap_sm *sm,
1282 				    struct eap_teap_data *data,
1283 				    struct wpabuf *in_buf)
1284 {
1285 	struct wpabuf *in_decrypted;
1286 
1287 	wpa_printf(MSG_DEBUG,
1288 		   "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1289 		   (unsigned long) wpabuf_len(in_buf));
1290 
1291 	if (data->pending_phase2_resp) {
1292 		wpa_printf(MSG_DEBUG,
1293 			   "EAP-TEAP: Pending Phase 2 response - skip decryption and use old data");
1294 		eap_teap_process_phase2_tlvs(sm, data,
1295 					     data->pending_phase2_resp);
1296 		wpabuf_free(data->pending_phase2_resp);
1297 		data->pending_phase2_resp = NULL;
1298 		return;
1299 	}
1300 
1301 	in_decrypted = tls_connection_decrypt(sm->cfg->ssl_ctx, data->ssl.conn,
1302 					      in_buf);
1303 	if (!in_decrypted) {
1304 		wpa_printf(MSG_INFO,
1305 			   "EAP-TEAP: Failed to decrypt Phase 2 data");
1306 		eap_teap_state(data, FAILURE);
1307 		return;
1308 	}
1309 
1310 	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Decrypted Phase 2 TLVs",
1311 			    in_decrypted);
1312 
1313 	eap_teap_process_phase2_tlvs(sm, data, in_decrypted);
1314 
1315 	if (sm->method_pending == METHOD_PENDING_WAIT) {
1316 		wpa_printf(MSG_DEBUG,
1317 			   "EAP-TEAP: Phase 2 method is in pending wait state - save decrypted response");
1318 		wpabuf_free(data->pending_phase2_resp);
1319 		data->pending_phase2_resp = in_decrypted;
1320 		return;
1321 	}
1322 
1323 	wpabuf_free(in_decrypted);
1324 }
1325 
1326 
eap_teap_process_version(struct eap_sm * sm,void * priv,int peer_version)1327 static int eap_teap_process_version(struct eap_sm *sm, void *priv,
1328 				    int peer_version)
1329 {
1330 	struct eap_teap_data *data = priv;
1331 
1332 	if (peer_version < 1) {
1333 		/* Version 1 was the first defined version, so reject 0 */
1334 		wpa_printf(MSG_INFO,
1335 			   "EAP-TEAP: Peer used unknown TEAP version %u",
1336 			   peer_version);
1337 		return -1;
1338 	}
1339 
1340 	if (peer_version < data->teap_version) {
1341 		wpa_printf(MSG_DEBUG, "EAP-TEAP: peer ver=%u, own ver=%u; "
1342 			   "use version %u",
1343 			   peer_version, data->teap_version, peer_version);
1344 		data->teap_version = peer_version;
1345 	}
1346 
1347 	data->peer_version = peer_version;
1348 
1349 	return 0;
1350 }
1351 
1352 
eap_teap_process_phase1(struct eap_sm * sm,struct eap_teap_data * data)1353 static int eap_teap_process_phase1(struct eap_sm *sm,
1354 				   struct eap_teap_data *data)
1355 {
1356 	if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
1357 		wpa_printf(MSG_INFO, "EAP-TEAP: TLS processing failed");
1358 		eap_teap_state(data, FAILURE);
1359 		return -1;
1360 	}
1361 
1362 	if (!tls_connection_established(sm->cfg->ssl_ctx, data->ssl.conn) ||
1363 	    wpabuf_len(data->ssl.tls_out) > 0)
1364 		return 1;
1365 
1366 	/*
1367 	 * Phase 1 was completed with the received message (e.g., when using
1368 	 * abbreviated handshake), so Phase 2 can be started immediately
1369 	 * without having to send through an empty message to the peer.
1370 	 */
1371 
1372 	return eap_teap_phase1_done(sm, data);
1373 }
1374 
1375 
eap_teap_process_phase2_start(struct eap_sm * sm,struct eap_teap_data * data)1376 static int eap_teap_process_phase2_start(struct eap_sm *sm,
1377 					 struct eap_teap_data *data)
1378 {
1379 	int next_vendor;
1380 	enum eap_type next_type;
1381 
1382 	if (data->identity) {
1383 		/* Identity is from client certificate */
1384 		os_free(sm->identity);
1385 		sm->identity = data->identity;
1386 		data->identity = NULL;
1387 		sm->identity_len = data->identity_len;
1388 		data->identity_len = 0;
1389 		if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1390 			wpa_hexdump_ascii(MSG_DEBUG,
1391 					  "EAP-TEAP: Phase 2 Identity not found in the user database",
1392 					  sm->identity, sm->identity_len);
1393 			next_vendor = EAP_VENDOR_IETF;
1394 			next_type = EAP_TYPE_NONE;
1395 			eap_teap_state(data, PHASE2_METHOD);
1396 		} else if (sm->cfg->eap_teap_auth == 2) {
1397 			wpa_printf(MSG_DEBUG,
1398 				   "EAP-TEAP: Used client certificate and identity already known - skip inner auth");
1399 			data->skipped_inner_auth = 1;
1400 			if (eap_teap_derive_imck(data->tls_cs, data->simck,
1401 						 NULL, 0, NULL, 0,
1402 						 data->simck_msk, data->cmk_msk,
1403 						 data->simck_emsk,
1404 						 data->cmk_emsk))
1405 				return -1;
1406 			eap_teap_state(data, CRYPTO_BINDING);
1407 			return 1;
1408 		} else if (sm->cfg->eap_teap_auth == 1) {
1409 			eap_teap_state(data, PHASE2_BASIC_AUTH);
1410 			return 1;
1411 		} else {
1412 			wpa_printf(MSG_DEBUG,
1413 				   "EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
1414 			next_vendor = sm->user->methods[0].vendor;
1415 			next_type = sm->user->methods[0].method;
1416 			sm->user_eap_method_index = 1;
1417 			eap_teap_state(data, PHASE2_METHOD);
1418 		}
1419 
1420 	} else if (sm->cfg->eap_teap_auth == 1) {
1421 		eap_teap_state(data, PHASE2_BASIC_AUTH);
1422 		return 0;
1423 	} else {
1424 		eap_teap_state(data, PHASE2_ID);
1425 		next_vendor = EAP_VENDOR_IETF;
1426 		next_type = EAP_TYPE_IDENTITY;
1427 	}
1428 
1429 	return eap_teap_phase2_init(sm, data, next_vendor, next_type);
1430 }
1431 
1432 
eap_teap_process_msg(struct eap_sm * sm,void * priv,const struct wpabuf * respData)1433 static void eap_teap_process_msg(struct eap_sm *sm, void *priv,
1434 				 const struct wpabuf *respData)
1435 {
1436 	struct eap_teap_data *data = priv;
1437 
1438 	switch (data->state) {
1439 	case PHASE1:
1440 	case PHASE1B:
1441 		if (eap_teap_process_phase1(sm, data))
1442 			break;
1443 
1444 		/* fall through */
1445 	case PHASE2_START:
1446 		eap_teap_process_phase2_start(sm, data);
1447 		break;
1448 	case PHASE2_ID:
1449 	case PHASE2_BASIC_AUTH:
1450 	case PHASE2_METHOD:
1451 	case CRYPTO_BINDING:
1452 	case SUCCESS_SEND_RESULT:
1453 		eap_teap_process_phase2(sm, data, data->ssl.tls_in);
1454 		break;
1455 	case FAILURE_SEND_RESULT:
1456 		/* Protected failure result indication completed. Ignore the
1457 		 * received message (which is supposed to include Result TLV
1458 		 * indicating failure) and terminate exchange with cleartext
1459 		 * EAP-Failure. */
1460 		eap_teap_state(data, FAILURE);
1461 		break;
1462 	default:
1463 		wpa_printf(MSG_DEBUG, "EAP-TEAP: Unexpected state %d in %s",
1464 			   data->state, __func__);
1465 		break;
1466 	}
1467 }
1468 
1469 
eap_teap_process(struct eap_sm * sm,void * priv,struct wpabuf * respData)1470 static void eap_teap_process(struct eap_sm *sm, void *priv,
1471 			     struct wpabuf *respData)
1472 {
1473 	struct eap_teap_data *data = priv;
1474 	const u8 *pos;
1475 	size_t len;
1476 	struct wpabuf *resp = respData;
1477 	u8 flags;
1478 
1479 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
1480 	if (!pos || len < 1)
1481 		return;
1482 
1483 	flags = *pos++;
1484 	len--;
1485 
1486 	if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1487 		/* Extract Outer TLVs from the message before common TLS
1488 		 * processing */
1489 		u32 message_len = 0, outer_tlv_len;
1490 		const u8 *hdr;
1491 
1492 		if (data->state != PHASE1) {
1493 			wpa_printf(MSG_INFO,
1494 				   "EAP-TEAP: Unexpected Outer TLVs in a message that is not the first message from the peer");
1495 			return;
1496 		}
1497 
1498 		if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1499 			if (len < 4) {
1500 				wpa_printf(MSG_INFO,
1501 					   "EAP-TEAP: Too short message to include Message Length field");
1502 				return;
1503 			}
1504 
1505 			message_len = WPA_GET_BE32(pos);
1506 			pos += 4;
1507 			len -= 4;
1508 			if (message_len < 4) {
1509 				wpa_printf(MSG_INFO,
1510 					   "EAP-TEAP: Message Length field has too msall value to include Outer TLV Length field");
1511 				return;
1512 			}
1513 		}
1514 
1515 		if (len < 4) {
1516 			wpa_printf(MSG_INFO,
1517 				   "EAP-TEAP: Too short message to include Outer TLVs Length field");
1518 			return;
1519 		}
1520 
1521 		outer_tlv_len = WPA_GET_BE32(pos);
1522 		pos += 4;
1523 		len -= 4;
1524 
1525 		wpa_printf(MSG_DEBUG,
1526 			   "EAP-TEAP: Message Length %u Outer TLV Length %u",
1527 			  message_len, outer_tlv_len);
1528 		if (len < outer_tlv_len) {
1529 			wpa_printf(MSG_INFO,
1530 				   "EAP-TEAP: Too short message to include Outer TLVs field");
1531 			return;
1532 		}
1533 
1534 		if (message_len &&
1535 		    (message_len < outer_tlv_len ||
1536 		     message_len < 4 + outer_tlv_len)) {
1537 			wpa_printf(MSG_INFO,
1538 				   "EAP-TEAP: Message Length field has too small value to include Outer TLVs");
1539 			return;
1540 		}
1541 
1542 		if (wpabuf_len(respData) < 4 + outer_tlv_len ||
1543 		    len < outer_tlv_len)
1544 			return;
1545 		resp = wpabuf_alloc(wpabuf_len(respData) - 4 - outer_tlv_len);
1546 		if (!resp)
1547 			return;
1548 		hdr = wpabuf_head(respData);
1549 		wpabuf_put_u8(resp, *hdr++); /* Code */
1550 		wpabuf_put_u8(resp, *hdr++); /* Identifier */
1551 		wpabuf_put_be16(resp, WPA_GET_BE16(hdr) - 4 - outer_tlv_len);
1552 		hdr += 2;
1553 		wpabuf_put_u8(resp, *hdr++); /* Type */
1554 		/* Flags | Ver */
1555 		wpabuf_put_u8(resp, flags & ~EAP_TEAP_FLAGS_OUTER_TLV_LEN);
1556 
1557 		if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)
1558 			wpabuf_put_be32(resp, message_len - 4 - outer_tlv_len);
1559 
1560 		wpabuf_put_data(resp, pos, len - outer_tlv_len);
1561 		pos += len - outer_tlv_len;
1562 		wpabuf_free(data->peer_outer_tlvs);
1563 		data->peer_outer_tlvs = wpabuf_alloc_copy(pos, outer_tlv_len);
1564 		if (!data->peer_outer_tlvs)
1565 			return;
1566 		wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Outer TLVs",
1567 				data->peer_outer_tlvs);
1568 
1569 		wpa_hexdump_buf(MSG_DEBUG,
1570 				"EAP-TEAP: TLS Data message after Outer TLV removal",
1571 				resp);
1572 		pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, resp,
1573 				       &len);
1574 		if (!pos || len < 1) {
1575 			wpa_printf(MSG_INFO,
1576 				   "EAP-TEAP: Invalid frame after Outer TLV removal");
1577 			return;
1578 		}
1579 	}
1580 
1581 	if (data->state == PHASE1)
1582 		eap_teap_state(data, PHASE1B);
1583 
1584 	if (eap_server_tls_process(sm, &data->ssl, resp, data,
1585 				   EAP_TYPE_TEAP, eap_teap_process_version,
1586 				   eap_teap_process_msg) < 0)
1587 		eap_teap_state(data, FAILURE);
1588 
1589 	if (resp != respData)
1590 		wpabuf_free(resp);
1591 }
1592 
1593 
eap_teap_isDone(struct eap_sm * sm,void * priv)1594 static bool eap_teap_isDone(struct eap_sm *sm, void *priv)
1595 {
1596 	struct eap_teap_data *data = priv;
1597 
1598 	return data->state == SUCCESS || data->state == FAILURE;
1599 }
1600 
1601 
eap_teap_getKey(struct eap_sm * sm,void * priv,size_t * len)1602 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
1603 {
1604 	struct eap_teap_data *data = priv;
1605 	u8 *eapKeyData;
1606 
1607 	if (data->state != SUCCESS)
1608 		return NULL;
1609 
1610 	eapKeyData = os_malloc(EAP_TEAP_KEY_LEN);
1611 	if (!eapKeyData)
1612 		return NULL;
1613 
1614 	if (eap_teap_derive_eap_msk(data->tls_cs, data->simck,
1615 				    eapKeyData) < 0) {
1616 		os_free(eapKeyData);
1617 		return NULL;
1618 	}
1619 	*len = EAP_TEAP_KEY_LEN;
1620 
1621 	return eapKeyData;
1622 }
1623 
1624 
eap_teap_get_emsk(struct eap_sm * sm,void * priv,size_t * len)1625 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
1626 {
1627 	struct eap_teap_data *data = priv;
1628 	u8 *eapKeyData;
1629 
1630 	if (data->state != SUCCESS)
1631 		return NULL;
1632 
1633 	eapKeyData = os_malloc(EAP_EMSK_LEN);
1634 	if (!eapKeyData)
1635 		return NULL;
1636 
1637 	if (eap_teap_derive_eap_emsk(data->tls_cs, data->simck,
1638 				     eapKeyData) < 0) {
1639 		os_free(eapKeyData);
1640 		return NULL;
1641 	}
1642 	*len = EAP_EMSK_LEN;
1643 
1644 	return eapKeyData;
1645 }
1646 
1647 
eap_teap_isSuccess(struct eap_sm * sm,void * priv)1648 static bool eap_teap_isSuccess(struct eap_sm *sm, void *priv)
1649 {
1650 	struct eap_teap_data *data = priv;
1651 
1652 	return data->state == SUCCESS;
1653 }
1654 
1655 
eap_teap_get_session_id(struct eap_sm * sm,void * priv,size_t * len)1656 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
1657 {
1658 	struct eap_teap_data *data = priv;
1659 	const size_t max_id_len = 100;
1660 	int res;
1661 	u8 *id;
1662 
1663 	if (data->state != SUCCESS)
1664 		return NULL;
1665 
1666 	id = os_malloc(max_id_len);
1667 	if (!id)
1668 		return NULL;
1669 
1670 	id[0] = EAP_TYPE_TEAP;
1671 	res = tls_get_tls_unique(data->ssl.conn, id + 1, max_id_len - 1);
1672 	if (res < 0) {
1673 		os_free(id);
1674 		wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
1675 		return NULL;
1676 	}
1677 
1678 	*len = 1 + res;
1679 	wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id", id, *len);
1680 	return id;
1681 }
1682 
1683 
eap_server_teap_register(void)1684 int eap_server_teap_register(void)
1685 {
1686 	struct eap_method *eap;
1687 
1688 	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1689 				      EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
1690 	if (!eap)
1691 		return -1;
1692 
1693 	eap->init = eap_teap_init;
1694 	eap->reset = eap_teap_reset;
1695 	eap->buildReq = eap_teap_buildReq;
1696 	eap->check = eap_teap_check;
1697 	eap->process = eap_teap_process;
1698 	eap->isDone = eap_teap_isDone;
1699 	eap->getKey = eap_teap_getKey;
1700 	eap->get_emsk = eap_teap_get_emsk;
1701 	eap->isSuccess = eap_teap_isSuccess;
1702 	eap->getSessionId = eap_teap_get_session_id;
1703 
1704 	return eap_server_method_register(eap);
1705 }
1706