]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/eap_server/eap_server_teap.c
EAP-TEAP server: Add support for requiring user and machine credentials
[thirdparty/hostap.git] / src / eap_server / eap_server_teap.c
1 /*
2 * EAP-TEAP server (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/aes_wrap.h"
13 #include "crypto/tls.h"
14 #include "crypto/random.h"
15 #include "eap_common/eap_teap_common.h"
16 #include "eap_i.h"
17 #include "eap_tls_common.h"
18
19
20 static void eap_teap_reset(struct eap_sm *sm, void *priv);
21
22
23 /* Private PAC-Opaque TLV types */
24 #define PAC_OPAQUE_TYPE_PAD 0
25 #define PAC_OPAQUE_TYPE_KEY 1
26 #define PAC_OPAQUE_TYPE_LIFETIME 2
27 #define PAC_OPAQUE_TYPE_IDENTITY 3
28
29 struct eap_teap_data {
30 struct eap_ssl_data ssl;
31 enum {
32 START, PHASE1, PHASE1B, PHASE2_START, PHASE2_ID,
33 PHASE2_BASIC_AUTH, PHASE2_METHOD, CRYPTO_BINDING, REQUEST_PAC,
34 FAILURE_SEND_RESULT, SUCCESS_SEND_RESULT, SUCCESS, FAILURE
35 } state;
36
37 u8 teap_version;
38 u8 peer_version;
39 u16 tls_cs;
40
41 const struct eap_method *phase2_method;
42 void *phase2_priv;
43
44 u8 crypto_binding_nonce[32];
45 int final_result;
46
47 u8 simck_msk[EAP_TEAP_SIMCK_LEN];
48 u8 cmk_msk[EAP_TEAP_CMK_LEN];
49 u8 simck_emsk[EAP_TEAP_SIMCK_LEN];
50 u8 cmk_emsk[EAP_TEAP_CMK_LEN];
51 int simck_idx;
52 int cmk_emsk_available;
53
54 u8 pac_opaque_encr[16];
55 u8 *srv_id;
56 size_t srv_id_len;
57 char *srv_id_info;
58
59 unsigned int basic_auth_not_done:1;
60 unsigned int inner_eap_not_done:1;
61 int anon_provisioning;
62 int skipped_inner_auth;
63 int send_new_pac; /* server triggered re-keying of Tunnel PAC */
64 struct wpabuf *pending_phase2_resp;
65 struct wpabuf *server_outer_tlvs;
66 struct wpabuf *peer_outer_tlvs;
67 u8 *identity; /* from PAC-Opaque */
68 size_t identity_len;
69 int eap_seq;
70 int tnc_started;
71
72 int pac_key_lifetime;
73 int pac_key_refresh_time;
74
75 enum teap_error_codes error_code;
76 enum teap_identity_types cur_id_type;
77 };
78
79
80 static int eap_teap_process_phase2_start(struct eap_sm *sm,
81 struct eap_teap_data *data);
82
83
84 static const char * eap_teap_state_txt(int state)
85 {
86 switch (state) {
87 case START:
88 return "START";
89 case PHASE1:
90 return "PHASE1";
91 case PHASE1B:
92 return "PHASE1B";
93 case PHASE2_START:
94 return "PHASE2_START";
95 case PHASE2_ID:
96 return "PHASE2_ID";
97 case PHASE2_BASIC_AUTH:
98 return "PHASE2_BASIC_AUTH";
99 case PHASE2_METHOD:
100 return "PHASE2_METHOD";
101 case CRYPTO_BINDING:
102 return "CRYPTO_BINDING";
103 case REQUEST_PAC:
104 return "REQUEST_PAC";
105 case FAILURE_SEND_RESULT:
106 return "FAILURE_SEND_RESULT";
107 case SUCCESS_SEND_RESULT:
108 return "SUCCESS_SEND_RESULT";
109 case SUCCESS:
110 return "SUCCESS";
111 case FAILURE:
112 return "FAILURE";
113 default:
114 return "Unknown?!";
115 }
116 }
117
118
119 static void eap_teap_state(struct eap_teap_data *data, int state)
120 {
121 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s -> %s",
122 eap_teap_state_txt(data->state),
123 eap_teap_state_txt(state));
124 data->state = state;
125 }
126
127
128 static enum eap_type eap_teap_req_failure(struct eap_teap_data *data,
129 enum teap_error_codes error)
130 {
131 eap_teap_state(data, FAILURE_SEND_RESULT);
132 return EAP_TYPE_NONE;
133 }
134
135
136 static int eap_teap_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
137 const u8 *client_random,
138 const u8 *server_random,
139 u8 *master_secret)
140 {
141 struct eap_teap_data *data = ctx;
142 const u8 *pac_opaque;
143 size_t pac_opaque_len;
144 u8 *buf, *pos, *end, *pac_key = NULL;
145 os_time_t lifetime = 0;
146 struct os_time now;
147 u8 *identity = NULL;
148 size_t identity_len = 0;
149
150 wpa_printf(MSG_DEBUG, "EAP-TEAP: SessionTicket callback");
151 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: SessionTicket (PAC-Opaque)",
152 ticket, len);
153
154 if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) {
155 wpa_printf(MSG_DEBUG, "EAP-TEAP: Ignore invalid SessionTicket");
156 return 0;
157 }
158
159 pac_opaque_len = WPA_GET_BE16(ticket + 2);
160 pac_opaque = ticket + 4;
161 if (pac_opaque_len < 8 || pac_opaque_len % 8 ||
162 pac_opaque_len > len - 4) {
163 wpa_printf(MSG_DEBUG,
164 "EAP-TEAP: Ignore invalid PAC-Opaque (len=%lu left=%lu)",
165 (unsigned long) pac_opaque_len,
166 (unsigned long) len);
167 return 0;
168 }
169 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Received PAC-Opaque",
170 pac_opaque, pac_opaque_len);
171
172 buf = os_malloc(pac_opaque_len - 8);
173 if (!buf) {
174 wpa_printf(MSG_DEBUG,
175 "EAP-TEAP: Failed to allocate memory for decrypting PAC-Opaque");
176 return 0;
177 }
178
179 if (aes_unwrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
180 (pac_opaque_len - 8) / 8, pac_opaque, buf) < 0) {
181 wpa_printf(MSG_DEBUG, "EAP-TEAP: Failed to decrypt PAC-Opaque");
182 os_free(buf);
183 /*
184 * This may have been caused by server changing the PAC-Opaque
185 * encryption key, so just ignore this PAC-Opaque instead of
186 * failing the authentication completely. Provisioning can now
187 * be used to provision a new PAC.
188 */
189 return 0;
190 }
191
192 end = buf + pac_opaque_len - 8;
193 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Decrypted PAC-Opaque",
194 buf, end - buf);
195
196 pos = buf;
197 while (end - pos > 1) {
198 u8 id, elen;
199
200 id = *pos++;
201 elen = *pos++;
202 if (elen > end - pos)
203 break;
204
205 switch (id) {
206 case PAC_OPAQUE_TYPE_PAD:
207 goto done;
208 case PAC_OPAQUE_TYPE_KEY:
209 if (elen != EAP_TEAP_PAC_KEY_LEN) {
210 wpa_printf(MSG_DEBUG,
211 "EAP-TEAP: Invalid PAC-Key length %d",
212 elen);
213 os_free(buf);
214 return -1;
215 }
216 pac_key = pos;
217 wpa_hexdump_key(MSG_DEBUG,
218 "EAP-TEAP: PAC-Key from decrypted PAC-Opaque",
219 pac_key, EAP_TEAP_PAC_KEY_LEN);
220 break;
221 case PAC_OPAQUE_TYPE_LIFETIME:
222 if (elen != 4) {
223 wpa_printf(MSG_DEBUG,
224 "EAP-TEAP: Invalid PAC-Key lifetime length %d",
225 elen);
226 os_free(buf);
227 return -1;
228 }
229 lifetime = WPA_GET_BE32(pos);
230 break;
231 case PAC_OPAQUE_TYPE_IDENTITY:
232 identity = pos;
233 identity_len = elen;
234 break;
235 }
236
237 pos += elen;
238 }
239 done:
240
241 if (!pac_key) {
242 wpa_printf(MSG_DEBUG,
243 "EAP-TEAP: No PAC-Key included in PAC-Opaque");
244 os_free(buf);
245 return -1;
246 }
247
248 if (identity) {
249 wpa_hexdump_ascii(MSG_DEBUG,
250 "EAP-TEAP: Identity from PAC-Opaque",
251 identity, identity_len);
252 os_free(data->identity);
253 data->identity = os_malloc(identity_len);
254 if (data->identity) {
255 os_memcpy(data->identity, identity, identity_len);
256 data->identity_len = identity_len;
257 }
258 }
259
260 if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) {
261 wpa_printf(MSG_DEBUG,
262 "EAP-TEAP: PAC-Key not valid anymore (lifetime=%ld now=%ld)",
263 lifetime, now.sec);
264 data->send_new_pac = 2;
265 /*
266 * Allow PAC to be used to allow a PAC update with some level
267 * of server authentication (i.e., do not fall back to full TLS
268 * handshake since we cannot be sure that the peer would be
269 * able to validate server certificate now). However, reject
270 * the authentication since the PAC was not valid anymore. Peer
271 * can connect again with the newly provisioned PAC after this.
272 */
273 } else if (lifetime - now.sec < data->pac_key_refresh_time) {
274 wpa_printf(MSG_DEBUG,
275 "EAP-TEAP: PAC-Key soft timeout; send an update if authentication succeeds");
276 data->send_new_pac = 1;
277 }
278
279 /* EAP-TEAP uses PAC-Key as the TLS master_secret */
280 os_memcpy(master_secret, pac_key, EAP_TEAP_PAC_KEY_LEN);
281
282 os_free(buf);
283
284 return 1;
285 }
286
287
288 static int eap_teap_derive_key_auth(struct eap_sm *sm,
289 struct eap_teap_data *data)
290 {
291 int res;
292
293 /* RFC 7170, Section 5.1 */
294 res = tls_connection_export_key(sm->cfg->ssl_ctx, data->ssl.conn,
295 TEAP_TLS_EXPORTER_LABEL_SKS, NULL, 0,
296 data->simck_msk, EAP_TEAP_SIMCK_LEN);
297 if (res)
298 return res;
299 wpa_hexdump_key(MSG_DEBUG,
300 "EAP-TEAP: session_key_seed (S-IMCK[0])",
301 data->simck_msk, EAP_TEAP_SIMCK_LEN);
302 os_memcpy(data->simck_emsk, data->simck_msk, EAP_TEAP_SIMCK_LEN);
303 data->simck_idx = 0;
304 return 0;
305 }
306
307
308 static int eap_teap_update_icmk(struct eap_sm *sm, struct eap_teap_data *data)
309 {
310 u8 *msk = NULL, *emsk = NULL;
311 size_t msk_len = 0, emsk_len = 0;
312 int res;
313
314 wpa_printf(MSG_DEBUG, "EAP-TEAP: Deriving ICMK[%d] (S-IMCK and CMK)",
315 data->simck_idx + 1);
316
317 if (sm->cfg->eap_teap_auth == 1)
318 return eap_teap_derive_cmk_basic_pw_auth(data->tls_cs,
319 data->simck_msk,
320 data->cmk_msk);
321
322 if (!data->phase2_method || !data->phase2_priv) {
323 wpa_printf(MSG_INFO, "EAP-TEAP: Phase 2 method not available");
324 return -1;
325 }
326
327 if (data->phase2_method->getKey) {
328 msk = data->phase2_method->getKey(sm, data->phase2_priv,
329 &msk_len);
330 if (!msk) {
331 wpa_printf(MSG_INFO,
332 "EAP-TEAP: Could not fetch Phase 2 MSK");
333 return -1;
334 }
335 }
336
337 if (data->phase2_method->get_emsk) {
338 emsk = data->phase2_method->get_emsk(sm, data->phase2_priv,
339 &emsk_len);
340 }
341
342 res = eap_teap_derive_imck(data->tls_cs,
343 data->simck_msk, data->simck_emsk,
344 msk, msk_len, emsk, emsk_len,
345 data->simck_msk, data->cmk_msk,
346 data->simck_emsk, data->cmk_emsk);
347 bin_clear_free(msk, msk_len);
348 bin_clear_free(emsk, emsk_len);
349 if (res == 0) {
350 data->simck_idx++;
351 if (emsk)
352 data->cmk_emsk_available = 1;
353 }
354 return 0;
355 }
356
357
358 static void * eap_teap_init(struct eap_sm *sm)
359 {
360 struct eap_teap_data *data;
361
362 data = os_zalloc(sizeof(*data));
363 if (!data)
364 return NULL;
365 data->teap_version = EAP_TEAP_VERSION;
366 data->state = START;
367
368 if (eap_server_tls_ssl_init(sm, &data->ssl, 0, EAP_TYPE_TEAP)) {
369 wpa_printf(MSG_INFO, "EAP-TEAP: Failed to initialize SSL.");
370 eap_teap_reset(sm, data);
371 return NULL;
372 }
373
374 /* TODO: Add anon-DH TLS cipher suites (and if one is negotiated,
375 * enforce inner EAP with mutual authentication to be used) */
376
377 if (tls_connection_set_session_ticket_cb(sm->cfg->ssl_ctx,
378 data->ssl.conn,
379 eap_teap_session_ticket_cb,
380 data) < 0) {
381 wpa_printf(MSG_INFO,
382 "EAP-TEAP: Failed to set SessionTicket callback");
383 eap_teap_reset(sm, data);
384 return NULL;
385 }
386
387 if (!sm->cfg->pac_opaque_encr_key) {
388 wpa_printf(MSG_INFO,
389 "EAP-TEAP: No PAC-Opaque encryption key configured");
390 eap_teap_reset(sm, data);
391 return NULL;
392 }
393 os_memcpy(data->pac_opaque_encr, sm->cfg->pac_opaque_encr_key,
394 sizeof(data->pac_opaque_encr));
395
396 if (!sm->cfg->eap_fast_a_id) {
397 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID configured");
398 eap_teap_reset(sm, data);
399 return NULL;
400 }
401 data->srv_id = os_malloc(sm->cfg->eap_fast_a_id_len);
402 if (!data->srv_id) {
403 eap_teap_reset(sm, data);
404 return NULL;
405 }
406 os_memcpy(data->srv_id, sm->cfg->eap_fast_a_id,
407 sm->cfg->eap_fast_a_id_len);
408 data->srv_id_len = sm->cfg->eap_fast_a_id_len;
409
410 if (!sm->cfg->eap_fast_a_id_info) {
411 wpa_printf(MSG_INFO, "EAP-TEAP: No A-ID-Info configured");
412 eap_teap_reset(sm, data);
413 return NULL;
414 }
415 data->srv_id_info = os_strdup(sm->cfg->eap_fast_a_id_info);
416 if (!data->srv_id_info) {
417 eap_teap_reset(sm, data);
418 return NULL;
419 }
420
421 /* PAC-Key lifetime in seconds (hard limit) */
422 data->pac_key_lifetime = sm->cfg->pac_key_lifetime;
423
424 /*
425 * PAC-Key refresh time in seconds (soft limit on remaining hard
426 * limit). The server will generate a new PAC-Key when this number of
427 * seconds (or fewer) of the lifetime remains.
428 */
429 data->pac_key_refresh_time = sm->cfg->pac_key_refresh_time;
430
431 return data;
432 }
433
434
435 static void eap_teap_reset(struct eap_sm *sm, void *priv)
436 {
437 struct eap_teap_data *data = priv;
438
439 if (!data)
440 return;
441 if (data->phase2_priv && data->phase2_method)
442 data->phase2_method->reset(sm, data->phase2_priv);
443 eap_server_tls_ssl_deinit(sm, &data->ssl);
444 os_free(data->srv_id);
445 os_free(data->srv_id_info);
446 wpabuf_free(data->pending_phase2_resp);
447 wpabuf_free(data->server_outer_tlvs);
448 wpabuf_free(data->peer_outer_tlvs);
449 os_free(data->identity);
450 forced_memzero(data->simck_msk, EAP_TEAP_SIMCK_LEN);
451 forced_memzero(data->simck_emsk, EAP_TEAP_SIMCK_LEN);
452 forced_memzero(data->cmk_msk, EAP_TEAP_CMK_LEN);
453 forced_memzero(data->cmk_emsk, EAP_TEAP_CMK_LEN);
454 forced_memzero(data->pac_opaque_encr, sizeof(data->pac_opaque_encr));
455 bin_clear_free(data, sizeof(*data));
456 }
457
458
459 static struct wpabuf * eap_teap_build_start(struct eap_sm *sm,
460 struct eap_teap_data *data, u8 id)
461 {
462 struct wpabuf *req;
463 size_t outer_tlv_len = sizeof(struct teap_tlv_hdr) + data->srv_id_len;
464 const u8 *start, *end;
465
466 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TEAP,
467 1 + 4 + outer_tlv_len, EAP_CODE_REQUEST, id);
468 if (!req) {
469 wpa_printf(MSG_ERROR,
470 "EAP-TEAP: Failed to allocate memory for request");
471 eap_teap_state(data, FAILURE);
472 return NULL;
473 }
474
475 wpabuf_put_u8(req, EAP_TLS_FLAGS_START | EAP_TEAP_FLAGS_OUTER_TLV_LEN |
476 data->teap_version);
477 wpabuf_put_be32(req, outer_tlv_len);
478
479 start = wpabuf_put(req, 0);
480
481 /* RFC 7170, Section 4.2.2: Authority-ID TLV */
482 eap_teap_put_tlv(req, TEAP_TLV_AUTHORITY_ID,
483 data->srv_id, data->srv_id_len);
484
485 end = wpabuf_put(req, 0);
486 wpabuf_free(data->server_outer_tlvs);
487 data->server_outer_tlvs = wpabuf_alloc_copy(start, end - start);
488 if (!data->server_outer_tlvs) {
489 eap_teap_state(data, FAILURE);
490 return NULL;
491 }
492
493 eap_teap_state(data, PHASE1);
494
495 return req;
496 }
497
498
499 static int eap_teap_phase1_done(struct eap_sm *sm, struct eap_teap_data *data)
500 {
501 char cipher[64];
502
503 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 1 done, starting Phase 2");
504
505 data->tls_cs = tls_connection_get_cipher_suite(data->ssl.conn);
506 wpa_printf(MSG_DEBUG, "EAP-TEAP: TLS cipher suite 0x%04x",
507 data->tls_cs);
508
509 if (tls_get_cipher(sm->cfg->ssl_ctx, data->ssl.conn,
510 cipher, sizeof(cipher)) < 0) {
511 wpa_printf(MSG_DEBUG,
512 "EAP-TEAP: Failed to get cipher information");
513 eap_teap_state(data, FAILURE);
514 return -1;
515 }
516 data->anon_provisioning = os_strstr(cipher, "ADH") != NULL;
517
518 if (data->anon_provisioning)
519 wpa_printf(MSG_DEBUG, "EAP-TEAP: Anonymous provisioning");
520
521 if (eap_teap_derive_key_auth(sm, data) < 0) {
522 eap_teap_state(data, FAILURE);
523 return -1;
524 }
525
526 eap_teap_state(data, PHASE2_START);
527
528 return 0;
529 }
530
531
532 static struct wpabuf * eap_teap_build_phase2_req(struct eap_sm *sm,
533 struct eap_teap_data *data,
534 u8 id)
535 {
536 struct wpabuf *req, *id_tlv = NULL;
537
538 if (sm->cfg->eap_teap_auth == 1 ||
539 (data->phase2_priv && data->phase2_method &&
540 data->phase2_method->vendor == EAP_VENDOR_IETF &&
541 data->phase2_method->method == EAP_TYPE_IDENTITY)) {
542 switch (sm->cfg->eap_teap_id) {
543 case EAP_TEAP_ID_ALLOW_ANY:
544 break;
545 case EAP_TEAP_ID_REQUIRE_USER:
546 case EAP_TEAP_ID_REQUEST_USER_ACCEPT_MACHINE:
547 data->cur_id_type = TEAP_IDENTITY_TYPE_USER;
548 id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
549 break;
550 case EAP_TEAP_ID_REQUIRE_MACHINE:
551 case EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER:
552 data->cur_id_type = TEAP_IDENTITY_TYPE_MACHINE;
553 id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
554 break;
555 case EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE:
556 if (data->cur_id_type == TEAP_IDENTITY_TYPE_USER)
557 data->cur_id_type = TEAP_IDENTITY_TYPE_MACHINE;
558 else
559 data->cur_id_type = TEAP_IDENTITY_TYPE_USER;
560 id_tlv = eap_teap_tlv_identity_type(data->cur_id_type);
561 break;
562 }
563 }
564
565 if (sm->cfg->eap_teap_auth == 1) {
566 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate Basic-Password-Auth");
567 data->basic_auth_not_done = 1;
568 req = wpabuf_alloc(sizeof(struct teap_tlv_hdr));
569 if (!req) {
570 wpabuf_free(id_tlv);
571 return NULL;
572 }
573 eap_teap_put_tlv_hdr(req, TEAP_TLV_BASIC_PASSWORD_AUTH_REQ, 0);
574 return wpabuf_concat(req, id_tlv);
575 }
576
577 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initiate inner EAP method");
578 data->inner_eap_not_done = 1;
579 if (!data->phase2_priv) {
580 wpa_printf(MSG_DEBUG,
581 "EAP-TEAP: Phase 2 method not initialized");
582 wpabuf_free(id_tlv);
583 return NULL;
584 }
585
586 req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
587 if (!req) {
588 wpabuf_free(id_tlv);
589 return NULL;
590 }
591
592 wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-TEAP: Phase 2 EAP-Request", req);
593
594 return wpabuf_concat(eap_teap_tlv_eap_payload(req), id_tlv);
595 }
596
597
598 static struct wpabuf * eap_teap_build_crypto_binding(
599 struct eap_sm *sm, struct eap_teap_data *data)
600 {
601 struct wpabuf *buf;
602 struct teap_tlv_result *result;
603 struct teap_tlv_crypto_binding *cb;
604 u8 subtype, flags;
605
606 buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*cb));
607 if (!buf)
608 return NULL;
609
610 if (data->send_new_pac || data->anon_provisioning ||
611 data->basic_auth_not_done || data->inner_eap_not_done ||
612 data->phase2_method || sm->cfg->eap_teap_separate_result)
613 data->final_result = 0;
614 else
615 data->final_result = 1;
616
617 if (!data->final_result || data->eap_seq > 0 ||
618 sm->cfg->eap_teap_auth == 1) {
619 /* Intermediate-Result */
620 wpa_printf(MSG_DEBUG,
621 "EAP-TEAP: Add Intermediate-Result TLV (status=SUCCESS)");
622 result = wpabuf_put(buf, sizeof(*result));
623 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
624 TEAP_TLV_INTERMEDIATE_RESULT);
625 result->length = host_to_be16(2);
626 result->status = host_to_be16(TEAP_STATUS_SUCCESS);
627 }
628
629 if (data->final_result) {
630 /* Result TLV */
631 wpa_printf(MSG_DEBUG,
632 "EAP-TEAP: Add Result TLV (status=SUCCESS)");
633 result = wpabuf_put(buf, sizeof(*result));
634 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
635 TEAP_TLV_RESULT);
636 result->length = host_to_be16(2);
637 result->status = host_to_be16(TEAP_STATUS_SUCCESS);
638 }
639
640 /* Crypto-Binding TLV */
641 cb = wpabuf_put(buf, sizeof(*cb));
642 cb->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
643 TEAP_TLV_CRYPTO_BINDING);
644 cb->length = host_to_be16(sizeof(*cb) - sizeof(struct teap_tlv_hdr));
645 cb->version = EAP_TEAP_VERSION;
646 cb->received_version = data->peer_version;
647 /* FIX: RFC 7170 is not clear on which Flags value to use when
648 * Crypto-Binding TLV is used with Basic-Password-Auth */
649 flags = data->cmk_emsk_available ?
650 TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC :
651 TEAP_CRYPTO_BINDING_MSK_CMAC;
652 subtype = TEAP_CRYPTO_BINDING_SUBTYPE_REQUEST;
653 cb->subtype = (flags << 4) | subtype;
654 if (random_get_bytes(cb->nonce, sizeof(cb->nonce)) < 0) {
655 wpabuf_free(buf);
656 return NULL;
657 }
658
659 /*
660 * RFC 7170, Section 4.2.13:
661 * The nonce in a request MUST have its least significant bit set to 0.
662 */
663 cb->nonce[sizeof(cb->nonce) - 1] &= ~0x01;
664
665 os_memcpy(data->crypto_binding_nonce, cb->nonce, sizeof(cb->nonce));
666
667 if (eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
668 data->peer_outer_tlvs, data->cmk_msk,
669 cb->msk_compound_mac) < 0) {
670 wpabuf_free(buf);
671 return NULL;
672 }
673
674 if (data->cmk_emsk_available &&
675 eap_teap_compound_mac(data->tls_cs, cb, data->server_outer_tlvs,
676 data->peer_outer_tlvs, data->cmk_emsk,
677 cb->emsk_compound_mac) < 0) {
678 wpabuf_free(buf);
679 return NULL;
680 }
681
682 wpa_printf(MSG_DEBUG,
683 "EAP-TEAP: Add Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
684 cb->version, cb->received_version, flags, subtype);
685 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
686 cb->nonce, sizeof(cb->nonce));
687 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
688 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
689 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
690 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
691
692 return buf;
693 }
694
695
696 static struct wpabuf * eap_teap_build_pac(struct eap_sm *sm,
697 struct eap_teap_data *data)
698 {
699 u8 pac_key[EAP_TEAP_PAC_KEY_LEN];
700 u8 *pac_buf, *pac_opaque;
701 struct wpabuf *buf;
702 u8 *pos;
703 size_t buf_len, srv_id_info_len, pac_len;
704 struct teap_tlv_hdr *pac_tlv;
705 struct pac_attr_hdr *pac_info;
706 struct teap_tlv_result *result;
707 struct os_time now;
708
709 wpa_printf(MSG_DEBUG, "EAP-TEAP: Build a new PAC");
710
711 if (random_get_bytes(pac_key, EAP_TEAP_PAC_KEY_LEN) < 0 ||
712 os_get_time(&now) < 0)
713 return NULL;
714 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Generated PAC-Key",
715 pac_key, EAP_TEAP_PAC_KEY_LEN);
716
717 pac_len = (2 + EAP_TEAP_PAC_KEY_LEN) + (2 + 4) +
718 (2 + sm->identity_len) + 8;
719 pac_buf = os_malloc(pac_len);
720 if (!pac_buf)
721 return NULL;
722
723 srv_id_info_len = os_strlen(data->srv_id_info);
724
725 pos = pac_buf;
726 *pos++ = PAC_OPAQUE_TYPE_KEY;
727 *pos++ = EAP_TEAP_PAC_KEY_LEN;
728 os_memcpy(pos, pac_key, EAP_TEAP_PAC_KEY_LEN);
729 pos += EAP_TEAP_PAC_KEY_LEN;
730
731 wpa_printf(MSG_DEBUG, "EAP-TEAP: PAC-Key lifetime: %u seconds",
732 data->pac_key_lifetime);
733 *pos++ = PAC_OPAQUE_TYPE_LIFETIME;
734 *pos++ = 4;
735 WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime);
736 pos += 4;
737
738 if (sm->identity) {
739 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TEAP: PAC-Opaque Identity",
740 sm->identity, sm->identity_len);
741 *pos++ = PAC_OPAQUE_TYPE_IDENTITY;
742 *pos++ = sm->identity_len;
743 os_memcpy(pos, sm->identity, sm->identity_len);
744 pos += sm->identity_len;
745 }
746
747 pac_len = pos - pac_buf;
748 while (pac_len % 8) {
749 *pos++ = PAC_OPAQUE_TYPE_PAD;
750 pac_len++;
751 }
752
753 pac_opaque = os_malloc(pac_len + 8);
754 if (!pac_opaque) {
755 os_free(pac_buf);
756 return NULL;
757 }
758 if (aes_wrap(data->pac_opaque_encr, sizeof(data->pac_opaque_encr),
759 pac_len / 8, pac_buf, pac_opaque) < 0) {
760 os_free(pac_buf);
761 os_free(pac_opaque);
762 return NULL;
763 }
764 os_free(pac_buf);
765
766 pac_len += 8;
767 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: PAC-Opaque", pac_opaque, pac_len);
768
769 buf_len = sizeof(*pac_tlv) +
770 sizeof(struct pac_attr_hdr) + EAP_TEAP_PAC_KEY_LEN +
771 sizeof(struct pac_attr_hdr) + pac_len +
772 data->srv_id_len + srv_id_info_len + 100 + sizeof(*result);
773 buf = wpabuf_alloc(buf_len);
774 if (!buf) {
775 os_free(pac_opaque);
776 return NULL;
777 }
778
779 /* Result TLV */
780 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Result TLV (status=SUCCESS)");
781 result = wpabuf_put(buf, sizeof(*result));
782 WPA_PUT_BE16((u8 *) &result->tlv_type,
783 TEAP_TLV_MANDATORY | TEAP_TLV_RESULT);
784 WPA_PUT_BE16((u8 *) &result->length, 2);
785 WPA_PUT_BE16((u8 *) &result->status, TEAP_STATUS_SUCCESS);
786
787 /* PAC TLV */
788 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add PAC TLV");
789 pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
790 pac_tlv->tlv_type = host_to_be16(TEAP_TLV_MANDATORY | TEAP_TLV_PAC);
791
792 /* PAC-Key */
793 eap_teap_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_TEAP_PAC_KEY_LEN);
794
795 /* PAC-Opaque */
796 eap_teap_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
797 os_free(pac_opaque);
798
799 /* PAC-Info */
800 pac_info = wpabuf_put(buf, sizeof(*pac_info));
801 pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
802
803 /* PAC-Lifetime (inside PAC-Info) */
804 eap_teap_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
805 wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime);
806
807 /* A-ID (inside PAC-Info) */
808 eap_teap_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
809
810 /* Note: headers may be misaligned after A-ID */
811
812 if (sm->identity) {
813 eap_teap_put_tlv(buf, PAC_TYPE_I_ID, sm->identity,
814 sm->identity_len);
815 }
816
817 /* A-ID-Info (inside PAC-Info) */
818 eap_teap_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
819 srv_id_info_len);
820
821 /* PAC-Type (inside PAC-Info) */
822 eap_teap_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
823 wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
824
825 /* Update PAC-Info and PAC TLV Length fields */
826 pos = wpabuf_put(buf, 0);
827 pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
828 pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));
829
830 return buf;
831 }
832
833
834 static int eap_teap_encrypt_phase2(struct eap_sm *sm,
835 struct eap_teap_data *data,
836 struct wpabuf *plain, int piggyback)
837 {
838 struct wpabuf *encr;
839
840 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Encrypting Phase 2 TLVs",
841 plain);
842 encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
843 wpabuf_free(plain);
844
845 if (!encr)
846 return -1;
847
848 if (data->ssl.tls_out && piggyback) {
849 wpa_printf(MSG_DEBUG,
850 "EAP-TEAP: Piggyback Phase 2 data (len=%d) with last Phase 1 Message (len=%d used=%d)",
851 (int) wpabuf_len(encr),
852 (int) wpabuf_len(data->ssl.tls_out),
853 (int) data->ssl.tls_out_pos);
854 if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
855 wpa_printf(MSG_WARNING,
856 "EAP-TEAP: Failed to resize output buffer");
857 wpabuf_free(encr);
858 return -1;
859 }
860 wpabuf_put_buf(data->ssl.tls_out, encr);
861 wpabuf_free(encr);
862 } else {
863 wpabuf_free(data->ssl.tls_out);
864 data->ssl.tls_out_pos = 0;
865 data->ssl.tls_out = encr;
866 }
867
868 return 0;
869 }
870
871
872 static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
873 {
874 struct eap_teap_data *data = priv;
875 struct wpabuf *req = NULL;
876 int piggyback = 0;
877
878 if (data->ssl.state == FRAG_ACK) {
879 return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
880 data->teap_version);
881 }
882
883 if (data->ssl.state == WAIT_FRAG_ACK) {
884 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
885 data->teap_version, id);
886 }
887
888 switch (data->state) {
889 case START:
890 return eap_teap_build_start(sm, data, id);
891 case PHASE1B:
892 if (tls_connection_established(sm->cfg->ssl_ctx,
893 data->ssl.conn)) {
894 if (eap_teap_phase1_done(sm, data) < 0)
895 return NULL;
896 if (data->state == PHASE2_START) {
897 int res;
898
899 /*
900 * Try to generate Phase 2 data to piggyback
901 * with the end of Phase 1 to avoid extra
902 * roundtrip.
903 */
904 wpa_printf(MSG_DEBUG,
905 "EAP-TEAP: Try to start Phase 2");
906 res = eap_teap_process_phase2_start(sm, data);
907 if (res == 1) {
908 req = eap_teap_build_crypto_binding(
909 sm, data);
910 piggyback = 1;
911 break;
912 }
913
914 if (res)
915 break;
916 req = eap_teap_build_phase2_req(sm, data, id);
917 piggyback = 1;
918 }
919 }
920 break;
921 case PHASE2_ID:
922 case PHASE2_BASIC_AUTH:
923 case PHASE2_METHOD:
924 req = eap_teap_build_phase2_req(sm, data, id);
925 break;
926 case CRYPTO_BINDING:
927 req = eap_teap_build_crypto_binding(sm, data);
928 if (data->phase2_method) {
929 /*
930 * Include the start of the next EAP method in the
931 * sequence in the same message with Crypto-Binding to
932 * save a round-trip.
933 */
934 struct wpabuf *eap;
935
936 eap = eap_teap_build_phase2_req(sm, data, id);
937 req = wpabuf_concat(req, eap);
938 eap_teap_state(data, PHASE2_METHOD);
939 }
940 break;
941 case REQUEST_PAC:
942 req = eap_teap_build_pac(sm, data);
943 break;
944 case FAILURE_SEND_RESULT:
945 req = eap_teap_tlv_result(TEAP_STATUS_FAILURE, 0);
946 if (data->error_code)
947 req = wpabuf_concat(
948 req, eap_teap_tlv_error(data->error_code));
949 break;
950 case SUCCESS_SEND_RESULT:
951 req = eap_teap_tlv_result(TEAP_STATUS_SUCCESS, 0);
952 data->final_result = 1;
953 break;
954 default:
955 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
956 __func__, data->state);
957 return NULL;
958 }
959
960 if (req && eap_teap_encrypt_phase2(sm, data, req, piggyback) < 0)
961 return NULL;
962
963 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TEAP,
964 data->teap_version, id);
965 }
966
967
968 static Boolean eap_teap_check(struct eap_sm *sm, void *priv,
969 struct wpabuf *respData)
970 {
971 const u8 *pos;
972 size_t len;
973
974 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
975 if (!pos || len < 1) {
976 wpa_printf(MSG_INFO, "EAP-TEAP: Invalid frame");
977 return TRUE;
978 }
979
980 return FALSE;
981 }
982
983
984 static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
985 int vendor, enum eap_type eap_type)
986 {
987 if (data->phase2_priv && data->phase2_method) {
988 data->phase2_method->reset(sm, data->phase2_priv);
989 data->phase2_method = NULL;
990 data->phase2_priv = NULL;
991 }
992 data->phase2_method = eap_server_get_eap_method(vendor, eap_type);
993 if (!data->phase2_method)
994 return -1;
995
996 sm->init_phase2 = 1;
997 data->phase2_priv = data->phase2_method->init(sm);
998 sm->init_phase2 = 0;
999
1000 return data->phase2_priv ? 0 : -1;
1001 }
1002
1003
1004 static int eap_teap_valid_id_type(struct eap_sm *sm, struct eap_teap_data *data,
1005 enum teap_identity_types id_type)
1006 {
1007 if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_USER &&
1008 id_type != TEAP_IDENTITY_TYPE_USER)
1009 return 0;
1010 if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_MACHINE &&
1011 id_type != TEAP_IDENTITY_TYPE_MACHINE)
1012 return 0;
1013 if (sm->cfg->eap_teap_id == EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE &&
1014 id_type != data->cur_id_type)
1015 return 0;
1016 if (sm->cfg->eap_teap_id != EAP_TEAP_ID_ALLOW_ANY &&
1017 id_type != TEAP_IDENTITY_TYPE_USER &&
1018 id_type != TEAP_IDENTITY_TYPE_MACHINE)
1019 return 0;
1020 return 1;
1021 }
1022
1023
1024 static void eap_teap_process_phase2_response(struct eap_sm *sm,
1025 struct eap_teap_data *data,
1026 u8 *in_data, size_t in_len,
1027 enum teap_identity_types id_type)
1028 {
1029 int next_vendor = EAP_VENDOR_IETF;
1030 enum eap_type next_type = EAP_TYPE_NONE;
1031 struct eap_hdr *hdr;
1032 u8 *pos;
1033 size_t left;
1034 struct wpabuf buf;
1035 const struct eap_method *m = data->phase2_method;
1036 void *priv = data->phase2_priv;
1037
1038 if (!priv) {
1039 wpa_printf(MSG_DEBUG,
1040 "EAP-TEAP: %s - Phase 2 not initialized?!",
1041 __func__);
1042 return;
1043 }
1044
1045 hdr = (struct eap_hdr *) in_data;
1046 pos = (u8 *) (hdr + 1);
1047
1048 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
1049 left = in_len - sizeof(*hdr);
1050 wpa_hexdump(MSG_DEBUG,
1051 "EAP-TEAP: Phase 2 type Nak'ed; allowed types",
1052 pos + 1, left - 1);
1053 #ifdef EAP_SERVER_TNC
1054 if (m && m->vendor == EAP_VENDOR_IETF &&
1055 m->method == EAP_TYPE_TNC) {
1056 wpa_printf(MSG_DEBUG,
1057 "EAP-TEAP: Peer Nak'ed required TNC negotiation");
1058 next_vendor = EAP_VENDOR_IETF;
1059 next_type = eap_teap_req_failure(data, 0);
1060 eap_teap_phase2_init(sm, data, next_vendor, next_type);
1061 return;
1062 }
1063 #endif /* EAP_SERVER_TNC */
1064 eap_sm_process_nak(sm, pos + 1, left - 1);
1065 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
1066 sm->user->methods[sm->user_eap_method_index].method !=
1067 EAP_TYPE_NONE) {
1068 next_vendor = sm->user->methods[
1069 sm->user_eap_method_index].vendor;
1070 next_type = sm->user->methods[
1071 sm->user_eap_method_index++].method;
1072 wpa_printf(MSG_DEBUG, "EAP-TEAP: try EAP type %u:%u",
1073 next_vendor, next_type);
1074 } else {
1075 next_vendor = EAP_VENDOR_IETF;
1076 next_type = eap_teap_req_failure(data, 0);
1077 }
1078 eap_teap_phase2_init(sm, data, next_vendor, next_type);
1079 return;
1080 }
1081
1082 wpabuf_set(&buf, in_data, in_len);
1083
1084 if (m->check(sm, priv, &buf)) {
1085 wpa_printf(MSG_DEBUG,
1086 "EAP-TEAP: Phase 2 check() asked to ignore the packet");
1087 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1088 return;
1089 }
1090
1091 m->process(sm, priv, &buf);
1092
1093 if (!m->isDone(sm, priv))
1094 return;
1095
1096 if (!m->isSuccess(sm, priv)) {
1097 wpa_printf(MSG_DEBUG, "EAP-TEAP: Phase 2 method failed");
1098 next_vendor = EAP_VENDOR_IETF;
1099 next_type = eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1100 eap_teap_phase2_init(sm, data, next_vendor, next_type);
1101 return;
1102 }
1103
1104 switch (data->state) {
1105 case PHASE2_ID:
1106 if (!eap_teap_valid_id_type(sm, data, id_type)) {
1107 wpa_printf(MSG_DEBUG,
1108 "EAP-TEAP: Provided Identity-Type %u not allowed",
1109 id_type);
1110 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1111 break;
1112 }
1113 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1114 wpa_hexdump_ascii(MSG_DEBUG,
1115 "EAP-TEAP: Phase 2 Identity not found in the user database",
1116 sm->identity, sm->identity_len);
1117 next_vendor = EAP_VENDOR_IETF;
1118 next_type = eap_teap_req_failure(
1119 data, TEAP_ERROR_INNER_METHOD);
1120 break;
1121 }
1122
1123 eap_teap_state(data, PHASE2_METHOD);
1124 if (data->anon_provisioning) {
1125 /* TODO: Allow any inner EAP method that provides
1126 * mutual authentication and EMSK derivation (i.e.,
1127 * EAP-pwd or EAP-EKE). */
1128 next_vendor = EAP_VENDOR_IETF;
1129 next_type = EAP_TYPE_PWD;
1130 sm->user_eap_method_index = 0;
1131 } else {
1132 next_vendor = sm->user->methods[0].vendor;
1133 next_type = sm->user->methods[0].method;
1134 sm->user_eap_method_index = 1;
1135 }
1136 wpa_printf(MSG_DEBUG, "EAP-TEAP: Try EAP type %u:%u",
1137 next_vendor, next_type);
1138 break;
1139 case PHASE2_METHOD:
1140 case CRYPTO_BINDING:
1141 eap_teap_update_icmk(sm, data);
1142 if (data->state == PHASE2_METHOD &&
1143 (sm->cfg->eap_teap_id !=
1144 EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE ||
1145 data->cur_id_type == TEAP_IDENTITY_TYPE_MACHINE))
1146 data->inner_eap_not_done = 0;
1147 eap_teap_state(data, CRYPTO_BINDING);
1148 data->eap_seq++;
1149 next_vendor = EAP_VENDOR_IETF;
1150 next_type = EAP_TYPE_NONE;
1151 #ifdef EAP_SERVER_TNC
1152 if (sm->cfg->tnc && !data->tnc_started) {
1153 wpa_printf(MSG_DEBUG, "EAP-TEAP: Initialize TNC");
1154 next_vendor = EAP_VENDOR_IETF;
1155 next_type = EAP_TYPE_TNC;
1156 data->tnc_started = 1;
1157 }
1158 #endif /* EAP_SERVER_TNC */
1159 break;
1160 case FAILURE:
1161 break;
1162 default:
1163 wpa_printf(MSG_DEBUG, "EAP-TEAP: %s - unexpected state %d",
1164 __func__, data->state);
1165 break;
1166 }
1167
1168 eap_teap_phase2_init(sm, data, next_vendor, next_type);
1169 }
1170
1171
1172 static void eap_teap_process_phase2_eap(struct eap_sm *sm,
1173 struct eap_teap_data *data,
1174 u8 *in_data, size_t in_len,
1175 enum teap_identity_types id_type)
1176 {
1177 struct eap_hdr *hdr;
1178 size_t len;
1179
1180 hdr = (struct eap_hdr *) in_data;
1181 if (in_len < (int) sizeof(*hdr)) {
1182 wpa_printf(MSG_INFO,
1183 "EAP-TEAP: Too short Phase 2 EAP frame (len=%lu)",
1184 (unsigned long) in_len);
1185 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1186 return;
1187 }
1188 len = be_to_host16(hdr->length);
1189 if (len > in_len) {
1190 wpa_printf(MSG_INFO,
1191 "EAP-TEAP: Length mismatch in Phase 2 EAP frame (len=%lu hdr->length=%lu)",
1192 (unsigned long) in_len, (unsigned long) len);
1193 eap_teap_req_failure(data, TEAP_ERROR_INNER_METHOD);
1194 return;
1195 }
1196 wpa_printf(MSG_DEBUG,
1197 "EAP-TEAP: Received Phase 2: code=%d identifier=%d length=%lu",
1198 hdr->code, hdr->identifier,
1199 (unsigned long) len);
1200 switch (hdr->code) {
1201 case EAP_CODE_RESPONSE:
1202 eap_teap_process_phase2_response(sm, data, (u8 *) hdr, len,
1203 id_type);
1204 break;
1205 default:
1206 wpa_printf(MSG_INFO,
1207 "EAP-TEAP: Unexpected code=%d in Phase 2 EAP header",
1208 hdr->code);
1209 break;
1210 }
1211 }
1212
1213
1214 static void eap_teap_process_basic_auth_resp(struct eap_sm *sm,
1215 struct eap_teap_data *data,
1216 u8 *in_data, size_t in_len,
1217 enum teap_identity_types id_type)
1218 {
1219 u8 *pos, *end, *username, *password, *new_id;
1220 u8 userlen, passlen;
1221
1222 if (!eap_teap_valid_id_type(sm, data, id_type)) {
1223 wpa_printf(MSG_DEBUG,
1224 "EAP-TEAP: Provided Identity-Type %u not allowed",
1225 id_type);
1226 eap_teap_req_failure(data, 0);
1227 return;
1228 }
1229
1230 pos = in_data;
1231 end = pos + in_len;
1232
1233 if (end - pos < 1) {
1234 wpa_printf(MSG_DEBUG,
1235 "EAP-TEAP: No room for Basic-Password-Auth-Resp Userlen field");
1236 eap_teap_req_failure(data, 0);
1237 return;
1238 }
1239 userlen = *pos++;
1240 if (end - pos < userlen) {
1241 wpa_printf(MSG_DEBUG,
1242 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Username field");
1243 eap_teap_req_failure(data, 0);
1244 return;
1245 }
1246 username = pos;
1247 pos += userlen;
1248 wpa_hexdump_ascii(MSG_DEBUG,
1249 "EAP-TEAP: Basic-Password-Auth-Resp Username",
1250 username, userlen);
1251
1252 if (end - pos < 1) {
1253 wpa_printf(MSG_DEBUG,
1254 "EAP-TEAP: No room for Basic-Password-Auth-Resp Passlen field");
1255 eap_teap_req_failure(data, 0);
1256 return;
1257 }
1258 passlen = *pos++;
1259 if (end - pos < passlen) {
1260 wpa_printf(MSG_DEBUG,
1261 "EAP-TEAP: Truncated Basic-Password-Auth-Resp Password field");
1262 eap_teap_req_failure(data, 0);
1263 return;
1264 }
1265 password = pos;
1266 pos += passlen;
1267 wpa_hexdump_ascii_key(MSG_DEBUG,
1268 "EAP-TEAP: Basic-Password-Auth-Resp Password",
1269 password, passlen);
1270
1271 if (end > pos) {
1272 wpa_printf(MSG_DEBUG,
1273 "EAP-TEAP: Unexpected %d extra octet(s) at the end of Basic-Password-Auth-Resp TLV",
1274 (int) (end - pos));
1275 eap_teap_req_failure(data, 0);
1276 return;
1277 }
1278
1279 if (eap_user_get(sm, username, userlen, 1) != 0) {
1280 wpa_printf(MSG_DEBUG,
1281 "EAP-TEAP: Username not found in the user database");
1282 eap_teap_req_failure(data, 0);
1283 return;
1284 }
1285
1286 if (!sm->user || !sm->user->password || sm->user->password_hash) {
1287 wpa_printf(MSG_DEBUG,
1288 "EAP-TEAP: No plaintext user password configured");
1289 eap_teap_req_failure(data, 0);
1290 return;
1291 }
1292
1293 if (sm->user->password_len != passlen ||
1294 os_memcmp_const(sm->user->password, password, passlen) != 0) {
1295 wpa_printf(MSG_DEBUG, "EAP-TEAP: Invalid password");
1296 eap_teap_req_failure(data, 0);
1297 return;
1298 }
1299
1300 wpa_printf(MSG_DEBUG, "EAP-TEAP: Correct password");
1301 new_id = os_memdup(username, userlen);
1302 if (new_id) {
1303 os_free(sm->identity);
1304 sm->identity = new_id;
1305 sm->identity_len = userlen;
1306 }
1307 if (sm->cfg->eap_teap_id != EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE ||
1308 data->cur_id_type == TEAP_IDENTITY_TYPE_MACHINE)
1309 data->basic_auth_not_done = 0;
1310 eap_teap_state(data, CRYPTO_BINDING);
1311 eap_teap_update_icmk(sm, data);
1312 }
1313
1314
1315 static int eap_teap_parse_tlvs(struct wpabuf *data,
1316 struct eap_teap_tlv_parse *tlv)
1317 {
1318 u16 tlv_type;
1319 int mandatory, res;
1320 size_t len;
1321 u8 *pos, *end;
1322
1323 os_memset(tlv, 0, sizeof(*tlv));
1324
1325 pos = wpabuf_mhead(data);
1326 end = pos + wpabuf_len(data);
1327 while (end - pos > 4) {
1328 mandatory = pos[0] & 0x80;
1329 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
1330 pos += 2;
1331 len = WPA_GET_BE16(pos);
1332 pos += 2;
1333 if (len > (size_t) (end - pos)) {
1334 wpa_printf(MSG_INFO, "EAP-TEAP: TLV overflow");
1335 return -1;
1336 }
1337 wpa_printf(MSG_DEBUG,
1338 "EAP-TEAP: Received Phase 2: TLV type %u (%s) length %u%s",
1339 tlv_type, eap_teap_tlv_type_str(tlv_type),
1340 (unsigned int) len,
1341 mandatory ? " (mandatory)" : "");
1342
1343 res = eap_teap_parse_tlv(tlv, tlv_type, pos, len);
1344 if (res == -2)
1345 break;
1346 if (res < 0) {
1347 if (mandatory) {
1348 wpa_printf(MSG_DEBUG,
1349 "EAP-TEAP: NAK unknown mandatory TLV type %u",
1350 tlv_type);
1351 /* TODO: generate NAK TLV */
1352 break;
1353 }
1354
1355 wpa_printf(MSG_DEBUG,
1356 "EAP-TEAP: Ignore unknown optional TLV type %u",
1357 tlv_type);
1358 }
1359
1360 pos += len;
1361 }
1362
1363 return 0;
1364 }
1365
1366
1367 static int eap_teap_validate_crypto_binding(
1368 struct eap_teap_data *data, const struct teap_tlv_crypto_binding *cb,
1369 size_t bind_len)
1370 {
1371 u8 flags, subtype;
1372
1373 subtype = cb->subtype & 0x0f;
1374 flags = cb->subtype >> 4;
1375
1376 wpa_printf(MSG_DEBUG,
1377 "EAP-TEAP: Reply Crypto-Binding TLV: Version %u Received Version %u Flags %u Sub-Type %u",
1378 cb->version, cb->received_version, flags, subtype);
1379 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Nonce",
1380 cb->nonce, sizeof(cb->nonce));
1381 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EMSK Compound MAC",
1382 cb->emsk_compound_mac, sizeof(cb->emsk_compound_mac));
1383 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
1384 cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
1385
1386 if (cb->version != EAP_TEAP_VERSION ||
1387 cb->received_version != data->peer_version) {
1388 wpa_printf(MSG_DEBUG,
1389 "EAP-TEAP: Unexpected version in Crypto-Binding: Version %u Received Version %u",
1390 cb->version, cb->received_version);
1391 return -1;
1392 }
1393
1394 if (flags < 1 || flags > 3) {
1395 wpa_printf(MSG_DEBUG,
1396 "EAP-TEAP: Unexpected Flags in Crypto-Binding: %u",
1397 flags);
1398 return -1;
1399 }
1400
1401 if (subtype != TEAP_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
1402 wpa_printf(MSG_DEBUG,
1403 "EAP-TEAP: Unexpected Sub-Type in Crypto-Binding: %u",
1404 subtype);
1405 return -1;
1406 }
1407
1408 if (os_memcmp_const(data->crypto_binding_nonce, cb->nonce,
1409 EAP_TEAP_NONCE_LEN - 1) != 0 ||
1410 (data->crypto_binding_nonce[EAP_TEAP_NONCE_LEN - 1] | 1) !=
1411 cb->nonce[EAP_TEAP_NONCE_LEN - 1]) {
1412 wpa_printf(MSG_DEBUG,
1413 "EAP-TEAP: Invalid Nonce in Crypto-Binding");
1414 return -1;
1415 }
1416
1417 if (flags == TEAP_CRYPTO_BINDING_MSK_CMAC ||
1418 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) {
1419 u8 msk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
1420
1421 if (eap_teap_compound_mac(data->tls_cs, cb,
1422 data->server_outer_tlvs,
1423 data->peer_outer_tlvs, data->cmk_msk,
1424 msk_compound_mac) < 0)
1425 return -1;
1426 if (os_memcmp_const(msk_compound_mac, cb->msk_compound_mac,
1427 EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1428 wpa_hexdump(MSG_DEBUG,
1429 "EAP-TEAP: Calculated MSK Compound MAC",
1430 msk_compound_mac,
1431 EAP_TEAP_COMPOUND_MAC_LEN);
1432 wpa_printf(MSG_INFO,
1433 "EAP-TEAP: MSK Compound MAC did not match");
1434 return -1;
1435 }
1436 }
1437
1438 if ((flags == TEAP_CRYPTO_BINDING_EMSK_CMAC ||
1439 flags == TEAP_CRYPTO_BINDING_EMSK_AND_MSK_CMAC) &&
1440 data->cmk_emsk_available) {
1441 u8 emsk_compound_mac[EAP_TEAP_COMPOUND_MAC_LEN];
1442
1443 if (eap_teap_compound_mac(data->tls_cs, cb,
1444 data->server_outer_tlvs,
1445 data->peer_outer_tlvs, data->cmk_emsk,
1446 emsk_compound_mac) < 0)
1447 return -1;
1448 if (os_memcmp_const(emsk_compound_mac, cb->emsk_compound_mac,
1449 EAP_TEAP_COMPOUND_MAC_LEN) != 0) {
1450 wpa_hexdump(MSG_DEBUG,
1451 "EAP-TEAP: Calculated EMSK Compound MAC",
1452 emsk_compound_mac,
1453 EAP_TEAP_COMPOUND_MAC_LEN);
1454 wpa_printf(MSG_INFO,
1455 "EAP-TEAP: EMSK Compound MAC did not match");
1456 return -1;
1457 }
1458 }
1459
1460 if (flags == TEAP_CRYPTO_BINDING_EMSK_CMAC &&
1461 !data->cmk_emsk_available) {
1462 wpa_printf(MSG_INFO,
1463 "EAP-TEAP: Peer included only EMSK Compound MAC, but no locally generated inner EAP EMSK to validate this");
1464 return -1;
1465 }
1466
1467 return 0;
1468 }
1469
1470
1471 static int eap_teap_pac_type(u8 *pac, size_t len, u16 type)
1472 {
1473 struct teap_attr_pac_type *tlv;
1474
1475 if (!pac || len != sizeof(*tlv))
1476 return 0;
1477
1478 tlv = (struct teap_attr_pac_type *) pac;
1479
1480 return be_to_host16(tlv->type) == PAC_TYPE_PAC_TYPE &&
1481 be_to_host16(tlv->length) == 2 &&
1482 be_to_host16(tlv->pac_type) == type;
1483 }
1484
1485
1486 static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
1487 struct eap_teap_data *data,
1488 struct wpabuf *in_data)
1489 {
1490 struct eap_teap_tlv_parse tlv;
1491 int check_crypto_binding = data->state == CRYPTO_BINDING;
1492
1493 if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
1494 wpa_printf(MSG_DEBUG,
1495 "EAP-TEAP: Failed to parse received Phase 2 TLVs");
1496 return;
1497 }
1498
1499 if (tlv.result == TEAP_STATUS_FAILURE) {
1500 wpa_printf(MSG_DEBUG, "EAP-TEAP: Result TLV indicated failure");
1501 eap_teap_state(data, FAILURE);
1502 return;
1503 }
1504
1505 if (tlv.nak) {
1506 wpa_printf(MSG_DEBUG,
1507 "EAP-TEAP: Peer NAK'ed Vendor-Id %u NAK-Type %u",
1508 WPA_GET_BE32(tlv.nak), WPA_GET_BE16(tlv.nak + 4));
1509 eap_teap_state(data, FAILURE_SEND_RESULT);
1510 return;
1511 }
1512
1513 if (data->state == REQUEST_PAC) {
1514 u16 type, len, res;
1515
1516 if (!tlv.pac || tlv.pac_len < 6) {
1517 wpa_printf(MSG_DEBUG,
1518 "EAP-TEAP: No PAC Acknowledgement received");
1519 eap_teap_state(data, FAILURE);
1520 return;
1521 }
1522
1523 type = WPA_GET_BE16(tlv.pac);
1524 len = WPA_GET_BE16(tlv.pac + 2);
1525 res = WPA_GET_BE16(tlv.pac + 4);
1526
1527 if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||
1528 res != TEAP_STATUS_SUCCESS) {
1529 wpa_printf(MSG_DEBUG,
1530 "EAP-TEAP: PAC TLV did not contain acknowledgement");
1531 eap_teap_state(data, FAILURE);
1532 return;
1533 }
1534
1535 wpa_printf(MSG_DEBUG,
1536 "EAP-TEAP: PAC-Acknowledgement received - PAC provisioning succeeded");
1537 eap_teap_state(data, SUCCESS);
1538 return;
1539 }
1540
1541 if (check_crypto_binding) {
1542 if (!tlv.crypto_binding) {
1543 wpa_printf(MSG_DEBUG,
1544 "EAP-TEAP: No Crypto-Binding TLV received");
1545 eap_teap_state(data, FAILURE);
1546 return;
1547 }
1548
1549 if (data->final_result &&
1550 tlv.result != TEAP_STATUS_SUCCESS) {
1551 wpa_printf(MSG_DEBUG,
1552 "EAP-TEAP: Crypto-Binding TLV without Success Result");
1553 eap_teap_state(data, FAILURE);
1554 return;
1555 }
1556
1557 if (sm->cfg->eap_teap_auth != 1 &&
1558 !data->skipped_inner_auth &&
1559 tlv.iresult != TEAP_STATUS_SUCCESS) {
1560 wpa_printf(MSG_DEBUG,
1561 "EAP-TEAP: Crypto-Binding TLV without intermediate Success Result");
1562 eap_teap_state(data, FAILURE);
1563 return;
1564 }
1565
1566 if (eap_teap_validate_crypto_binding(data, tlv.crypto_binding,
1567 tlv.crypto_binding_len)) {
1568 eap_teap_state(data, FAILURE);
1569 return;
1570 }
1571
1572 wpa_printf(MSG_DEBUG,
1573 "EAP-TEAP: Valid Crypto-Binding TLV received");
1574 if (data->final_result) {
1575 wpa_printf(MSG_DEBUG,
1576 "EAP-TEAP: Authentication completed successfully");
1577 }
1578
1579 if (data->anon_provisioning &&
1580 sm->cfg->eap_fast_prov != ANON_PROV &&
1581 sm->cfg->eap_fast_prov != BOTH_PROV) {
1582 wpa_printf(MSG_DEBUG,
1583 "EAP-TEAP: Client is trying to use unauthenticated provisioning which is disabled");
1584 eap_teap_state(data, FAILURE);
1585 return;
1586 }
1587
1588 if (sm->cfg->eap_fast_prov != AUTH_PROV &&
1589 sm->cfg->eap_fast_prov != BOTH_PROV &&
1590 tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV &&
1591 eap_teap_pac_type(tlv.pac, tlv.pac_len,
1592 PAC_TYPE_TUNNEL_PAC)) {
1593 wpa_printf(MSG_DEBUG,
1594 "EAP-TEAP: Client is trying to use authenticated provisioning which is disabled");
1595 eap_teap_state(data, FAILURE);
1596 return;
1597 }
1598
1599 if (data->anon_provisioning ||
1600 (tlv.request_action == TEAP_REQUEST_ACTION_PROCESS_TLV &&
1601 eap_teap_pac_type(tlv.pac, tlv.pac_len,
1602 PAC_TYPE_TUNNEL_PAC))) {
1603 wpa_printf(MSG_DEBUG,
1604 "EAP-TEAP: Requested a new Tunnel PAC");
1605 eap_teap_state(data, REQUEST_PAC);
1606 } else if (data->send_new_pac) {
1607 wpa_printf(MSG_DEBUG,
1608 "EAP-TEAP: Server triggered re-keying of Tunnel PAC");
1609 eap_teap_state(data, REQUEST_PAC);
1610 } else if (data->final_result) {
1611 eap_teap_state(data, SUCCESS);
1612 } else if (sm->cfg->eap_teap_separate_result) {
1613 eap_teap_state(data, SUCCESS_SEND_RESULT);
1614 }
1615 }
1616
1617 if (tlv.basic_auth_resp) {
1618 if (sm->cfg->eap_teap_auth != 1) {
1619 wpa_printf(MSG_DEBUG,
1620 "EAP-TEAP: Unexpected Basic-Password-Auth-Resp when trying to use inner EAP");
1621 eap_teap_state(data, FAILURE);
1622 return;
1623 }
1624 eap_teap_process_basic_auth_resp(sm, data, tlv.basic_auth_resp,
1625 tlv.basic_auth_resp_len,
1626 tlv.identity_type);
1627 }
1628
1629 if (tlv.eap_payload_tlv) {
1630 if (sm->cfg->eap_teap_auth == 1) {
1631 wpa_printf(MSG_DEBUG,
1632 "EAP-TEAP: Unexpected EAP Payload TLV when trying to use Basic-Password-Auth");
1633 eap_teap_state(data, FAILURE);
1634 return;
1635 }
1636 eap_teap_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
1637 tlv.eap_payload_tlv_len,
1638 tlv.identity_type);
1639 }
1640
1641 if (data->state == SUCCESS_SEND_RESULT &&
1642 tlv.result == TEAP_STATUS_SUCCESS) {
1643 wpa_printf(MSG_DEBUG,
1644 "EAP-TEAP: Peer agreed with final success - authentication completed");
1645 eap_teap_state(data, SUCCESS);
1646 } else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
1647 sm->cfg->eap_teap_auth == 1 && data->basic_auth_not_done) {
1648 wpa_printf(MSG_DEBUG,
1649 "EAP-TEAP: Continue with basic password authentication for second credential");
1650 eap_teap_state(data, PHASE2_BASIC_AUTH);
1651 } else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
1652 sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done) {
1653 wpa_printf(MSG_DEBUG,
1654 "EAP-TEAP: Continue with inner EAP authentication for second credential");
1655 eap_teap_state(data, PHASE2_ID);
1656 if (eap_teap_phase2_init(sm, data, EAP_VENDOR_IETF,
1657 EAP_TYPE_IDENTITY) < 0)
1658 eap_teap_state(data, FAILURE);
1659 }
1660 }
1661
1662
1663 static void eap_teap_process_phase2(struct eap_sm *sm,
1664 struct eap_teap_data *data,
1665 struct wpabuf *in_buf)
1666 {
1667 struct wpabuf *in_decrypted;
1668
1669 wpa_printf(MSG_DEBUG,
1670 "EAP-TEAP: Received %lu bytes encrypted data for Phase 2",
1671 (unsigned long) wpabuf_len(in_buf));
1672
1673 if (data->pending_phase2_resp) {
1674 wpa_printf(MSG_DEBUG,
1675 "EAP-TEAP: Pending Phase 2 response - skip decryption and use old data");
1676 eap_teap_process_phase2_tlvs(sm, data,
1677 data->pending_phase2_resp);
1678 wpabuf_free(data->pending_phase2_resp);
1679 data->pending_phase2_resp = NULL;
1680 return;
1681 }
1682
1683 in_decrypted = tls_connection_decrypt(sm->cfg->ssl_ctx, data->ssl.conn,
1684 in_buf);
1685 if (!in_decrypted) {
1686 wpa_printf(MSG_INFO,
1687 "EAP-TEAP: Failed to decrypt Phase 2 data");
1688 eap_teap_state(data, FAILURE);
1689 return;
1690 }
1691
1692 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TEAP: Decrypted Phase 2 TLVs",
1693 in_decrypted);
1694
1695 eap_teap_process_phase2_tlvs(sm, data, in_decrypted);
1696
1697 if (sm->method_pending == METHOD_PENDING_WAIT) {
1698 wpa_printf(MSG_DEBUG,
1699 "EAP-TEAP: Phase 2 method is in pending wait state - save decrypted response");
1700 wpabuf_free(data->pending_phase2_resp);
1701 data->pending_phase2_resp = in_decrypted;
1702 return;
1703 }
1704
1705 wpabuf_free(in_decrypted);
1706 }
1707
1708
1709 static int eap_teap_process_version(struct eap_sm *sm, void *priv,
1710 int peer_version)
1711 {
1712 struct eap_teap_data *data = priv;
1713
1714 if (peer_version < 1) {
1715 /* Version 1 was the first defined version, so reject 0 */
1716 wpa_printf(MSG_INFO,
1717 "EAP-TEAP: Peer used unknown TEAP version %u",
1718 peer_version);
1719 return -1;
1720 }
1721
1722 if (peer_version < data->teap_version) {
1723 wpa_printf(MSG_DEBUG, "EAP-TEAP: peer ver=%u, own ver=%u; "
1724 "use version %u",
1725 peer_version, data->teap_version, peer_version);
1726 data->teap_version = peer_version;
1727 }
1728
1729 data->peer_version = peer_version;
1730
1731 return 0;
1732 }
1733
1734
1735 static int eap_teap_process_phase1(struct eap_sm *sm,
1736 struct eap_teap_data *data)
1737 {
1738 if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
1739 wpa_printf(MSG_INFO, "EAP-TEAP: TLS processing failed");
1740 eap_teap_state(data, FAILURE);
1741 return -1;
1742 }
1743
1744 if (!tls_connection_established(sm->cfg->ssl_ctx, data->ssl.conn) ||
1745 wpabuf_len(data->ssl.tls_out) > 0)
1746 return 1;
1747
1748 /*
1749 * Phase 1 was completed with the received message (e.g., when using
1750 * abbreviated handshake), so Phase 2 can be started immediately
1751 * without having to send through an empty message to the peer.
1752 */
1753
1754 return eap_teap_phase1_done(sm, data);
1755 }
1756
1757
1758 static int eap_teap_process_phase2_start(struct eap_sm *sm,
1759 struct eap_teap_data *data)
1760 {
1761 int next_vendor;
1762 enum eap_type next_type;
1763
1764 if (data->identity) {
1765 /* Used PAC and identity is from PAC-Opaque */
1766 os_free(sm->identity);
1767 sm->identity = data->identity;
1768 data->identity = NULL;
1769 sm->identity_len = data->identity_len;
1770 data->identity_len = 0;
1771 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
1772 wpa_hexdump_ascii(MSG_DEBUG,
1773 "EAP-TEAP: Phase 2 Identity not found in the user database",
1774 sm->identity, sm->identity_len);
1775 next_vendor = EAP_VENDOR_IETF;
1776 next_type = EAP_TYPE_NONE;
1777 eap_teap_state(data, PHASE2_METHOD);
1778 } else if (sm->cfg->eap_teap_pac_no_inner) {
1779 wpa_printf(MSG_DEBUG,
1780 "EAP-TEAP: Used PAC and identity already known - skip inner auth");
1781 data->skipped_inner_auth = 1;
1782 /* FIX: Need to derive CMK here. However, how is that
1783 * supposed to be done? RFC 7170 does not tell that for
1784 * the no-inner-auth case. */
1785 eap_teap_derive_cmk_basic_pw_auth(data->tls_cs,
1786 data->simck_msk,
1787 data->cmk_msk);
1788 eap_teap_state(data, CRYPTO_BINDING);
1789 return 1;
1790 } else if (sm->cfg->eap_teap_auth == 1) {
1791 eap_teap_state(data, PHASE2_BASIC_AUTH);
1792 return 1;
1793 } else {
1794 wpa_printf(MSG_DEBUG,
1795 "EAP-TEAP: Identity already known - skip Phase 2 Identity Request");
1796 next_vendor = sm->user->methods[0].vendor;
1797 next_type = sm->user->methods[0].method;
1798 sm->user_eap_method_index = 1;
1799 eap_teap_state(data, PHASE2_METHOD);
1800 }
1801
1802 } else if (sm->cfg->eap_teap_auth == 1) {
1803 eap_teap_state(data, PHASE2_BASIC_AUTH);
1804 return 0;
1805 } else {
1806 eap_teap_state(data, PHASE2_ID);
1807 next_vendor = EAP_VENDOR_IETF;
1808 next_type = EAP_TYPE_IDENTITY;
1809 }
1810
1811 return eap_teap_phase2_init(sm, data, next_vendor, next_type);
1812 }
1813
1814
1815 static void eap_teap_process_msg(struct eap_sm *sm, void *priv,
1816 const struct wpabuf *respData)
1817 {
1818 struct eap_teap_data *data = priv;
1819
1820 switch (data->state) {
1821 case PHASE1:
1822 case PHASE1B:
1823 if (eap_teap_process_phase1(sm, data))
1824 break;
1825
1826 /* fall through */
1827 case PHASE2_START:
1828 eap_teap_process_phase2_start(sm, data);
1829 break;
1830 case PHASE2_ID:
1831 case PHASE2_BASIC_AUTH:
1832 case PHASE2_METHOD:
1833 case CRYPTO_BINDING:
1834 case REQUEST_PAC:
1835 case SUCCESS_SEND_RESULT:
1836 eap_teap_process_phase2(sm, data, data->ssl.tls_in);
1837 break;
1838 case FAILURE_SEND_RESULT:
1839 /* Protected failure result indication completed. Ignore the
1840 * received message (which is supposed to include Result TLV
1841 * indicating failure) and terminate exchange with cleartext
1842 * EAP-Failure. */
1843 eap_teap_state(data, FAILURE);
1844 break;
1845 default:
1846 wpa_printf(MSG_DEBUG, "EAP-TEAP: Unexpected state %d in %s",
1847 data->state, __func__);
1848 break;
1849 }
1850 }
1851
1852
1853 static void eap_teap_process(struct eap_sm *sm, void *priv,
1854 struct wpabuf *respData)
1855 {
1856 struct eap_teap_data *data = priv;
1857 const u8 *pos;
1858 size_t len;
1859 struct wpabuf *resp = respData;
1860 u8 flags;
1861
1862 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, respData, &len);
1863 if (!pos || len < 1)
1864 return;
1865
1866 flags = *pos++;
1867 len--;
1868
1869 if (flags & EAP_TEAP_FLAGS_OUTER_TLV_LEN) {
1870 /* Extract Outer TLVs from the message before common TLS
1871 * processing */
1872 u32 message_len = 0, outer_tlv_len;
1873 const u8 *hdr;
1874
1875 if (data->state != PHASE1) {
1876 wpa_printf(MSG_INFO,
1877 "EAP-TEAP: Unexpected Outer TLVs in a message that is not the first message from the peer");
1878 return;
1879 }
1880
1881 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
1882 if (len < 4) {
1883 wpa_printf(MSG_INFO,
1884 "EAP-TEAP: Too short message to include Message Length field");
1885 return;
1886 }
1887
1888 message_len = WPA_GET_BE32(pos);
1889 pos += 4;
1890 len -= 4;
1891 if (message_len < 4) {
1892 wpa_printf(MSG_INFO,
1893 "EAP-TEAP: Message Length field has too msall value to include Outer TLV Length field");
1894 return;
1895 }
1896 }
1897
1898 if (len < 4) {
1899 wpa_printf(MSG_INFO,
1900 "EAP-TEAP: Too short message to include Outer TLVs Length field");
1901 return;
1902 }
1903
1904 outer_tlv_len = WPA_GET_BE32(pos);
1905 pos += 4;
1906 len -= 4;
1907
1908 wpa_printf(MSG_DEBUG,
1909 "EAP-TEAP: Message Length %u Outer TLV Length %u",
1910 message_len, outer_tlv_len);
1911 if (len < outer_tlv_len) {
1912 wpa_printf(MSG_INFO,
1913 "EAP-TEAP: Too short message to include Outer TLVs field");
1914 return;
1915 }
1916
1917 if (message_len &&
1918 (message_len < outer_tlv_len ||
1919 message_len < 4 + outer_tlv_len)) {
1920 wpa_printf(MSG_INFO,
1921 "EAP-TEAP: Message Length field has too small value to include Outer TLVs");
1922 return;
1923 }
1924
1925 if (wpabuf_len(respData) < 4 + outer_tlv_len ||
1926 len < outer_tlv_len)
1927 return;
1928 resp = wpabuf_alloc(wpabuf_len(respData) - 4 - outer_tlv_len);
1929 if (!resp)
1930 return;
1931 hdr = wpabuf_head(respData);
1932 wpabuf_put_u8(resp, *hdr++); /* Code */
1933 wpabuf_put_u8(resp, *hdr++); /* Identifier */
1934 wpabuf_put_be16(resp, WPA_GET_BE16(hdr) - 4 - outer_tlv_len);
1935 hdr += 2;
1936 wpabuf_put_u8(resp, *hdr++); /* Type */
1937 /* Flags | Ver */
1938 wpabuf_put_u8(resp, flags & ~EAP_TEAP_FLAGS_OUTER_TLV_LEN);
1939
1940 if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)
1941 wpabuf_put_be32(resp, message_len - 4 - outer_tlv_len);
1942
1943 wpabuf_put_data(resp, pos, len - outer_tlv_len);
1944 pos += len - outer_tlv_len;
1945 wpabuf_free(data->peer_outer_tlvs);
1946 data->peer_outer_tlvs = wpabuf_alloc_copy(pos, outer_tlv_len);
1947 if (!data->peer_outer_tlvs)
1948 return;
1949 wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: Outer TLVs",
1950 data->peer_outer_tlvs);
1951
1952 wpa_hexdump_buf(MSG_DEBUG,
1953 "EAP-TEAP: TLS Data message after Outer TLV removal",
1954 resp);
1955 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TEAP, resp,
1956 &len);
1957 if (!pos || len < 1) {
1958 wpa_printf(MSG_INFO,
1959 "EAP-TEAP: Invalid frame after Outer TLV removal");
1960 return;
1961 }
1962 }
1963
1964 if (data->state == PHASE1)
1965 eap_teap_state(data, PHASE1B);
1966
1967 if (eap_server_tls_process(sm, &data->ssl, resp, data,
1968 EAP_TYPE_TEAP, eap_teap_process_version,
1969 eap_teap_process_msg) < 0)
1970 eap_teap_state(data, FAILURE);
1971
1972 if (resp != respData)
1973 wpabuf_free(resp);
1974 }
1975
1976
1977 static Boolean eap_teap_isDone(struct eap_sm *sm, void *priv)
1978 {
1979 struct eap_teap_data *data = priv;
1980
1981 return data->state == SUCCESS || data->state == FAILURE;
1982 }
1983
1984
1985 static u8 * eap_teap_getKey(struct eap_sm *sm, void *priv, size_t *len)
1986 {
1987 struct eap_teap_data *data = priv;
1988 u8 *eapKeyData;
1989
1990 if (data->state != SUCCESS)
1991 return NULL;
1992
1993 eapKeyData = os_malloc(EAP_TEAP_KEY_LEN);
1994 if (!eapKeyData)
1995 return NULL;
1996
1997 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
1998 * is used in this derivation */
1999 if (eap_teap_derive_eap_msk(data->tls_cs, data->simck_msk,
2000 eapKeyData) < 0) {
2001 os_free(eapKeyData);
2002 return NULL;
2003 }
2004 *len = EAP_TEAP_KEY_LEN;
2005
2006 return eapKeyData;
2007 }
2008
2009
2010 static u8 * eap_teap_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
2011 {
2012 struct eap_teap_data *data = priv;
2013 u8 *eapKeyData;
2014
2015 if (data->state != SUCCESS)
2016 return NULL;
2017
2018 eapKeyData = os_malloc(EAP_EMSK_LEN);
2019 if (!eapKeyData)
2020 return NULL;
2021
2022 /* FIX: RFC 7170 does not describe whether MSK or EMSK based S-IMCK[j]
2023 * is used in this derivation */
2024 if (eap_teap_derive_eap_emsk(data->tls_cs, data->simck_msk,
2025 eapKeyData) < 0) {
2026 os_free(eapKeyData);
2027 return NULL;
2028 }
2029 *len = EAP_EMSK_LEN;
2030
2031 return eapKeyData;
2032 }
2033
2034
2035 static Boolean eap_teap_isSuccess(struct eap_sm *sm, void *priv)
2036 {
2037 struct eap_teap_data *data = priv;
2038
2039 return data->state == SUCCESS;
2040 }
2041
2042
2043 static u8 * eap_teap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
2044 {
2045 struct eap_teap_data *data = priv;
2046 const size_t max_id_len = 100;
2047 int res;
2048 u8 *id;
2049
2050 if (data->state != SUCCESS)
2051 return NULL;
2052
2053 id = os_malloc(max_id_len);
2054 if (!id)
2055 return NULL;
2056
2057 id[0] = EAP_TYPE_TEAP;
2058 res = tls_get_tls_unique(data->ssl.conn, id + 1, max_id_len - 1);
2059 if (res < 0) {
2060 os_free(id);
2061 wpa_printf(MSG_ERROR, "EAP-TEAP: Failed to derive Session-Id");
2062 return NULL;
2063 }
2064
2065 *len = 1 + res;
2066 wpa_hexdump(MSG_DEBUG, "EAP-TEAP: Derived Session-Id", id, *len);
2067 return id;
2068 }
2069
2070
2071 int eap_server_teap_register(void)
2072 {
2073 struct eap_method *eap;
2074
2075 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
2076 EAP_VENDOR_IETF, EAP_TYPE_TEAP, "TEAP");
2077 if (!eap)
2078 return -1;
2079
2080 eap->init = eap_teap_init;
2081 eap->reset = eap_teap_reset;
2082 eap->buildReq = eap_teap_buildReq;
2083 eap->check = eap_teap_check;
2084 eap->process = eap_teap_process;
2085 eap->isDone = eap_teap_isDone;
2086 eap->getKey = eap_teap_getKey;
2087 eap->get_emsk = eap_teap_get_emsk;
2088 eap->isSuccess = eap_teap_isSuccess;
2089 eap->getSessionId = eap_teap_get_session_id;
2090
2091 return eap_server_method_register(eap);
2092 }