]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/eap_server/eap_server_teap.c
MFV r361937:
[FreeBSD/FreeBSD.git] / contrib / wpa / 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, 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:
104                 return "SUCCESS";
105         case FAILURE:
106                 return "FAILURE";
107         default:
108                 return "Unknown?!";
109         }
110 }
111
112
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }