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