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