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