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