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