LCOV - code coverage report
Current view: top level - src/eap_peer - eap_ttls.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 639 799 80.0 %
Date: 2015-09-27 Functions: 42 42 100.0 %

          Line data    Source code
       1             : /*
       2             :  * EAP peer method: EAP-TTLS (RFC 5281)
       3             :  * Copyright (c) 2004-2011, 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/ms_funcs.h"
      13             : #include "crypto/sha1.h"
      14             : #include "crypto/tls.h"
      15             : #include "eap_common/chap.h"
      16             : #include "eap_common/eap_ttls.h"
      17             : #include "mschapv2.h"
      18             : #include "eap_i.h"
      19             : #include "eap_tls_common.h"
      20             : #include "eap_config.h"
      21             : 
      22             : 
      23             : #define EAP_TTLS_VERSION 0
      24             : 
      25             : 
      26             : static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
      27             : 
      28             : 
      29             : struct eap_ttls_data {
      30             :         struct eap_ssl_data ssl;
      31             : 
      32             :         int ttls_version;
      33             : 
      34             :         const struct eap_method *phase2_method;
      35             :         void *phase2_priv;
      36             :         int phase2_success;
      37             :         int phase2_start;
      38             : 
      39             :         enum phase2_types {
      40             :                 EAP_TTLS_PHASE2_EAP,
      41             :                 EAP_TTLS_PHASE2_MSCHAPV2,
      42             :                 EAP_TTLS_PHASE2_MSCHAP,
      43             :                 EAP_TTLS_PHASE2_PAP,
      44             :                 EAP_TTLS_PHASE2_CHAP
      45             :         } phase2_type;
      46             :         struct eap_method_type phase2_eap_type;
      47             :         struct eap_method_type *phase2_eap_types;
      48             :         size_t num_phase2_eap_types;
      49             : 
      50             :         u8 auth_response[MSCHAPV2_AUTH_RESPONSE_LEN];
      51             :         int auth_response_valid;
      52             :         u8 master_key[MSCHAPV2_MASTER_KEY_LEN]; /* MSCHAPv2 master key */
      53             :         u8 ident;
      54             :         int resuming; /* starting a resumed session */
      55             :         int reauth; /* reauthentication */
      56             :         u8 *key_data;
      57             :         u8 *session_id;
      58             :         size_t id_len;
      59             : 
      60             :         struct wpabuf *pending_phase2_req;
      61             : 
      62             : #ifdef EAP_TNC
      63             :         int ready_for_tnc;
      64             :         int tnc_started;
      65             : #endif /* EAP_TNC */
      66             : };
      67             : 
      68             : 
      69         189 : static void * eap_ttls_init(struct eap_sm *sm)
      70             : {
      71             :         struct eap_ttls_data *data;
      72         189 :         struct eap_peer_config *config = eap_get_config(sm);
      73             :         char *selected;
      74             : 
      75         189 :         data = os_zalloc(sizeof(*data));
      76         189 :         if (data == NULL)
      77           0 :                 return NULL;
      78         189 :         data->ttls_version = EAP_TTLS_VERSION;
      79         189 :         selected = "EAP";
      80         189 :         data->phase2_type = EAP_TTLS_PHASE2_EAP;
      81             : 
      82         189 :         if (config && config->phase2) {
      83         184 :                 if (os_strstr(config->phase2, "autheap=")) {
      84          25 :                         selected = "EAP";
      85          25 :                         data->phase2_type = EAP_TTLS_PHASE2_EAP;
      86         159 :                 } else if (os_strstr(config->phase2, "auth=MSCHAPV2")) {
      87          97 :                         selected = "MSCHAPV2";
      88          97 :                         data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
      89          62 :                 } else if (os_strstr(config->phase2, "auth=MSCHAP")) {
      90          15 :                         selected = "MSCHAP";
      91          15 :                         data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
      92          47 :                 } else if (os_strstr(config->phase2, "auth=PAP")) {
      93          40 :                         selected = "PAP";
      94          40 :                         data->phase2_type = EAP_TTLS_PHASE2_PAP;
      95           7 :                 } else if (os_strstr(config->phase2, "auth=CHAP")) {
      96           7 :                         selected = "CHAP";
      97           7 :                         data->phase2_type = EAP_TTLS_PHASE2_CHAP;
      98             :                 }
      99             :         }
     100         189 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
     101             : 
     102         189 :         if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
     103          30 :                 if (eap_peer_select_phase2_methods(config, "autheap=",
     104             :                                                    &data->phase2_eap_types,
     105             :                                                    &data->num_phase2_eap_types)
     106             :                     < 0) {
     107           0 :                         eap_ttls_deinit(sm, data);
     108           0 :                         return NULL;
     109             :                 }
     110             : 
     111          30 :                 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
     112          30 :                 data->phase2_eap_type.method = EAP_TYPE_NONE;
     113             :         }
     114             : 
     115         189 :         if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TTLS)) {
     116           4 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
     117           4 :                 eap_ttls_deinit(sm, data);
     118           4 :                 return NULL;
     119             :         }
     120             : 
     121         185 :         return data;
     122             : }
     123             : 
     124             : 
     125         189 : static void eap_ttls_phase2_eap_deinit(struct eap_sm *sm,
     126             :                                        struct eap_ttls_data *data)
     127             : {
     128         189 :         if (data->phase2_priv && data->phase2_method) {
     129          21 :                 data->phase2_method->deinit(sm, data->phase2_priv);
     130          21 :                 data->phase2_method = NULL;
     131          21 :                 data->phase2_priv = NULL;
     132             :         }
     133         189 : }
     134             : 
     135             : 
     136         388 : static void eap_ttls_free_key(struct eap_ttls_data *data)
     137             : {
     138         388 :         if (data->key_data) {
     139         179 :                 bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
     140         179 :                 data->key_data = NULL;
     141             :         }
     142         388 : }
     143             : 
     144             : 
     145         189 : static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
     146             : {
     147         189 :         struct eap_ttls_data *data = priv;
     148         189 :         if (data == NULL)
     149         189 :                 return;
     150         189 :         eap_ttls_phase2_eap_deinit(sm, data);
     151         189 :         os_free(data->phase2_eap_types);
     152         189 :         eap_peer_tls_ssl_deinit(sm, &data->ssl);
     153         189 :         eap_ttls_free_key(data);
     154         189 :         os_free(data->session_id);
     155         189 :         wpabuf_free(data->pending_phase2_req);
     156         189 :         os_free(data);
     157             : }
     158             : 
     159             : 
     160         496 : static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
     161             :                              int mandatory, size_t len)
     162             : {
     163             :         struct ttls_avp_vendor *avp;
     164             :         u8 flags;
     165             :         size_t hdrlen;
     166             : 
     167         496 :         avp = (struct ttls_avp_vendor *) avphdr;
     168         496 :         flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
     169         496 :         if (vendor_id) {
     170         200 :                 flags |= AVP_FLAGS_VENDOR;
     171         200 :                 hdrlen = sizeof(*avp);
     172         200 :                 avp->vendor_id = host_to_be32(vendor_id);
     173             :         } else {
     174         296 :                 hdrlen = sizeof(struct ttls_avp);
     175             :         }
     176             : 
     177         496 :         avp->avp_code = host_to_be32(avp_code);
     178         496 :         avp->avp_length = host_to_be32(((u32) flags << 24) |
     179             :                                        (u32) (hdrlen + len));
     180             : 
     181         496 :         return avphdr + hdrlen;
     182             : }
     183             : 
     184             : 
     185         254 : static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
     186             :                              u32 vendor_id, int mandatory,
     187             :                              const u8 *data, size_t len)
     188             : {
     189             :         u8 *pos;
     190         254 :         pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
     191         254 :         os_memcpy(pos, data, len);
     192         254 :         pos += len;
     193         254 :         AVP_PAD(start, pos);
     194         254 :         return pos;
     195             : }
     196             : 
     197             : 
     198          97 : static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
     199             :                                     int mandatory)
     200             : {
     201             :         struct wpabuf *msg;
     202             :         u8 *avp, *pos;
     203             : 
     204          97 :         msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
     205          97 :         if (msg == NULL) {
     206           0 :                 wpabuf_free(*resp);
     207           0 :                 *resp = NULL;
     208           0 :                 return -1;
     209             :         }
     210             : 
     211          97 :         avp = wpabuf_mhead(msg);
     212          97 :         pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp));
     213          97 :         os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
     214          97 :         pos += wpabuf_len(*resp);
     215          97 :         AVP_PAD(avp, pos);
     216          97 :         wpabuf_free(*resp);
     217          97 :         wpabuf_put(msg, pos - avp);
     218          97 :         *resp = msg;
     219          97 :         return 0;
     220             : }
     221             : 
     222             : 
     223         179 : static int eap_ttls_v0_derive_key(struct eap_sm *sm,
     224             :                                   struct eap_ttls_data *data)
     225             : {
     226         179 :         eap_ttls_free_key(data);
     227         179 :         data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
     228             :                                                  "ttls keying material",
     229             :                                                  EAP_TLS_KEY_LEN +
     230             :                                                  EAP_EMSK_LEN);
     231         179 :         if (!data->key_data) {
     232           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to derive key");
     233           0 :                 return -1;
     234             :         }
     235             : 
     236         179 :         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
     237         179 :                         data->key_data, EAP_TLS_KEY_LEN);
     238         179 :         wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
     239         179 :                         data->key_data + EAP_TLS_KEY_LEN,
     240             :                         EAP_EMSK_LEN);
     241             : 
     242         179 :         os_free(data->session_id);
     243         179 :         data->session_id = eap_peer_tls_derive_session_id(sm, &data->ssl,
     244             :                                                           EAP_TYPE_TTLS,
     245             :                                                           &data->id_len);
     246         179 :         if (data->session_id) {
     247         358 :                 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived Session-Id",
     248         179 :                             data->session_id, data->id_len);
     249             :         } else {
     250           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to derive Session-Id");
     251             :         }
     252             : 
     253         179 :         return 0;
     254             : }
     255             : 
     256             : 
     257             : #ifndef CONFIG_FIPS
     258         109 : static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
     259             :                                         struct eap_ttls_data *data, size_t len)
     260             : {
     261         109 :         return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
     262             : }
     263             : #endif /* CONFIG_FIPS */
     264             : 
     265             : 
     266          31 : static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
     267             :                                               u8 method)
     268             : {
     269             :         size_t i;
     270          86 :         for (i = 0; i < data->num_phase2_eap_types; i++) {
     271          62 :                 if (data->phase2_eap_types[i].vendor != EAP_VENDOR_IETF ||
     272          31 :                     data->phase2_eap_types[i].method != method)
     273          12 :                         continue;
     274             : 
     275          19 :                 data->phase2_eap_type.vendor =
     276          19 :                         data->phase2_eap_types[i].vendor;
     277          19 :                 data->phase2_eap_type.method =
     278          19 :                         data->phase2_eap_types[i].method;
     279          19 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
     280             :                            "Phase 2 EAP vendor %d method %d",
     281             :                            data->phase2_eap_type.vendor,
     282             :                            data->phase2_eap_type.method);
     283          19 :                 break;
     284             :         }
     285          31 : }
     286             : 
     287             : 
     288          56 : static int eap_ttls_phase2_eap_process(struct eap_sm *sm,
     289             :                                        struct eap_ttls_data *data,
     290             :                                        struct eap_method_ret *ret,
     291             :                                        struct eap_hdr *hdr, size_t len,
     292             :                                        struct wpabuf **resp)
     293             : {
     294             :         struct wpabuf msg;
     295             :         struct eap_method_ret iret;
     296             : 
     297          56 :         os_memset(&iret, 0, sizeof(iret));
     298          56 :         wpabuf_set(&msg, hdr, len);
     299          56 :         *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
     300             :                                              &msg);
     301          94 :         if ((iret.methodState == METHOD_DONE ||
     302          75 :              iret.methodState == METHOD_MAY_CONT) &&
     303          65 :             (iret.decision == DECISION_UNCOND_SUCC ||
     304          45 :              iret.decision == DECISION_COND_SUCC ||
     305          17 :              iret.decision == DECISION_FAIL)) {
     306          37 :                 ret->methodState = iret.methodState;
     307          37 :                 ret->decision = iret.decision;
     308             :         }
     309             : 
     310          56 :         return 0;
     311             : }
     312             : 
     313             : 
     314          70 : static int eap_ttls_phase2_request_eap_method(struct eap_sm *sm,
     315             :                                               struct eap_ttls_data *data,
     316             :                                               struct eap_method_ret *ret,
     317             :                                               struct eap_hdr *hdr, size_t len,
     318             :                                               u8 method, struct wpabuf **resp)
     319             : {
     320             : #ifdef EAP_TNC
     321          91 :         if (data->tnc_started && data->phase2_method &&
     322          63 :             data->phase2_priv && method == EAP_TYPE_TNC &&
     323          21 :             data->phase2_eap_type.method == EAP_TYPE_TNC)
     324          21 :                 return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len,
     325             :                                                    resp);
     326             : 
     327          49 :         if (data->ready_for_tnc && !data->tnc_started &&
     328             :             method == EAP_TYPE_TNC) {
     329           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
     330             :                            "EAP method");
     331           0 :                 data->tnc_started = 1;
     332             :         }
     333             : 
     334          49 :         if (data->tnc_started) {
     335           4 :                 if (data->phase2_eap_type.vendor != EAP_VENDOR_IETF ||
     336           2 :                     data->phase2_eap_type.method == EAP_TYPE_TNC) {
     337           0 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected EAP "
     338             :                                    "type %d for TNC", method);
     339           0 :                         return -1;
     340             :                 }
     341             : 
     342           2 :                 data->phase2_eap_type.vendor = EAP_VENDOR_IETF;
     343           2 :                 data->phase2_eap_type.method = method;
     344           2 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
     345             :                            "Phase 2 EAP vendor %d method %d (TNC)",
     346             :                            data->phase2_eap_type.vendor,
     347             :                            data->phase2_eap_type.method);
     348             : 
     349           2 :                 if (data->phase2_type == EAP_TTLS_PHASE2_EAP)
     350           0 :                         eap_ttls_phase2_eap_deinit(sm, data);
     351             :         }
     352             : #endif /* EAP_TNC */
     353             : 
     354          98 :         if (data->phase2_eap_type.vendor == EAP_VENDOR_IETF &&
     355          49 :             data->phase2_eap_type.method == EAP_TYPE_NONE)
     356          31 :                 eap_ttls_phase2_select_eap_method(data, method);
     357             : 
     358          49 :         if (method != data->phase2_eap_type.method || method == EAP_TYPE_NONE)
     359             :         {
     360          14 :                 if (eap_peer_tls_phase2_nak(data->phase2_eap_types,
     361             :                                             data->num_phase2_eap_types,
     362             :                                             hdr, resp))
     363           0 :                         return -1;
     364          14 :                 return 0;
     365             :         }
     366             : 
     367          35 :         if (data->phase2_priv == NULL) {
     368          21 :                 data->phase2_method = eap_peer_get_eap_method(
     369             :                         EAP_VENDOR_IETF, method);
     370          21 :                 if (data->phase2_method) {
     371          21 :                         sm->init_phase2 = 1;
     372          21 :                         data->phase2_priv = data->phase2_method->init(sm);
     373          21 :                         sm->init_phase2 = 0;
     374             :                 }
     375             :         }
     376          35 :         if (data->phase2_priv == NULL || data->phase2_method == NULL) {
     377           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
     378             :                            "Phase 2 EAP method %d", method);
     379           0 :                 return -1;
     380             :         }
     381             : 
     382          35 :         return eap_ttls_phase2_eap_process(sm, data, ret, hdr, len, resp);
     383             : }
     384             : 
     385             : 
     386          99 : static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
     387             :                                        struct eap_ttls_data *data,
     388             :                                        struct eap_method_ret *ret,
     389             :                                        struct eap_hdr *hdr,
     390             :                                        struct wpabuf **resp)
     391             : {
     392          99 :         size_t len = be_to_host16(hdr->length);
     393             :         u8 *pos;
     394          99 :         struct eap_peer_config *config = eap_get_config(sm);
     395             : 
     396          99 :         if (len <= sizeof(struct eap_hdr)) {
     397           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: too short "
     398             :                            "Phase 2 request (len=%lu)", (unsigned long) len);
     399           0 :                 return -1;
     400             :         }
     401          99 :         pos = (u8 *) (hdr + 1);
     402          99 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
     403          99 :         switch (*pos) {
     404             :         case EAP_TYPE_IDENTITY:
     405          29 :                 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
     406          29 :                 break;
     407             :         default:
     408          70 :                 if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len,
     409          70 :                                                        *pos, resp) < 0)
     410           0 :                         return -1;
     411          70 :                 break;
     412             :         }
     413             : 
     414         101 :         if (*resp == NULL &&
     415           4 :             (config->pending_req_identity || config->pending_req_password ||
     416           0 :              config->pending_req_otp)) {
     417           2 :                 return 0;
     418             :         }
     419             : 
     420          97 :         if (*resp == NULL)
     421           0 :                 return -1;
     422             : 
     423          97 :         wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
     424             :                         *resp);
     425          97 :         return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1);
     426             : }
     427             : 
     428             : 
     429          87 : static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
     430             :                                             struct eap_ttls_data *data,
     431             :                                             struct eap_method_ret *ret,
     432             :                                             struct wpabuf **resp)
     433             : {
     434             : #ifdef CONFIG_FIPS
     435             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPV2 not supported in FIPS build");
     436             :         return -1;
     437             : #else /* CONFIG_FIPS */
     438             : #ifdef EAP_MSCHAPv2
     439             :         struct wpabuf *msg;
     440             :         u8 *buf, *pos, *challenge, *peer_challenge;
     441             :         const u8 *identity, *password;
     442             :         size_t identity_len, password_len;
     443             :         int pwhash;
     444             : 
     445          87 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
     446             : 
     447          87 :         identity = eap_get_config_identity(sm, &identity_len);
     448          87 :         password = eap_get_config_password2(sm, &password_len, &pwhash);
     449          87 :         if (identity == NULL || password == NULL)
     450           0 :                 return -1;
     451             : 
     452          87 :         msg = wpabuf_alloc(identity_len + 1000);
     453          87 :         if (msg == NULL) {
     454           0 :                 wpa_printf(MSG_ERROR,
     455             :                            "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
     456           0 :                 return -1;
     457             :         }
     458          87 :         pos = buf = wpabuf_mhead(msg);
     459             : 
     460             :         /* User-Name */
     461          87 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     462             :                                identity, identity_len);
     463             : 
     464             :         /* MS-CHAP-Challenge */
     465          87 :         challenge = eap_ttls_implicit_challenge(
     466             :                 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
     467          87 :         if (challenge == NULL) {
     468           0 :                 wpabuf_free(msg);
     469           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
     470             :                            "implicit challenge");
     471           0 :                 return -1;
     472             :         }
     473             : 
     474          87 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
     475             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     476             :                                challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
     477             : 
     478             :         /* MS-CHAP2-Response */
     479          87 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,
     480             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     481             :                                EAP_TTLS_MSCHAPV2_RESPONSE_LEN);
     482          87 :         data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
     483          87 :         *pos++ = data->ident;
     484          87 :         *pos++ = 0; /* Flags */
     485          87 :         if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
     486           0 :                 os_free(challenge);
     487           0 :                 wpabuf_free(msg);
     488           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
     489             :                            "random data for peer challenge");
     490           0 :                 return -1;
     491             :         }
     492          87 :         peer_challenge = pos;
     493          87 :         pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
     494          87 :         os_memset(pos, 0, 8); /* Reserved, must be zero */
     495          87 :         pos += 8;
     496          87 :         if (mschapv2_derive_response(identity, identity_len, password,
     497             :                                      password_len, pwhash, challenge,
     498          87 :                                      peer_challenge, pos, data->auth_response,
     499          87 :                                      data->master_key)) {
     500           0 :                 os_free(challenge);
     501           0 :                 wpabuf_free(msg);
     502           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
     503             :                            "response");
     504           0 :                 return -1;
     505             :         }
     506          87 :         data->auth_response_valid = 1;
     507             : 
     508          87 :         pos += 24;
     509          87 :         os_free(challenge);
     510          87 :         AVP_PAD(buf, pos);
     511             : 
     512          87 :         wpabuf_put(msg, pos - buf);
     513          87 :         *resp = msg;
     514             : 
     515          87 :         return 0;
     516             : #else /* EAP_MSCHAPv2 */
     517             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
     518             :         return -1;
     519             : #endif /* EAP_MSCHAPv2 */
     520             : #endif /* CONFIG_FIPS */
     521             : }
     522             : 
     523             : 
     524          13 : static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
     525             :                                           struct eap_ttls_data *data,
     526             :                                           struct eap_method_ret *ret,
     527             :                                           struct wpabuf **resp)
     528             : {
     529             : #ifdef CONFIG_FIPS
     530             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAP not supported in FIPS build");
     531             :         return -1;
     532             : #else /* CONFIG_FIPS */
     533             :         struct wpabuf *msg;
     534             :         u8 *buf, *pos, *challenge;
     535             :         const u8 *identity, *password;
     536             :         size_t identity_len, password_len;
     537             :         int pwhash;
     538             : 
     539          13 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
     540             : 
     541          13 :         identity = eap_get_config_identity(sm, &identity_len);
     542          13 :         password = eap_get_config_password2(sm, &password_len, &pwhash);
     543          13 :         if (identity == NULL || password == NULL)
     544           0 :                 return -1;
     545             : 
     546          13 :         msg = wpabuf_alloc(identity_len + 1000);
     547          13 :         if (msg == NULL) {
     548           0 :                 wpa_printf(MSG_ERROR,
     549             :                            "EAP-TTLS/MSCHAP: Failed to allocate memory");
     550           0 :                 return -1;
     551             :         }
     552          13 :         pos = buf = wpabuf_mhead(msg);
     553             : 
     554             :         /* User-Name */
     555          13 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     556             :                                identity, identity_len);
     557             : 
     558             :         /* MS-CHAP-Challenge */
     559          13 :         challenge = eap_ttls_implicit_challenge(
     560             :                 sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
     561          13 :         if (challenge == NULL) {
     562           0 :                 wpabuf_free(msg);
     563           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
     564             :                            "implicit challenge");
     565           0 :                 return -1;
     566             :         }
     567             : 
     568          13 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
     569             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     570             :                                challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
     571             : 
     572             :         /* MS-CHAP-Response */
     573          13 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,
     574             :                                RADIUS_VENDOR_ID_MICROSOFT, 1,
     575             :                                EAP_TTLS_MSCHAP_RESPONSE_LEN);
     576          13 :         data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];
     577          13 :         *pos++ = data->ident;
     578          13 :         *pos++ = 1; /* Flags: Use NT style passwords */
     579          13 :         os_memset(pos, 0, 24); /* LM-Response */
     580          13 :         pos += 24;
     581          13 :         if (pwhash) {
     582           0 :                 challenge_response(challenge, password, pos); /* NT-Response */
     583           0 :                 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash",
     584             :                                 password, 16);
     585             :         } else {
     586          13 :                 nt_challenge_response(challenge, password, password_len,
     587             :                                       pos); /* NT-Response */
     588          13 :                 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
     589             :                                       password, password_len);
     590             :         }
     591          13 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
     592             :                     challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
     593          13 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
     594          13 :         pos += 24;
     595          13 :         os_free(challenge);
     596          13 :         AVP_PAD(buf, pos);
     597             : 
     598          13 :         wpabuf_put(msg, pos - buf);
     599          13 :         *resp = msg;
     600             : 
     601             :         /* EAP-TTLS/MSCHAP does not provide tunneled success
     602             :          * notification, so assume that Phase2 succeeds. */
     603          13 :         ret->methodState = METHOD_DONE;
     604          13 :         ret->decision = DECISION_COND_SUCC;
     605             : 
     606          13 :         return 0;
     607             : #endif /* CONFIG_FIPS */
     608             : }
     609             : 
     610             : 
     611          36 : static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
     612             :                                        struct eap_ttls_data *data,
     613             :                                        struct eap_method_ret *ret,
     614             :                                        struct wpabuf **resp)
     615             : {
     616             :         struct wpabuf *msg;
     617             :         u8 *buf, *pos;
     618             :         size_t pad;
     619             :         const u8 *identity, *password;
     620             :         size_t identity_len, password_len;
     621             : 
     622          36 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
     623             : 
     624          36 :         identity = eap_get_config_identity(sm, &identity_len);
     625          36 :         password = eap_get_config_password(sm, &password_len);
     626          36 :         if (identity == NULL || password == NULL)
     627           0 :                 return -1;
     628             : 
     629          36 :         msg = wpabuf_alloc(identity_len + password_len + 100);
     630          36 :         if (msg == NULL) {
     631           0 :                 wpa_printf(MSG_ERROR,
     632             :                            "EAP-TTLS/PAP: Failed to allocate memory");
     633           0 :                 return -1;
     634             :         }
     635          36 :         pos = buf = wpabuf_mhead(msg);
     636             : 
     637             :         /* User-Name */
     638          36 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     639             :                                identity, identity_len);
     640             : 
     641             :         /* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
     642             :          * the data, so no separate encryption is used in the AVP itself.
     643             :          * However, the password is padded to obfuscate its length. */
     644          36 :         pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15;
     645          36 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
     646             :                                password_len + pad);
     647          36 :         os_memcpy(pos, password, password_len);
     648          36 :         pos += password_len;
     649          36 :         os_memset(pos, 0, pad);
     650          36 :         pos += pad;
     651          36 :         AVP_PAD(buf, pos);
     652             : 
     653          36 :         wpabuf_put(msg, pos - buf);
     654          36 :         *resp = msg;
     655             : 
     656             :         /* EAP-TTLS/PAP does not provide tunneled success notification,
     657             :          * so assume that Phase2 succeeds. */
     658          36 :         ret->methodState = METHOD_DONE;
     659          36 :         ret->decision = DECISION_COND_SUCC;
     660             : 
     661          36 :         return 0;
     662             : }
     663             : 
     664             : 
     665           9 : static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
     666             :                                         struct eap_ttls_data *data,
     667             :                                         struct eap_method_ret *ret,
     668             :                                         struct wpabuf **resp)
     669             : {
     670             : #ifdef CONFIG_FIPS
     671             :         wpa_printf(MSG_ERROR, "EAP-TTLS: CHAP not supported in FIPS build");
     672             :         return -1;
     673             : #else /* CONFIG_FIPS */
     674             :         struct wpabuf *msg;
     675             :         u8 *buf, *pos, *challenge;
     676             :         const u8 *identity, *password;
     677             :         size_t identity_len, password_len;
     678             : 
     679           9 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
     680             : 
     681           9 :         identity = eap_get_config_identity(sm, &identity_len);
     682           9 :         password = eap_get_config_password(sm, &password_len);
     683           9 :         if (identity == NULL || password == NULL)
     684           0 :                 return -1;
     685             : 
     686           9 :         msg = wpabuf_alloc(identity_len + 1000);
     687           9 :         if (msg == NULL) {
     688           0 :                 wpa_printf(MSG_ERROR,
     689             :                            "EAP-TTLS/CHAP: Failed to allocate memory");
     690           0 :                 return -1;
     691             :         }
     692           9 :         pos = buf = wpabuf_mhead(msg);
     693             : 
     694             :         /* User-Name */
     695           9 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
     696             :                                identity, identity_len);
     697             : 
     698             :         /* CHAP-Challenge */
     699           9 :         challenge = eap_ttls_implicit_challenge(
     700             :                 sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
     701           9 :         if (challenge == NULL) {
     702           0 :                 wpabuf_free(msg);
     703           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
     704             :                            "implicit challenge");
     705           0 :                 return -1;
     706             :         }
     707             : 
     708           9 :         pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,
     709             :                                challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
     710             : 
     711             :         /* CHAP-Password */
     712           9 :         pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,
     713             :                                1 + EAP_TTLS_CHAP_PASSWORD_LEN);
     714           9 :         data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];
     715           9 :         *pos++ = data->ident;
     716             : 
     717             :         /* MD5(Ident + Password + Challenge) */
     718           9 :         chap_md5(data->ident, password, password_len, challenge,
     719             :                  EAP_TTLS_CHAP_CHALLENGE_LEN, pos);
     720             : 
     721           9 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
     722             :                           identity, identity_len);
     723           9 :         wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
     724             :                               password, password_len);
     725           9 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
     726             :                     challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
     727           9 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
     728             :                     pos, EAP_TTLS_CHAP_PASSWORD_LEN);
     729           9 :         pos += EAP_TTLS_CHAP_PASSWORD_LEN;
     730           9 :         os_free(challenge);
     731           9 :         AVP_PAD(buf, pos);
     732             : 
     733           9 :         wpabuf_put(msg, pos - buf);
     734           9 :         *resp = msg;
     735             : 
     736             :         /* EAP-TTLS/CHAP does not provide tunneled success
     737             :          * notification, so assume that Phase2 succeeds. */
     738           9 :         ret->methodState = METHOD_DONE;
     739           9 :         ret->decision = DECISION_COND_SUCC;
     740             : 
     741           9 :         return 0;
     742             : #endif /* CONFIG_FIPS */
     743             : }
     744             : 
     745             : 
     746         249 : static int eap_ttls_phase2_request(struct eap_sm *sm,
     747             :                                    struct eap_ttls_data *data,
     748             :                                    struct eap_method_ret *ret,
     749             :                                    struct eap_hdr *hdr,
     750             :                                    struct wpabuf **resp)
     751             : {
     752         249 :         int res = 0;
     753             :         size_t len;
     754         249 :         enum phase2_types phase2_type = data->phase2_type;
     755             : 
     756             : #ifdef EAP_TNC
     757         249 :         if (data->tnc_started) {
     758          23 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC");
     759          23 :                 phase2_type = EAP_TTLS_PHASE2_EAP;
     760             :         }
     761             : #endif /* EAP_TNC */
     762             : 
     763         249 :         if (phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||
     764         145 :             phase2_type == EAP_TTLS_PHASE2_MSCHAP ||
     765         108 :             phase2_type == EAP_TTLS_PHASE2_PAP ||
     766             :             phase2_type == EAP_TTLS_PHASE2_CHAP) {
     767         150 :                 if (eap_get_config_identity(sm, &len) == NULL) {
     768           2 :                         wpa_printf(MSG_INFO,
     769             :                                    "EAP-TTLS: Identity not configured");
     770           2 :                         eap_sm_request_identity(sm);
     771           2 :                         if (eap_get_config_password(sm, &len) == NULL)
     772           1 :                                 eap_sm_request_password(sm);
     773           2 :                         return 0;
     774             :                 }
     775             : 
     776         148 :                 if (eap_get_config_password(sm, &len) == NULL) {
     777           3 :                         wpa_printf(MSG_INFO,
     778             :                                    "EAP-TTLS: Password not configured");
     779           3 :                         eap_sm_request_password(sm);
     780           3 :                         return 0;
     781             :                 }
     782             :         }
     783             : 
     784         244 :         switch (phase2_type) {
     785             :         case EAP_TTLS_PHASE2_EAP:
     786          99 :                 res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
     787          99 :                 break;
     788             :         case EAP_TTLS_PHASE2_MSCHAPV2:
     789          87 :                 res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);
     790          87 :                 break;
     791             :         case EAP_TTLS_PHASE2_MSCHAP:
     792          13 :                 res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);
     793          13 :                 break;
     794             :         case EAP_TTLS_PHASE2_PAP:
     795          36 :                 res = eap_ttls_phase2_request_pap(sm, data, ret, resp);
     796          36 :                 break;
     797             :         case EAP_TTLS_PHASE2_CHAP:
     798           9 :                 res = eap_ttls_phase2_request_chap(sm, data, ret, resp);
     799           9 :                 break;
     800             :         default:
     801           0 :                 wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
     802           0 :                 res = -1;
     803           0 :                 break;
     804             :         }
     805             : 
     806         244 :         if (res < 0) {
     807           0 :                 ret->methodState = METHOD_DONE;
     808           0 :                 ret->decision = DECISION_FAIL;
     809             :         }
     810             : 
     811         244 :         return res;
     812             : }
     813             : 
     814             : 
     815             : struct ttls_parse_avp {
     816             :         u8 *mschapv2;
     817             :         u8 *eapdata;
     818             :         size_t eap_len;
     819             :         int mschapv2_error;
     820             : };
     821             : 
     822             : 
     823          70 : static int eap_ttls_parse_attr_eap(const u8 *dpos, size_t dlen,
     824             :                                    struct ttls_parse_avp *parse)
     825             : {
     826          70 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
     827          70 :         if (parse->eapdata == NULL) {
     828          70 :                 parse->eapdata = os_malloc(dlen);
     829          70 :                 if (parse->eapdata == NULL) {
     830           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
     831             :                                    "memory for Phase 2 EAP data");
     832           0 :                         return -1;
     833             :                 }
     834          70 :                 os_memcpy(parse->eapdata, dpos, dlen);
     835          70 :                 parse->eap_len = dlen;
     836             :         } else {
     837           0 :                 u8 *neweap = os_realloc(parse->eapdata, parse->eap_len + dlen);
     838           0 :                 if (neweap == NULL) {
     839           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Failed to allocate "
     840             :                                    "memory for Phase 2 EAP data");
     841           0 :                         return -1;
     842             :                 }
     843           0 :                 os_memcpy(neweap + parse->eap_len, dpos, dlen);
     844           0 :                 parse->eapdata = neweap;
     845           0 :                 parse->eap_len += dlen;
     846             :         }
     847             : 
     848          70 :         return 0;
     849             : }
     850             : 
     851             : 
     852         156 : static int eap_ttls_parse_avp(u8 *pos, size_t left,
     853             :                               struct ttls_parse_avp *parse)
     854             : {
     855             :         struct ttls_avp *avp;
     856         156 :         u32 avp_code, avp_length, vendor_id = 0;
     857             :         u8 avp_flags, *dpos;
     858             :         size_t dlen;
     859             : 
     860         156 :         avp = (struct ttls_avp *) pos;
     861         156 :         avp_code = be_to_host32(avp->avp_code);
     862         156 :         avp_length = be_to_host32(avp->avp_length);
     863         156 :         avp_flags = (avp_length >> 24) & 0xff;
     864         156 :         avp_length &= 0xffffff;
     865         156 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
     866             :                    "length=%d", (int) avp_code, avp_flags,
     867             :                    (int) avp_length);
     868             : 
     869         156 :         if (avp_length > left) {
     870           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
     871             :                            "(len=%d, left=%lu) - dropped",
     872             :                            (int) avp_length, (unsigned long) left);
     873           0 :                 return -1;
     874             :         }
     875             : 
     876         156 :         if (avp_length < sizeof(*avp)) {
     877           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length %d",
     878             :                            avp_length);
     879           0 :                 return -1;
     880             :         }
     881             : 
     882         156 :         dpos = (u8 *) (avp + 1);
     883         156 :         dlen = avp_length - sizeof(*avp);
     884         156 :         if (avp_flags & AVP_FLAGS_VENDOR) {
     885          86 :                 if (dlen < 4) {
     886           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Vendor AVP "
     887             :                                    "underflow");
     888           0 :                         return -1;
     889             :                 }
     890          86 :                 vendor_id = WPA_GET_BE32(dpos);
     891          86 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
     892             :                            (int) vendor_id);
     893          86 :                 dpos += 4;
     894          86 :                 dlen -= 4;
     895             :         }
     896             : 
     897         156 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
     898             : 
     899         156 :         if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
     900         140 :                 if (eap_ttls_parse_attr_eap(dpos, dlen, parse) < 0)
     901           0 :                         return -1;
     902          86 :         } else if (vendor_id == 0 && avp_code == RADIUS_ATTR_REPLY_MESSAGE) {
     903             :                 /* This is an optional message that can be displayed to
     904             :                  * the user. */
     905           0 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: AVP - Reply-Message",
     906             :                                   dpos, dlen);
     907          86 :         } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     908             :                    avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {
     909          85 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP2-Success",
     910             :                                   dpos, dlen);
     911          85 :                 if (dlen != 43) {
     912           0 :                         wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "
     913             :                                    "MS-CHAP2-Success length "
     914             :                                    "(len=%lu, expected 43)",
     915             :                                    (unsigned long) dlen);
     916           0 :                         return -1;
     917             :                 }
     918          85 :                 parse->mschapv2 = dpos;
     919           1 :         } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
     920             :                    avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {
     921           1 :                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MS-CHAP-Error",
     922             :                                   dpos, dlen);
     923           1 :                 parse->mschapv2_error = 1;
     924           0 :         } else if (avp_flags & AVP_FLAGS_MANDATORY) {
     925           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported mandatory AVP "
     926             :                            "code %d vendor_id %d - dropped",
     927             :                            (int) avp_code, (int) vendor_id);
     928           0 :                 return -1;
     929             :         } else {
     930           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported AVP "
     931             :                            "code %d vendor_id %d",
     932             :                            (int) avp_code, (int) vendor_id);
     933             :         }
     934             : 
     935         156 :         return avp_length;
     936             : }
     937             : 
     938             : 
     939         156 : static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,
     940             :                                struct ttls_parse_avp *parse)
     941             : {
     942             :         u8 *pos;
     943             :         size_t left, pad;
     944             :         int avp_length;
     945             : 
     946         156 :         pos = wpabuf_mhead(in_decrypted);
     947         156 :         left = wpabuf_len(in_decrypted);
     948         156 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);
     949         156 :         if (left < sizeof(struct ttls_avp)) {
     950           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
     951             :                            " len=%lu expected %lu or more - dropped",
     952             :                            (unsigned long) left,
     953             :                            (unsigned long) sizeof(struct ttls_avp));
     954           0 :                 return -1;
     955             :         }
     956             : 
     957             :         /* Parse AVPs */
     958         156 :         os_memset(parse, 0, sizeof(*parse));
     959             : 
     960         468 :         while (left > 0) {
     961         156 :                 avp_length = eap_ttls_parse_avp(pos, left, parse);
     962         156 :                 if (avp_length < 0)
     963           0 :                         return -1;
     964             : 
     965         156 :                 pad = (4 - (avp_length & 3)) & 3;
     966         156 :                 pos += avp_length + pad;
     967         156 :                 if (left < avp_length + pad)
     968          85 :                         left = 0;
     969             :                 else
     970          71 :                         left -= avp_length + pad;
     971             :         }
     972             : 
     973         156 :         return 0;
     974             : }
     975             : 
     976             : 
     977         179 : static u8 * eap_ttls_fake_identity_request(void)
     978             : {
     979             :         struct eap_hdr *hdr;
     980             :         u8 *buf;
     981             : 
     982         179 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "
     983             :                    "Phase 2 - use fake EAP-Request Identity");
     984         179 :         buf = os_malloc(sizeof(*hdr) + 1);
     985         179 :         if (buf == NULL) {
     986           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "
     987             :                            "memory for fake EAP-Identity Request");
     988           0 :                 return NULL;
     989             :         }
     990             : 
     991         179 :         hdr = (struct eap_hdr *) buf;
     992         179 :         hdr->code = EAP_CODE_REQUEST;
     993         179 :         hdr->identifier = 0;
     994         179 :         hdr->length = host_to_be16(sizeof(*hdr) + 1);
     995         179 :         buf[sizeof(*hdr)] = EAP_TYPE_IDENTITY;
     996             : 
     997         179 :         return buf;
     998             : }
     999             : 
    1000             : 
    1001         247 : static int eap_ttls_encrypt_response(struct eap_sm *sm,
    1002             :                                      struct eap_ttls_data *data,
    1003             :                                      struct wpabuf *resp, u8 identifier,
    1004             :                                      struct wpabuf **out_data)
    1005             : {
    1006         247 :         if (resp == NULL)
    1007           5 :                 return 0;
    1008             : 
    1009         242 :         wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
    1010             :                             resp);
    1011         242 :         if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
    1012             :                                  data->ttls_version, identifier,
    1013             :                                  resp, out_data)) {
    1014           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
    1015             :                            "frame");
    1016           0 :                 wpabuf_free(resp);
    1017           0 :                 return -1;
    1018             :         }
    1019         242 :         wpabuf_free(resp);
    1020             : 
    1021         242 :         return 0;
    1022             : }
    1023             : 
    1024             : 
    1025          70 : static int eap_ttls_process_phase2_eap(struct eap_sm *sm,
    1026             :                                        struct eap_ttls_data *data,
    1027             :                                        struct eap_method_ret *ret,
    1028             :                                        struct ttls_parse_avp *parse,
    1029             :                                        struct wpabuf **resp)
    1030             : {
    1031             :         struct eap_hdr *hdr;
    1032             :         size_t len;
    1033             : 
    1034          70 :         if (parse->eapdata == NULL) {
    1035           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in the "
    1036             :                            "packet - dropped");
    1037           0 :                 return -1;
    1038             :         }
    1039             : 
    1040         140 :         wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",
    1041          70 :                     parse->eapdata, parse->eap_len);
    1042          70 :         hdr = (struct eap_hdr *) parse->eapdata;
    1043             : 
    1044          70 :         if (parse->eap_len < sizeof(*hdr)) {
    1045           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 EAP "
    1046             :                            "frame (len=%lu, expected %lu or more) - dropped",
    1047             :                            (unsigned long) parse->eap_len,
    1048             :                            (unsigned long) sizeof(*hdr));
    1049           0 :                 return -1;
    1050             :         }
    1051          70 :         len = be_to_host16(hdr->length);
    1052          70 :         if (len > parse->eap_len) {
    1053           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in Phase 2 "
    1054             :                            "EAP frame (EAP hdr len=%lu, EAP data len in "
    1055             :                            "AVP=%lu)",
    1056             :                            (unsigned long) len,
    1057             :                            (unsigned long) parse->eap_len);
    1058           0 :                 return -1;
    1059             :         }
    1060         140 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "
    1061             :                    "identifier=%d length=%lu",
    1062         140 :                    hdr->code, hdr->identifier, (unsigned long) len);
    1063          70 :         switch (hdr->code) {
    1064             :         case EAP_CODE_REQUEST:
    1065          70 :                 if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {
    1066           0 :                         wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
    1067             :                                    "processing failed");
    1068           0 :                         return -1;
    1069             :                 }
    1070          70 :                 break;
    1071             :         default:
    1072           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "
    1073           0 :                            "Phase 2 EAP header", hdr->code);
    1074           0 :                 return -1;
    1075             :         }
    1076             : 
    1077          70 :         return 0;
    1078             : }
    1079             : 
    1080             : 
    1081          88 : static int eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
    1082             :                                             struct eap_ttls_data *data,
    1083             :                                             struct eap_method_ret *ret,
    1084             :                                             struct ttls_parse_avp *parse)
    1085             : {
    1086             : #ifdef EAP_MSCHAPv2
    1087          88 :         if (parse->mschapv2_error) {
    1088           1 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "
    1089             :                            "MS-CHAP-Error - failed");
    1090           1 :                 ret->methodState = METHOD_DONE;
    1091           1 :                 ret->decision = DECISION_FAIL;
    1092             :                 /* Reply with empty data to ACK error */
    1093           1 :                 return 1;
    1094             :         }
    1095             : 
    1096          87 :         if (parse->mschapv2 == NULL) {
    1097             : #ifdef EAP_TNC
    1098           2 :                 if (data->phase2_success && parse->eapdata) {
    1099             :                         /*
    1100             :                          * Allow EAP-TNC to be started after successfully
    1101             :                          * completed MSCHAPV2.
    1102             :                          */
    1103           2 :                         return 1;
    1104             :                 }
    1105             : #endif /* EAP_TNC */
    1106           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success AVP "
    1107             :                            "received for Phase2 MSCHAPV2");
    1108           0 :                 return -1;
    1109             :         }
    1110          85 :         if (parse->mschapv2[0] != data->ident) {
    1111           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch for Phase 2 "
    1112             :                            "MSCHAPV2 (received Ident 0x%02x, expected 0x%02x)",
    1113           0 :                            parse->mschapv2[0], data->ident);
    1114           0 :                 return -1;
    1115             :         }
    1116         170 :         if (!data->auth_response_valid ||
    1117          85 :             mschapv2_verify_auth_response(data->auth_response,
    1118          85 :                                           parse->mschapv2 + 1, 42)) {
    1119           0 :                 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid authenticator "
    1120             :                            "response in Phase 2 MSCHAPV2 success request");
    1121           0 :                 return -1;
    1122             :         }
    1123             : 
    1124          85 :         wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
    1125             :                    "authentication succeeded");
    1126          85 :         ret->methodState = METHOD_DONE;
    1127          85 :         ret->decision = DECISION_UNCOND_SUCC;
    1128          85 :         data->phase2_success = 1;
    1129             : 
    1130             :         /*
    1131             :          * Reply with empty data; authentication server will reply
    1132             :          * with EAP-Success after this.
    1133             :          */
    1134          85 :         return 1;
    1135             : #else /* EAP_MSCHAPv2 */
    1136             :         wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
    1137             :         return -1;
    1138             : #endif /* EAP_MSCHAPv2 */
    1139             : }
    1140             : 
    1141             : 
    1142             : #ifdef EAP_TNC
    1143           2 : static int eap_ttls_process_tnc_start(struct eap_sm *sm,
    1144             :                                       struct eap_ttls_data *data,
    1145             :                                       struct eap_method_ret *ret,
    1146             :                                       struct ttls_parse_avp *parse,
    1147             :                                       struct wpabuf **resp)
    1148             : {
    1149             :         /* TNC uses inner EAP method after non-EAP TTLS phase 2. */
    1150           2 :         if (parse->eapdata == NULL) {
    1151           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
    1152             :                            "unexpected tunneled data (no EAP)");
    1153           0 :                 return -1;
    1154             :         }
    1155             : 
    1156           2 :         if (!data->ready_for_tnc) {
    1157           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received "
    1158             :                            "EAP after non-EAP, but not ready for TNC");
    1159           0 :                 return -1;
    1160             :         }
    1161             : 
    1162           2 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: Start TNC after completed "
    1163             :                    "non-EAP method");
    1164           2 :         data->tnc_started = 1;
    1165             : 
    1166           2 :         if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)
    1167           0 :                 return -1;
    1168             : 
    1169           2 :         return 0;
    1170             : }
    1171             : #endif /* EAP_TNC */
    1172             : 
    1173             : 
    1174         156 : static int eap_ttls_process_decrypted(struct eap_sm *sm,
    1175             :                                       struct eap_ttls_data *data,
    1176             :                                       struct eap_method_ret *ret,
    1177             :                                       u8 identifier,
    1178             :                                       struct ttls_parse_avp *parse,
    1179             :                                       struct wpabuf *in_decrypted,
    1180             :                                       struct wpabuf **out_data)
    1181             : {
    1182         156 :         struct wpabuf *resp = NULL;
    1183         156 :         struct eap_peer_config *config = eap_get_config(sm);
    1184             :         int res;
    1185         156 :         enum phase2_types phase2_type = data->phase2_type;
    1186             : 
    1187             : #ifdef EAP_TNC
    1188         156 :         if (data->tnc_started)
    1189          21 :                 phase2_type = EAP_TTLS_PHASE2_EAP;
    1190             : #endif /* EAP_TNC */
    1191             : 
    1192         156 :         switch (phase2_type) {
    1193             :         case EAP_TTLS_PHASE2_EAP:
    1194          68 :                 if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <
    1195             :                     0)
    1196           0 :                         return -1;
    1197          68 :                 break;
    1198             :         case EAP_TTLS_PHASE2_MSCHAPV2:
    1199          88 :                 res = eap_ttls_process_phase2_mschapv2(sm, data, ret, parse);
    1200             : #ifdef EAP_TNC
    1201          88 :                 if (res == 1 && parse->eapdata && data->phase2_success) {
    1202             :                         /*
    1203             :                          * TNC may be required as the next
    1204             :                          * authentication method within the tunnel.
    1205             :                          */
    1206           2 :                         ret->methodState = METHOD_MAY_CONT;
    1207           2 :                         data->ready_for_tnc = 1;
    1208           2 :                         if (eap_ttls_process_tnc_start(sm, data, ret, parse,
    1209             :                                                        &resp) == 0)
    1210           2 :                                 break;
    1211             :                 }
    1212             : #endif /* EAP_TNC */
    1213          86 :                 return res;
    1214             :         case EAP_TTLS_PHASE2_MSCHAP:
    1215             :         case EAP_TTLS_PHASE2_PAP:
    1216             :         case EAP_TTLS_PHASE2_CHAP:
    1217             : #ifdef EAP_TNC
    1218           0 :                 if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <
    1219             :                     0)
    1220           0 :                         return -1;
    1221           0 :                 break;
    1222             : #else /* EAP_TNC */
    1223             :                 /* EAP-TTLS/{MSCHAP,PAP,CHAP} should not send any TLS tunneled
    1224             :                  * requests to the supplicant */
    1225             :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "
    1226             :                            "tunneled data");
    1227             :                 return -1;
    1228             : #endif /* EAP_TNC */
    1229             :         }
    1230             : 
    1231          70 :         if (resp) {
    1232          68 :                 if (eap_ttls_encrypt_response(sm, data, resp, identifier,
    1233             :                                               out_data) < 0)
    1234           0 :                         return -1;
    1235           4 :         } else if (config->pending_req_identity ||
    1236           2 :                    config->pending_req_password ||
    1237           0 :                    config->pending_req_otp ||
    1238           0 :                    config->pending_req_new_password) {
    1239           2 :                 wpabuf_free(data->pending_phase2_req);
    1240           2 :                 data->pending_phase2_req = wpabuf_dup(in_decrypted);
    1241             :         }
    1242             : 
    1243          70 :         return 0;
    1244             : }
    1245             : 
    1246             : 
    1247         179 : static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
    1248             :                                               struct eap_ttls_data *data,
    1249             :                                               struct eap_method_ret *ret,
    1250             :                                               u8 identifier,
    1251             :                                               struct wpabuf **out_data)
    1252             : {
    1253         179 :         int retval = 0;
    1254             :         struct eap_hdr *hdr;
    1255             :         struct wpabuf *resp;
    1256             : 
    1257         179 :         hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();
    1258         179 :         if (hdr == NULL) {
    1259           0 :                 ret->methodState = METHOD_DONE;
    1260           0 :                 ret->decision = DECISION_FAIL;
    1261           0 :                 return -1;
    1262             :         }
    1263             : 
    1264         179 :         resp = NULL;
    1265         179 :         if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {
    1266           0 :                 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
    1267             :                            "processing failed");
    1268           0 :                 retval = -1;
    1269             :         } else {
    1270         179 :                 struct eap_peer_config *config = eap_get_config(sm);
    1271         184 :                 if (resp == NULL &&
    1272           8 :                     (config->pending_req_identity ||
    1273           3 :                      config->pending_req_password ||
    1274           0 :                      config->pending_req_otp ||
    1275           0 :                      config->pending_req_new_password)) {
    1276             :                         /*
    1277             :                          * Use empty buffer to force implicit request
    1278             :                          * processing when EAP request is re-processed after
    1279             :                          * user input.
    1280             :                          */
    1281           5 :                         wpabuf_free(data->pending_phase2_req);
    1282           5 :                         data->pending_phase2_req = wpabuf_alloc(0);
    1283             :                 }
    1284             : 
    1285         179 :                 retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
    1286             :                                                    out_data);
    1287             :         }
    1288             : 
    1289         179 :         os_free(hdr);
    1290             : 
    1291         179 :         if (retval < 0) {
    1292           0 :                 ret->methodState = METHOD_DONE;
    1293           0 :                 ret->decision = DECISION_FAIL;
    1294             :         }
    1295             : 
    1296         179 :         return retval;
    1297             : }
    1298             : 
    1299             : 
    1300         174 : static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,
    1301             :                                  struct eap_method_ret *ret, u8 identifier,
    1302             :                                  struct wpabuf **out_data)
    1303             : {
    1304         174 :         data->phase2_start = 0;
    1305             : 
    1306             :         /*
    1307             :          * EAP-TTLS does not use Phase2 on fast re-auth; this must be done only
    1308             :          * if TLS part was indeed resuming a previous session. Most
    1309             :          * Authentication Servers terminate EAP-TTLS before reaching this
    1310             :          * point, but some do not. Make wpa_supplicant stop phase 2 here, if
    1311             :          * needed.
    1312             :          */
    1313         189 :         if (data->reauth &&
    1314          15 :             tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
    1315           0 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
    1316             :                            "skip phase 2");
    1317           0 :                 *out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,
    1318             :                                                    data->ttls_version);
    1319           0 :                 ret->methodState = METHOD_DONE;
    1320           0 :                 ret->decision = DECISION_UNCOND_SUCC;
    1321           0 :                 data->phase2_success = 1;
    1322           0 :                 return 0;
    1323             :         }
    1324             : 
    1325         174 :         return eap_ttls_implicit_identity_request(sm, data, ret, identifier,
    1326             :                                                   out_data);
    1327             : }
    1328             : 
    1329             : 
    1330         341 : static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
    1331             :                             struct eap_method_ret *ret, u8 identifier,
    1332             :                             const struct wpabuf *in_data,
    1333             :                             struct wpabuf **out_data)
    1334             : {
    1335         341 :         struct wpabuf *in_decrypted = NULL;
    1336         341 :         int retval = 0;
    1337             :         struct ttls_parse_avp parse;
    1338             : 
    1339         341 :         os_memset(&parse, 0, sizeof(parse));
    1340             : 
    1341         341 :         wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
    1342             :                    " Phase 2",
    1343             :                    in_data ? (unsigned long) wpabuf_len(in_data) : 0);
    1344             : 
    1345         341 :         if (data->pending_phase2_req) {
    1346           7 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
    1347             :                            "skip decryption and use old data");
    1348             :                 /* Clear TLS reassembly state. */
    1349           7 :                 eap_peer_tls_reset_input(&data->ssl);
    1350             : 
    1351           7 :                 in_decrypted = data->pending_phase2_req;
    1352           7 :                 data->pending_phase2_req = NULL;
    1353           7 :                 if (wpabuf_len(in_decrypted) == 0) {
    1354           5 :                         wpabuf_free(in_decrypted);
    1355           5 :                         return eap_ttls_implicit_identity_request(
    1356             :                                 sm, data, ret, identifier, out_data);
    1357             :                 }
    1358           2 :                 goto continue_req;
    1359             :         }
    1360             : 
    1361         514 :         if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
    1362         180 :             data->phase2_start) {
    1363         174 :                 return eap_ttls_phase2_start(sm, data, ret, identifier,
    1364             :                                              out_data);
    1365             :         }
    1366             : 
    1367         160 :         if (in_data == NULL || wpabuf_len(in_data) == 0) {
    1368             :                 /* Received TLS ACK - requesting more fragments */
    1369           6 :                 return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
    1370             :                                             data->ttls_version,
    1371             :                                             identifier, NULL, out_data);
    1372             :         }
    1373             : 
    1374         154 :         retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
    1375         154 :         if (retval)
    1376           0 :                 goto done;
    1377             : 
    1378             : continue_req:
    1379         156 :         data->phase2_start = 0;
    1380             : 
    1381         156 :         if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {
    1382           0 :                 retval = -1;
    1383           0 :                 goto done;
    1384             :         }
    1385             : 
    1386         156 :         retval = eap_ttls_process_decrypted(sm, data, ret, identifier,
    1387             :                                             &parse, in_decrypted, out_data);
    1388             : 
    1389             : done:
    1390         156 :         wpabuf_free(in_decrypted);
    1391         156 :         os_free(parse.eapdata);
    1392             : 
    1393         156 :         if (retval < 0) {
    1394           0 :                 ret->methodState = METHOD_DONE;
    1395           0 :                 ret->decision = DECISION_FAIL;
    1396             :         }
    1397             : 
    1398         156 :         return retval;
    1399             : }
    1400             : 
    1401             : 
    1402         804 : static int eap_ttls_process_handshake(struct eap_sm *sm,
    1403             :                                       struct eap_ttls_data *data,
    1404             :                                       struct eap_method_ret *ret,
    1405             :                                       u8 identifier,
    1406             :                                       const struct wpabuf *in_data,
    1407             :                                       struct wpabuf **out_data)
    1408             : {
    1409             :         int res;
    1410             : 
    1411         804 :         res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
    1412             :                                           data->ttls_version, identifier,
    1413             :                                           in_data, out_data);
    1414         804 :         if (res < 0) {
    1415          20 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS processing failed");
    1416          20 :                 ret->methodState = METHOD_DONE;
    1417          20 :                 ret->decision = DECISION_FAIL;
    1418          20 :                 return -1;
    1419             :         }
    1420             : 
    1421         784 :         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
    1422         179 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
    1423             :                            "Phase 2");
    1424         179 :                 if (data->resuming) {
    1425          20 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth - may "
    1426             :                                    "skip Phase 2");
    1427          20 :                         ret->decision = DECISION_COND_SUCC;
    1428          20 :                         ret->methodState = METHOD_MAY_CONT;
    1429             :                 }
    1430         179 :                 data->phase2_start = 1;
    1431         179 :                 eap_ttls_v0_derive_key(sm, data);
    1432             : 
    1433         179 :                 if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
    1434         174 :                         if (eap_ttls_decrypt(sm, data, ret, identifier,
    1435             :                                              NULL, out_data)) {
    1436           0 :                                 wpa_printf(MSG_WARNING, "EAP-TTLS: "
    1437             :                                            "failed to process early "
    1438             :                                            "start for Phase 2");
    1439             :                         }
    1440         174 :                         res = 0;
    1441             :                 }
    1442         179 :                 data->resuming = 0;
    1443             :         }
    1444             : 
    1445         784 :         if (res == 2) {
    1446             :                 /*
    1447             :                  * Application data included in the handshake message.
    1448             :                  */
    1449           0 :                 wpabuf_free(data->pending_phase2_req);
    1450           0 :                 data->pending_phase2_req = *out_data;
    1451           0 :                 *out_data = NULL;
    1452           0 :                 res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
    1453             :                                        out_data);
    1454             :         }
    1455             : 
    1456         784 :         return res;
    1457             : }
    1458             : 
    1459             : 
    1460         971 : static void eap_ttls_check_auth_status(struct eap_sm *sm, 
    1461             :                                        struct eap_ttls_data *data,
    1462             :                                        struct eap_method_ret *ret)
    1463             : {
    1464         971 :         if (ret->methodState == METHOD_DONE) {
    1465         182 :                 ret->allowNotifications = FALSE;
    1466         272 :                 if (ret->decision == DECISION_UNCOND_SUCC ||
    1467          90 :                     ret->decision == DECISION_COND_SUCC) {
    1468         160 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
    1469             :                                    "completed successfully");
    1470         160 :                         data->phase2_success = 1;
    1471             : #ifdef EAP_TNC
    1472         160 :                         if (!data->ready_for_tnc && !data->tnc_started) {
    1473             :                                 /*
    1474             :                                  * TNC may be required as the next
    1475             :                                  * authentication method within the tunnel.
    1476             :                                  */
    1477         160 :                                 ret->methodState = METHOD_MAY_CONT;
    1478         160 :                                 data->ready_for_tnc = 1;
    1479             :                         }
    1480             : #endif /* EAP_TNC */
    1481             :                 }
    1482        1578 :         } else if (ret->methodState == METHOD_MAY_CONT &&
    1483        1576 :                    (ret->decision == DECISION_UNCOND_SUCC ||
    1484         787 :                     ret->decision == DECISION_COND_SUCC)) {
    1485          15 :                         wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
    1486             :                                    "completed successfully (MAY_CONT)");
    1487          15 :                         data->phase2_success = 1;
    1488             :         }
    1489         971 : }
    1490             : 
    1491             : 
    1492         971 : static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
    1493             :                                         struct eap_method_ret *ret,
    1494             :                                         const struct wpabuf *reqData)
    1495             : {
    1496             :         size_t left;
    1497             :         int res;
    1498             :         u8 flags, id;
    1499             :         struct wpabuf *resp;
    1500             :         const u8 *pos;
    1501         971 :         struct eap_ttls_data *data = priv;
    1502             :         struct wpabuf msg;
    1503             : 
    1504         971 :         pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
    1505             :                                         reqData, &left, &flags);
    1506         971 :         if (pos == NULL)
    1507           0 :                 return NULL;
    1508         971 :         id = eap_get_id(reqData);
    1509             : 
    1510         971 :         if (flags & EAP_TLS_FLAGS_START) {
    1511         205 :                 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start (server ver=%d, own "
    1512             :                            "ver=%d)", flags & EAP_TLS_VERSION_MASK,
    1513             :                            data->ttls_version);
    1514             : 
    1515             :                 /* RFC 5281, Ch. 9.2:
    1516             :                  * "This packet MAY contain additional information in the form
    1517             :                  * of AVPs, which may provide useful hints to the client"
    1518             :                  * For now, ignore any potential extra data.
    1519             :                  */
    1520         205 :                 left = 0;
    1521             :         }
    1522             : 
    1523         971 :         wpabuf_set(&msg, pos, left);
    1524             : 
    1525         971 :         resp = NULL;
    1526        1138 :         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
    1527         167 :             !data->resuming) {
    1528         167 :                 res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
    1529             :         } else {
    1530         804 :                 res = eap_ttls_process_handshake(sm, data, ret, id,
    1531             :                                                  &msg, &resp);
    1532             :         }
    1533             : 
    1534         971 :         eap_ttls_check_auth_status(sm, data, ret);
    1535             : 
    1536             :         /* FIX: what about res == -1? Could just move all error processing into
    1537             :          * the other functions and get rid of this res==1 case here. */
    1538         971 :         if (res == 1) {
    1539         260 :                 wpabuf_free(resp);
    1540         260 :                 return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
    1541             :                                               data->ttls_version);
    1542             :         }
    1543         711 :         return resp;
    1544             : }
    1545             : 
    1546             : 
    1547          51 : static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv)
    1548             : {
    1549          51 :         struct eap_ttls_data *data = priv;
    1550         102 :         return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
    1551          51 :                 data->phase2_success;
    1552             : }
    1553             : 
    1554             : 
    1555          26 : static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
    1556             : {
    1557          26 :         struct eap_ttls_data *data = priv;
    1558          26 :         wpabuf_free(data->pending_phase2_req);
    1559          26 :         data->pending_phase2_req = NULL;
    1560             : #ifdef EAP_TNC
    1561          26 :         data->ready_for_tnc = 0;
    1562          26 :         data->tnc_started = 0;
    1563             : #endif /* EAP_TNC */
    1564          26 : }
    1565             : 
    1566             : 
    1567          20 : static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
    1568             : {
    1569          20 :         struct eap_ttls_data *data = priv;
    1570          20 :         eap_ttls_free_key(data);
    1571          20 :         os_free(data->session_id);
    1572          20 :         data->session_id = NULL;
    1573          20 :         if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
    1574           0 :                 os_free(data);
    1575           0 :                 return NULL;
    1576             :         }
    1577          24 :         if (data->phase2_priv && data->phase2_method &&
    1578           4 :             data->phase2_method->init_for_reauth)
    1579           0 :                 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
    1580          20 :         data->phase2_start = 0;
    1581          20 :         data->phase2_success = 0;
    1582          20 :         data->resuming = 1;
    1583          20 :         data->reauth = 1;
    1584          20 :         return priv;
    1585             : }
    1586             : 
    1587             : 
    1588         111 : static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,
    1589             :                                size_t buflen, int verbose)
    1590             : {
    1591         111 :         struct eap_ttls_data *data = priv;
    1592             :         int len, ret;
    1593             : 
    1594         111 :         len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
    1595         111 :         ret = os_snprintf(buf + len, buflen - len,
    1596             :                           "EAP-TTLSv%d Phase2 method=",
    1597             :                           data->ttls_version);
    1598         111 :         if (os_snprintf_error(buflen - len, ret))
    1599           0 :                 return len;
    1600         111 :         len += ret;
    1601         111 :         switch (data->phase2_type) {
    1602             :         case EAP_TTLS_PHASE2_EAP:
    1603          30 :                 ret = os_snprintf(buf + len, buflen - len, "EAP-%s\n",
    1604          15 :                                   data->phase2_method ?
    1605          15 :                                   data->phase2_method->name : "?");
    1606          15 :                 break;
    1607             :         case EAP_TTLS_PHASE2_MSCHAPV2:
    1608          52 :                 ret = os_snprintf(buf + len, buflen - len, "MSCHAPV2\n");
    1609          52 :                 break;
    1610             :         case EAP_TTLS_PHASE2_MSCHAP:
    1611           8 :                 ret = os_snprintf(buf + len, buflen - len, "MSCHAP\n");
    1612           8 :                 break;
    1613             :         case EAP_TTLS_PHASE2_PAP:
    1614          27 :                 ret = os_snprintf(buf + len, buflen - len, "PAP\n");
    1615          27 :                 break;
    1616             :         case EAP_TTLS_PHASE2_CHAP:
    1617           9 :                 ret = os_snprintf(buf + len, buflen - len, "CHAP\n");
    1618           9 :                 break;
    1619             :         default:
    1620           0 :                 ret = 0;
    1621           0 :                 break;
    1622             :         }
    1623         111 :         if (os_snprintf_error(buflen - len, ret))
    1624           0 :                 return len;
    1625         111 :         len += ret;
    1626             : 
    1627         111 :         return len;
    1628             : }
    1629             : 
    1630             : 
    1631         971 : static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv)
    1632             : {
    1633         971 :         struct eap_ttls_data *data = priv;
    1634         971 :         return data->key_data != NULL && data->phase2_success;
    1635             : }
    1636             : 
    1637             : 
    1638         205 : static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
    1639             : {
    1640         205 :         struct eap_ttls_data *data = priv;
    1641             :         u8 *key;
    1642             : 
    1643         205 :         if (data->key_data == NULL || !data->phase2_success)
    1644           0 :                 return NULL;
    1645             : 
    1646         205 :         key = os_malloc(EAP_TLS_KEY_LEN);
    1647         205 :         if (key == NULL)
    1648           0 :                 return NULL;
    1649             : 
    1650         205 :         *len = EAP_TLS_KEY_LEN;
    1651         205 :         os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
    1652             : 
    1653         205 :         return key;
    1654             : }
    1655             : 
    1656             : 
    1657         205 : static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
    1658             : {
    1659         205 :         struct eap_ttls_data *data = priv;
    1660             :         u8 *id;
    1661             : 
    1662         205 :         if (data->session_id == NULL || !data->phase2_success)
    1663           0 :                 return NULL;
    1664             : 
    1665         205 :         id = os_malloc(data->id_len);
    1666         205 :         if (id == NULL)
    1667           0 :                 return NULL;
    1668             : 
    1669         205 :         *len = data->id_len;
    1670         205 :         os_memcpy(id, data->session_id, data->id_len);
    1671             : 
    1672         205 :         return id;
    1673             : }
    1674             : 
    1675             : 
    1676           2 : static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
    1677             : {
    1678           2 :         struct eap_ttls_data *data = priv;
    1679             :         u8 *key;
    1680             : 
    1681           2 :         if (data->key_data == NULL)
    1682           0 :                 return NULL;
    1683             : 
    1684           2 :         key = os_malloc(EAP_EMSK_LEN);
    1685           2 :         if (key == NULL)
    1686           0 :                 return NULL;
    1687             : 
    1688           2 :         *len = EAP_EMSK_LEN;
    1689           2 :         os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
    1690             : 
    1691           2 :         return key;
    1692             : }
    1693             : 
    1694             : 
    1695          49 : int eap_peer_ttls_register(void)
    1696             : {
    1697             :         struct eap_method *eap;
    1698             :         int ret;
    1699             : 
    1700          49 :         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
    1701             :                                     EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
    1702          49 :         if (eap == NULL)
    1703           0 :                 return -1;
    1704             : 
    1705          49 :         eap->init = eap_ttls_init;
    1706          49 :         eap->deinit = eap_ttls_deinit;
    1707          49 :         eap->process = eap_ttls_process;
    1708          49 :         eap->isKeyAvailable = eap_ttls_isKeyAvailable;
    1709          49 :         eap->getKey = eap_ttls_getKey;
    1710          49 :         eap->getSessionId = eap_ttls_get_session_id;
    1711          49 :         eap->get_status = eap_ttls_get_status;
    1712          49 :         eap->has_reauth_data = eap_ttls_has_reauth_data;
    1713          49 :         eap->deinit_for_reauth = eap_ttls_deinit_for_reauth;
    1714          49 :         eap->init_for_reauth = eap_ttls_init_for_reauth;
    1715          49 :         eap->get_emsk = eap_ttls_get_emsk;
    1716             : 
    1717          49 :         ret = eap_peer_method_register(eap);
    1718          49 :         if (ret)
    1719           0 :                 eap_peer_method_free(eap);
    1720          49 :         return ret;
    1721             : }

Generated by: LCOV version 1.10