eap_fast.c
Go to the documentation of this file.
00001 /*
00002  * EAP peer method: EAP-FAST (RFC 4851)
00003  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "crypto/tls.h"
00019 #include "crypto/sha1.h"
00020 #include "eap_common/eap_tlv_common.h"
00021 #include "eap_i.h"
00022 #include "eap_tls_common.h"
00023 #include "eap_config.h"
00024 #include "eap_fast_pac.h"
00025 
00026 #ifdef EAP_FAST_DYNAMIC
00027 #include "eap_fast_pac.c"
00028 #endif /* EAP_FAST_DYNAMIC */
00029 
00030 /* TODO:
00031  * - test session resumption and enable it if it interoperates
00032  * - password change (pending mschapv2 packet; replay decrypted packet)
00033  */
00034 
00035 
00036 static void eap_fast_deinit(struct eap_sm *sm, void *priv);
00037 
00038 
00039 struct eap_fast_data {
00040         struct eap_ssl_data ssl;
00041 
00042         int fast_version;
00043 
00044         const struct eap_method *phase2_method;
00045         void *phase2_priv;
00046         int phase2_success;
00047 
00048         struct eap_method_type phase2_type;
00049         struct eap_method_type *phase2_types;
00050         size_t num_phase2_types;
00051         int resuming; /* starting a resumed session */
00052         struct eap_fast_key_block_provisioning *key_block_p;
00053 #define EAP_FAST_PROV_UNAUTH 1
00054 #define EAP_FAST_PROV_AUTH 2
00055         int provisioning_allowed; /* Allowed PAC provisioning modes */
00056         int provisioning; /* doing PAC provisioning (not the normal auth) */
00057         int anon_provisioning; /* doing anonymous (unauthenticated)
00058                                 * provisioning */
00059         int session_ticket_used;
00060 
00061         u8 key_data[EAP_FAST_KEY_LEN];
00062         u8 emsk[EAP_EMSK_LEN];
00063         int success;
00064 
00065         struct eap_fast_pac *pac;
00066         struct eap_fast_pac *current_pac;
00067         size_t max_pac_list_len;
00068         int use_pac_binary_format;
00069 
00070         u8 simck[EAP_FAST_SIMCK_LEN];
00071         int simck_idx;
00072 
00073         struct wpabuf *pending_phase2_req;
00074 };
00075 
00076 
00077 static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
00078                                       const u8 *client_random,
00079                                       const u8 *server_random,
00080                                       u8 *master_secret)
00081 {
00082         struct eap_fast_data *data = ctx;
00083 
00084         wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback");
00085 
00086         if (client_random == NULL || server_random == NULL ||
00087             master_secret == NULL) {
00088                 wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket failed - fall "
00089                            "back to full TLS handshake");
00090                 data->session_ticket_used = 0;
00091                 if (data->provisioning_allowed) {
00092                         wpa_printf(MSG_DEBUG, "EAP-FAST: Try to provision a "
00093                                    "new PAC-Key");
00094                         data->provisioning = 1;
00095                         data->current_pac = NULL;
00096                 }
00097                 return 0;
00098         }
00099 
00100         wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket", ticket, len);
00101 
00102         if (data->current_pac == NULL) {
00103                 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key available for "
00104                            "using SessionTicket");
00105                 data->session_ticket_used = 0;
00106                 return 0;
00107         }
00108 
00109         eap_fast_derive_master_secret(data->current_pac->pac_key,
00110                                       server_random, client_random,
00111                                       master_secret);
00112 
00113         data->session_ticket_used = 1;
00114 
00115         return 1;
00116 }
00117 
00118 
00119 static int eap_fast_parse_phase1(struct eap_fast_data *data,
00120                                  const char *phase1)
00121 {
00122         const char *pos;
00123 
00124         pos = os_strstr(phase1, "fast_provisioning=");
00125         if (pos) {
00126                 data->provisioning_allowed = atoi(pos + 18);
00127                 wpa_printf(MSG_DEBUG, "EAP-FAST: Automatic PAC provisioning "
00128                            "mode: %d", data->provisioning_allowed);
00129         }
00130 
00131         pos = os_strstr(phase1, "fast_max_pac_list_len=");
00132         if (pos) {
00133                 data->max_pac_list_len = atoi(pos + 22);
00134                 if (data->max_pac_list_len == 0)
00135                         data->max_pac_list_len = 1;
00136                 wpa_printf(MSG_DEBUG, "EAP-FAST: Maximum PAC list length: %lu",
00137                            (unsigned long) data->max_pac_list_len);
00138         }
00139 
00140         pos = os_strstr(phase1, "fast_pac_format=binary");
00141         if (pos) {
00142                 data->use_pac_binary_format = 1;
00143                 wpa_printf(MSG_DEBUG, "EAP-FAST: Using binary format for PAC "
00144                            "list");
00145         }
00146 
00147         return 0;
00148 }
00149 
00150 
00151 static void * eap_fast_init(struct eap_sm *sm)
00152 {
00153         struct eap_fast_data *data;
00154         struct eap_peer_config *config = eap_get_config(sm);
00155 
00156         data = os_zalloc(sizeof(*data));
00157         if (data == NULL)
00158                 return NULL;
00159         data->fast_version = EAP_FAST_VERSION;
00160         data->max_pac_list_len = 10;
00161 
00162         if (config && config->phase1 &&
00163             eap_fast_parse_phase1(data, config->phase1) < 0) {
00164                 eap_fast_deinit(sm, data);
00165                 return NULL;
00166         }
00167 
00168         if (eap_peer_select_phase2_methods(config, "auth=",
00169                                            &data->phase2_types,
00170                                            &data->num_phase2_types) < 0) {
00171                 eap_fast_deinit(sm, data);
00172                 return NULL;
00173         }
00174 
00175         data->phase2_type.vendor = EAP_VENDOR_IETF;
00176         data->phase2_type.method = EAP_TYPE_NONE;
00177 
00178         if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
00179                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
00180                 eap_fast_deinit(sm, data);
00181                 return NULL;
00182         }
00183 
00184         if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
00185                                                  eap_fast_session_ticket_cb,
00186                                                  data) < 0) {
00187                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket "
00188                            "callback");
00189                 eap_fast_deinit(sm, data);
00190                 return NULL;
00191         }
00192 
00193         /*
00194          * The local RADIUS server in a Cisco AP does not seem to like empty
00195          * fragments before data, so disable that workaround for CBC.
00196          * TODO: consider making this configurable
00197          */
00198         if (tls_connection_enable_workaround(sm->ssl_ctx, data->ssl.conn)) {
00199                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to enable TLS "
00200                            "workarounds");
00201         }
00202 
00203         if (data->use_pac_binary_format &&
00204             eap_fast_load_pac_bin(sm, &data->pac, config->pac_file) < 0) {
00205                 eap_fast_deinit(sm, data);
00206                 return NULL;
00207         }
00208 
00209         if (!data->use_pac_binary_format &&
00210             eap_fast_load_pac(sm, &data->pac, config->pac_file) < 0) {
00211                 eap_fast_deinit(sm, data);
00212                 return NULL;
00213         }
00214         eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len);
00215 
00216         if (data->pac == NULL && !data->provisioning_allowed) {
00217                 wpa_printf(MSG_INFO, "EAP-FAST: No PAC configured and "
00218                            "provisioning disabled");
00219                 eap_fast_deinit(sm, data);
00220                 return NULL;
00221         }
00222 
00223         return data;
00224 }
00225 
00226 
00227 static void eap_fast_deinit(struct eap_sm *sm, void *priv)
00228 {
00229         struct eap_fast_data *data = priv;
00230         struct eap_fast_pac *pac, *prev;
00231 
00232         if (data == NULL)
00233                 return;
00234         if (data->phase2_priv && data->phase2_method)
00235                 data->phase2_method->deinit(sm, data->phase2_priv);
00236         os_free(data->phase2_types);
00237         os_free(data->key_block_p);
00238         eap_peer_tls_ssl_deinit(sm, &data->ssl);
00239 
00240         pac = data->pac;
00241         prev = NULL;
00242         while (pac) {
00243                 prev = pac;
00244                 pac = pac->next;
00245                 eap_fast_free_pac(prev);
00246         }
00247         wpabuf_free(data->pending_phase2_req);
00248         os_free(data);
00249 }
00250 
00251 
00252 static int eap_fast_derive_msk(struct eap_fast_data *data)
00253 {
00254         eap_fast_derive_eap_msk(data->simck, data->key_data);
00255         eap_fast_derive_eap_emsk(data->simck, data->emsk);
00256         data->success = 1;
00257         return 0;
00258 }
00259 
00260 
00261 static void eap_fast_derive_key_auth(struct eap_sm *sm,
00262                                      struct eap_fast_data *data)
00263 {
00264         u8 *sks;
00265 
00266         /* RFC 4851, Section 5.1:
00267          * Extra key material after TLS key_block: session_key_seed[40]
00268          */
00269 
00270         sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion",
00271                                   EAP_FAST_SKS_LEN);
00272         if (sks == NULL) {
00273                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
00274                            "session_key_seed");
00275                 return;
00276         }
00277 
00278         /*
00279          * RFC 4851, Section 5.2:
00280          * S-IMCK[0] = session_key_seed
00281          */
00282         wpa_hexdump_key(MSG_DEBUG,
00283                         "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
00284                         sks, EAP_FAST_SKS_LEN);
00285         data->simck_idx = 0;
00286         os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
00287         os_free(sks);
00288 }
00289 
00290 
00291 static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
00292                                              struct eap_fast_data *data)
00293 {
00294         os_free(data->key_block_p);
00295         data->key_block_p = (struct eap_fast_key_block_provisioning *)
00296                 eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
00297                                     "key expansion",
00298                                     sizeof(*data->key_block_p));
00299         if (data->key_block_p == NULL) {
00300                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
00301                 return;
00302         }
00303         /*
00304          * RFC 4851, Section 5.2:
00305          * S-IMCK[0] = session_key_seed
00306          */
00307         wpa_hexdump_key(MSG_DEBUG,
00308                         "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
00309                         data->key_block_p->session_key_seed,
00310                         sizeof(data->key_block_p->session_key_seed));
00311         data->simck_idx = 0;
00312         os_memcpy(data->simck, data->key_block_p->session_key_seed,
00313                   EAP_FAST_SIMCK_LEN);
00314         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
00315                         data->key_block_p->server_challenge,
00316                         sizeof(data->key_block_p->server_challenge));
00317         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
00318                         data->key_block_p->client_challenge,
00319                         sizeof(data->key_block_p->client_challenge));
00320 }
00321 
00322 
00323 static void eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
00324 {
00325         if (data->anon_provisioning)
00326                 eap_fast_derive_key_provisioning(sm, data);
00327         else
00328                 eap_fast_derive_key_auth(sm, data);
00329 }
00330 
00331 
00332 static int eap_fast_init_phase2_method(struct eap_sm *sm,
00333                                        struct eap_fast_data *data)
00334 {
00335         data->phase2_method =
00336                 eap_peer_get_eap_method(data->phase2_type.vendor,
00337                                         data->phase2_type.method);
00338         if (data->phase2_method == NULL)
00339                 return -1;
00340 
00341         if (data->key_block_p) {
00342                 sm->auth_challenge = data->key_block_p->server_challenge;
00343                 sm->peer_challenge = data->key_block_p->client_challenge;
00344         }
00345         sm->init_phase2 = 1;
00346         data->phase2_priv = data->phase2_method->init(sm);
00347         sm->init_phase2 = 0;
00348         sm->auth_challenge = NULL;
00349         sm->peer_challenge = NULL;
00350 
00351         return data->phase2_priv == NULL ? -1 : 0;
00352 }
00353 
00354 
00355 static int eap_fast_select_phase2_method(struct eap_fast_data *data, u8 type)
00356 {
00357         size_t i;
00358 
00359         /* TODO: TNC with anonymous provisioning; need to require both
00360          * completed MSCHAPv2 and TNC */
00361 
00362         if (data->anon_provisioning && type != EAP_TYPE_MSCHAPV2) {
00363                 wpa_printf(MSG_INFO, "EAP-FAST: Only EAP-MSCHAPv2 is allowed "
00364                            "during unauthenticated provisioning; reject phase2"
00365                            " type %d", type);
00366                 return -1;
00367         }
00368 
00369 #ifdef EAP_TNC
00370         if (type == EAP_TYPE_TNC) {
00371                 data->phase2_type.vendor = EAP_VENDOR_IETF;
00372                 data->phase2_type.method = EAP_TYPE_TNC;
00373                 wpa_printf(MSG_DEBUG, "EAP-FAST: Selected Phase 2 EAP "
00374                            "vendor %d method %d for TNC",
00375                            data->phase2_type.vendor,
00376                            data->phase2_type.method);
00377                 return 0;
00378         }
00379 #endif /* EAP_TNC */
00380 
00381         for (i = 0; i < data->num_phase2_types; i++) {
00382                 if (data->phase2_types[i].vendor != EAP_VENDOR_IETF ||
00383                     data->phase2_types[i].method != type)
00384                         continue;
00385 
00386                 data->phase2_type.vendor = data->phase2_types[i].vendor;
00387                 data->phase2_type.method = data->phase2_types[i].method;
00388                 wpa_printf(MSG_DEBUG, "EAP-FAST: Selected Phase 2 EAP "
00389                            "vendor %d method %d",
00390                            data->phase2_type.vendor,
00391                            data->phase2_type.method);
00392                 break;
00393         }
00394 
00395         if (type != data->phase2_type.method || type == EAP_TYPE_NONE)
00396                 return -1;
00397 
00398         return 0;
00399 }
00400 
00401 
00402 static int eap_fast_phase2_request(struct eap_sm *sm,
00403                                    struct eap_fast_data *data,
00404                                    struct eap_method_ret *ret,
00405                                    struct eap_hdr *hdr,
00406                                    struct wpabuf **resp)
00407 {
00408         size_t len = be_to_host16(hdr->length);
00409         u8 *pos;
00410         struct eap_method_ret iret;
00411         struct eap_peer_config *config = eap_get_config(sm);
00412         struct wpabuf msg;
00413 
00414         if (len <= sizeof(struct eap_hdr)) {
00415                 wpa_printf(MSG_INFO, "EAP-FAST: too short "
00416                            "Phase 2 request (len=%lu)", (unsigned long) len);
00417                 return -1;
00418         }
00419         pos = (u8 *) (hdr + 1);
00420         wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
00421         if (*pos == EAP_TYPE_IDENTITY) {
00422                 *resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
00423                 return 0;
00424         }
00425 
00426         if (data->phase2_priv && data->phase2_method &&
00427             *pos != data->phase2_type.method) {
00428                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 EAP sequence - "
00429                            "deinitialize previous method");
00430                 data->phase2_method->deinit(sm, data->phase2_priv);
00431                 data->phase2_method = NULL;
00432                 data->phase2_priv = NULL;
00433                 data->phase2_type.vendor = EAP_VENDOR_IETF;
00434                 data->phase2_type.method = EAP_TYPE_NONE;
00435         }
00436 
00437         if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
00438             data->phase2_type.method == EAP_TYPE_NONE &&
00439             eap_fast_select_phase2_method(data, *pos) < 0) {
00440                 if (eap_peer_tls_phase2_nak(data->phase2_types,
00441                                             data->num_phase2_types,
00442                                             hdr, resp))
00443                         return -1;
00444                 return 0;
00445         }
00446 
00447         if (data->phase2_priv == NULL &&
00448             eap_fast_init_phase2_method(sm, data) < 0) {
00449                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize "
00450                            "Phase 2 EAP method %d", *pos);
00451                 ret->methodState = METHOD_DONE;
00452                 ret->decision = DECISION_FAIL;
00453                 return -1;
00454         }
00455 
00456         os_memset(&iret, 0, sizeof(iret));
00457         wpabuf_set(&msg, hdr, len);
00458         *resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
00459                                              &msg);
00460         if (*resp == NULL ||
00461             (iret.methodState == METHOD_DONE &&
00462              iret.decision == DECISION_FAIL)) {
00463                 ret->methodState = METHOD_DONE;
00464                 ret->decision = DECISION_FAIL;
00465         } else if ((iret.methodState == METHOD_DONE ||
00466                     iret.methodState == METHOD_MAY_CONT) &&
00467                    (iret.decision == DECISION_UNCOND_SUCC ||
00468                     iret.decision == DECISION_COND_SUCC)) {
00469                 data->phase2_success = 1;
00470         }
00471 
00472         if (*resp == NULL && config &&
00473             (config->pending_req_identity || config->pending_req_password ||
00474              config->pending_req_otp || config->pending_req_new_password)) {
00475                 wpabuf_free(data->pending_phase2_req);
00476                 data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
00477         } else if (*resp == NULL)
00478                 return -1;
00479 
00480         return 0;
00481 }
00482 
00483 
00484 static struct wpabuf * eap_fast_tlv_nak(int vendor_id, int tlv_type)
00485 {
00486         struct wpabuf *buf;
00487         struct eap_tlv_nak_tlv *nak;
00488         buf = wpabuf_alloc(sizeof(*nak));
00489         if (buf == NULL)
00490                 return NULL;
00491         nak = wpabuf_put(buf, sizeof(*nak));
00492         nak->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_NAK_TLV);
00493         nak->length = host_to_be16(6);
00494         nak->vendor_id = host_to_be32(vendor_id);
00495         nak->nak_type = host_to_be16(tlv_type);
00496         return buf;
00497 }
00498 
00499 
00500 static struct wpabuf * eap_fast_tlv_result(int status, int intermediate)
00501 {
00502         struct wpabuf *buf;
00503         struct eap_tlv_intermediate_result_tlv *result;
00504         buf = wpabuf_alloc(sizeof(*result));
00505         if (buf == NULL)
00506                 return NULL;
00507         wpa_printf(MSG_DEBUG, "EAP-FAST: Add %sResult TLV(status=%d)",
00508                    intermediate ? "Intermediate " : "", status);
00509         result = wpabuf_put(buf, sizeof(*result));
00510         result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
00511                                         (intermediate ?
00512                                          EAP_TLV_INTERMEDIATE_RESULT_TLV :
00513                                          EAP_TLV_RESULT_TLV));
00514         result->length = host_to_be16(2);
00515         result->status = host_to_be16(status);
00516         return buf;
00517 }
00518 
00519 
00520 static struct wpabuf * eap_fast_tlv_pac_ack(void)
00521 {
00522         struct wpabuf *buf;
00523         struct eap_tlv_result_tlv *res;
00524         struct eap_tlv_pac_ack_tlv *ack;
00525 
00526         buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack));
00527         if (buf == NULL)
00528                 return NULL;
00529 
00530         wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV (ack)");
00531         ack = wpabuf_put(buf, sizeof(*ack));
00532         ack->tlv_type = host_to_be16(EAP_TLV_PAC_TLV |
00533                                      EAP_TLV_TYPE_MANDATORY);
00534         ack->length = host_to_be16(sizeof(*ack) - sizeof(struct eap_tlv_hdr));
00535         ack->pac_type = host_to_be16(PAC_TYPE_PAC_ACKNOWLEDGEMENT);
00536         ack->pac_len = host_to_be16(2);
00537         ack->result = host_to_be16(EAP_TLV_RESULT_SUCCESS);
00538 
00539         return buf;
00540 }
00541 
00542 
00543 static struct wpabuf * eap_fast_process_eap_payload_tlv(
00544         struct eap_sm *sm, struct eap_fast_data *data,
00545         struct eap_method_ret *ret, const struct eap_hdr *req,
00546         u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
00547 {
00548         struct eap_hdr *hdr;
00549         struct wpabuf *resp = NULL;
00550 
00551         if (eap_payload_tlv_len < sizeof(*hdr)) {
00552                 wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP "
00553                            "Payload TLV (len=%lu)",
00554                            (unsigned long) eap_payload_tlv_len);
00555                 return NULL;
00556         }
00557 
00558         hdr = (struct eap_hdr *) eap_payload_tlv;
00559         if (be_to_host16(hdr->length) > eap_payload_tlv_len) {
00560                 wpa_printf(MSG_DEBUG, "EAP-FAST: EAP packet overflow in "
00561                            "EAP Payload TLV");
00562                 return NULL;
00563         }
00564 
00565         if (hdr->code != EAP_CODE_REQUEST) {
00566                 wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
00567                            "Phase 2 EAP header", hdr->code);
00568                 return NULL;
00569         }
00570 
00571         if (eap_fast_phase2_request(sm, data, ret, hdr, &resp)) {
00572                 wpa_printf(MSG_INFO, "EAP-FAST: Phase2 Request processing "
00573                            "failed");
00574                 return NULL;
00575         }
00576 
00577         return eap_fast_tlv_eap_payload(resp);
00578 }
00579 
00580 
00581 static int eap_fast_validate_crypto_binding(
00582         struct eap_tlv_crypto_binding_tlv *_bind)
00583 {
00584         wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV: Version %d "
00585                    "Received Version %d SubType %d",
00586                    _bind->version, _bind->received_version, _bind->subtype);
00587         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
00588                     _bind->nonce, sizeof(_bind->nonce));
00589         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
00590                     _bind->compound_mac, sizeof(_bind->compound_mac));
00591 
00592         if (_bind->version != EAP_FAST_VERSION ||
00593             _bind->received_version != EAP_FAST_VERSION ||
00594             _bind->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST) {
00595                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid version/subtype in "
00596                            "Crypto-Binding TLV: Version %d "
00597                            "Received Version %d SubType %d",
00598                            _bind->version, _bind->received_version,
00599                            _bind->subtype);
00600                 return -1;
00601         }
00602 
00603         return 0;
00604 }
00605 
00606 
00607 static void eap_fast_write_crypto_binding(
00608         struct eap_tlv_crypto_binding_tlv *rbind,
00609         struct eap_tlv_crypto_binding_tlv *_bind, const u8 *cmk)
00610 {
00611         rbind->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
00612                                        EAP_TLV_CRYPTO_BINDING_TLV);
00613         rbind->length = host_to_be16(sizeof(*rbind) -
00614                                      sizeof(struct eap_tlv_hdr));
00615         rbind->version = EAP_FAST_VERSION;
00616         rbind->received_version = _bind->version;
00617         rbind->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE;
00618         os_memcpy(rbind->nonce, _bind->nonce, sizeof(_bind->nonce));
00619         inc_byte_array(rbind->nonce, sizeof(rbind->nonce));
00620         hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) rbind, sizeof(*rbind),
00621                   rbind->compound_mac);
00622 
00623         wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: Version %d "
00624                    "Received Version %d SubType %d",
00625                    rbind->version, rbind->received_version, rbind->subtype);
00626         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
00627                     rbind->nonce, sizeof(rbind->nonce));
00628         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
00629                     rbind->compound_mac, sizeof(rbind->compound_mac));
00630 }
00631 
00632 
00633 static int eap_fast_get_phase2_key(struct eap_sm *sm,
00634                                    struct eap_fast_data *data,
00635                                    u8 *isk, size_t isk_len)
00636 {
00637         u8 *key;
00638         size_t key_len;
00639 
00640         os_memset(isk, 0, isk_len);
00641 
00642         if (data->phase2_method == NULL || data->phase2_priv == NULL) {
00643                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
00644                            "available");
00645                 return -1;
00646         }
00647 
00648         if (data->phase2_method->isKeyAvailable == NULL ||
00649             data->phase2_method->getKey == NULL)
00650                 return 0;
00651 
00652         if (!data->phase2_method->isKeyAvailable(sm, data->phase2_priv) ||
00653             (key = data->phase2_method->getKey(sm, data->phase2_priv,
00654                                                &key_len)) == NULL) {
00655                 wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key material "
00656                            "from Phase 2");
00657                 return -1;
00658         }
00659 
00660         if (key_len > isk_len)
00661                 key_len = isk_len;
00662         if (key_len == 32 &&
00663             data->phase2_method->vendor == EAP_VENDOR_IETF &&
00664             data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
00665                 /*
00666                  * EAP-FAST uses reverse order for MS-MPPE keys when deriving
00667                  * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
00668                  * ISK for EAP-FAST cryptobinding.
00669                  */
00670                 os_memcpy(isk, key + 16, 16);
00671                 os_memcpy(isk + 16, key, 16);
00672         } else
00673                 os_memcpy(isk, key, key_len);
00674         os_free(key);
00675 
00676         return 0;
00677 }
00678 
00679 
00680 static int eap_fast_get_cmk(struct eap_sm *sm, struct eap_fast_data *data,
00681                             u8 *cmk)
00682 {
00683         u8 isk[32], imck[60];
00684 
00685         wpa_printf(MSG_DEBUG, "EAP-FAST: Determining CMK[%d] for Compound MIC "
00686                    "calculation", data->simck_idx + 1);
00687 
00688         /*
00689          * RFC 4851, Section 5.2:
00690          * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
00691          *                 MSK[j], 60)
00692          * S-IMCK[j] = first 40 octets of IMCK[j]
00693          * CMK[j] = last 20 octets of IMCK[j]
00694          */
00695 
00696         if (eap_fast_get_phase2_key(sm, data, isk, sizeof(isk)) < 0)
00697                 return -1;
00698         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk));
00699         sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
00700                    "Inner Methods Compound Keys",
00701                    isk, sizeof(isk), imck, sizeof(imck));
00702         data->simck_idx++;
00703         os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN);
00704         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]",
00705                         data->simck, EAP_FAST_SIMCK_LEN);
00706         os_memcpy(cmk, imck + EAP_FAST_SIMCK_LEN, EAP_FAST_CMK_LEN);
00707         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]",
00708                         cmk, EAP_FAST_CMK_LEN);
00709 
00710         return 0;
00711 }
00712 
00713 
00714 static u8 * eap_fast_write_pac_request(u8 *pos, u16 pac_type)
00715 {
00716         struct eap_tlv_hdr *pac;
00717         struct eap_tlv_request_action_tlv *act;
00718         struct eap_tlv_pac_type_tlv *type;
00719 
00720         act = (struct eap_tlv_request_action_tlv *) pos;
00721         act->tlv_type = host_to_be16(EAP_TLV_REQUEST_ACTION_TLV);
00722         act->length = host_to_be16(2);
00723         act->action = host_to_be16(EAP_TLV_ACTION_PROCESS_TLV);
00724 
00725         pac = (struct eap_tlv_hdr *) (act + 1);
00726         pac->tlv_type = host_to_be16(EAP_TLV_PAC_TLV);
00727         pac->length = host_to_be16(sizeof(*type));
00728 
00729         type = (struct eap_tlv_pac_type_tlv *) (pac + 1);
00730         type->tlv_type = host_to_be16(PAC_TYPE_PAC_TYPE);
00731         type->length = host_to_be16(2);
00732         type->pac_type = host_to_be16(pac_type);
00733 
00734         return (u8 *) (type + 1);
00735 }
00736 
00737 
00738 static struct wpabuf * eap_fast_process_crypto_binding(
00739         struct eap_sm *sm, struct eap_fast_data *data,
00740         struct eap_method_ret *ret,
00741         struct eap_tlv_crypto_binding_tlv *_bind, size_t bind_len)
00742 {
00743         struct wpabuf *resp;
00744         u8 *pos;
00745         u8 cmk[EAP_FAST_CMK_LEN], cmac[SHA1_MAC_LEN];
00746         int res;
00747         size_t len;
00748 
00749         if (eap_fast_validate_crypto_binding(_bind) < 0)
00750                 return NULL;
00751 
00752         if (eap_fast_get_cmk(sm, data, cmk) < 0)
00753                 return NULL;
00754 
00755         /* Validate received Compound MAC */
00756         os_memcpy(cmac, _bind->compound_mac, sizeof(cmac));
00757         os_memset(_bind->compound_mac, 0, sizeof(cmac));
00758         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for Compound "
00759                     "MAC calculation", (u8 *) _bind, bind_len);
00760         hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) _bind, bind_len,
00761                   _bind->compound_mac);
00762         res = os_memcmp(cmac, _bind->compound_mac, sizeof(cmac));
00763         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Received Compound MAC",
00764                     cmac, sizeof(cmac));
00765         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC",
00766                     _bind->compound_mac, sizeof(cmac));
00767         if (res != 0) {
00768                 wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match");
00769                 os_memcpy(_bind->compound_mac, cmac, sizeof(cmac));
00770                 return NULL;
00771         }
00772 
00773         /*
00774          * Compound MAC was valid, so authentication succeeded. Reply with
00775          * crypto binding to allow server to complete authentication.
00776          */
00777 
00778         len = sizeof(struct eap_tlv_crypto_binding_tlv);
00779         resp = wpabuf_alloc(len);
00780         if (resp == NULL)
00781                 return NULL;
00782 
00783         if (!data->anon_provisioning && data->phase2_success &&
00784             eap_fast_derive_msk(data) < 0) {
00785                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to generate MSK");
00786                 ret->methodState = METHOD_DONE;
00787                 ret->decision = DECISION_FAIL;
00788                 data->phase2_success = 0;
00789                 wpabuf_free(resp);
00790                 return NULL;
00791         }
00792 
00793         pos = wpabuf_put(resp, sizeof(struct eap_tlv_crypto_binding_tlv));
00794         eap_fast_write_crypto_binding((struct eap_tlv_crypto_binding_tlv *)
00795                                       pos, _bind, cmk);
00796 
00797         return resp;
00798 }
00799 
00800 
00801 static void eap_fast_parse_pac_tlv(struct eap_fast_pac *entry, int type,
00802                                    u8 *pos, size_t len, int *pac_key_found)
00803 {
00804         switch (type & 0x7fff) {
00805         case PAC_TYPE_PAC_KEY:
00806                 wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key", pos, len);
00807                 if (len != EAP_FAST_PAC_KEY_LEN) {
00808                         wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid PAC-Key "
00809                                    "length %lu", (unsigned long) len);
00810                         break;
00811                 }
00812                 *pac_key_found = 1;
00813                 os_memcpy(entry->pac_key, pos, len);
00814                 break;
00815         case PAC_TYPE_PAC_OPAQUE:
00816                 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque", pos, len);
00817                 entry->pac_opaque = pos;
00818                 entry->pac_opaque_len = len;
00819                 break;
00820         case PAC_TYPE_PAC_INFO:
00821                 wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info", pos, len);
00822                 entry->pac_info = pos;
00823                 entry->pac_info_len = len;
00824                 break;
00825         default:
00826                 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC type %d",
00827                            type);
00828                 break;
00829         }
00830 }
00831 
00832 
00833 static int eap_fast_process_pac_tlv(struct eap_fast_pac *entry,
00834                                     u8 *pac, size_t pac_len)
00835 {
00836         struct pac_tlv_hdr *hdr;
00837         u8 *pos;
00838         size_t left, len;
00839         int type, pac_key_found = 0;
00840 
00841         pos = pac;
00842         left = pac_len;
00843 
00844         while (left > sizeof(*hdr)) {
00845                 hdr = (struct pac_tlv_hdr *) pos;
00846                 type = be_to_host16(hdr->type);
00847                 len = be_to_host16(hdr->len);
00848                 pos += sizeof(*hdr);
00849                 left -= sizeof(*hdr);
00850                 if (len > left) {
00851                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV overrun "
00852                                    "(type=%d len=%lu left=%lu)",
00853                                    type, (unsigned long) len,
00854                                    (unsigned long) left);
00855                         return -1;
00856                 }
00857 
00858                 eap_fast_parse_pac_tlv(entry, type, pos, len, &pac_key_found);
00859 
00860                 pos += len;
00861                 left -= len;
00862         }
00863 
00864         if (!pac_key_found || !entry->pac_opaque || !entry->pac_info) {
00865                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV does not include "
00866                            "all the required fields");
00867                 return -1;
00868         }
00869 
00870         return 0;
00871 }
00872 
00873 
00874 static int eap_fast_parse_pac_info(struct eap_fast_pac *entry, int type,
00875                                    u8 *pos, size_t len)
00876 {
00877         u16 pac_type;
00878         u32 lifetime;
00879         struct os_time now;
00880 
00881         switch (type & 0x7fff) {
00882         case PAC_TYPE_CRED_LIFETIME:
00883                 if (len != 4) {
00884                         wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Info - "
00885                                     "Invalid CRED_LIFETIME length - ignored",
00886                                     pos, len);
00887                         return 0;
00888                 }
00889 
00890                 /*
00891                  * This is not currently saved separately in PAC files since
00892                  * the server can automatically initiate PAC update when
00893                  * needed. Anyway, the information is available from PAC-Info
00894                  * dump if it is needed for something in the future.
00895                  */
00896                 lifetime = WPA_GET_BE32(pos);
00897                 os_get_time(&now);
00898                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info - CRED_LIFETIME %d "
00899                            "(%d days)",
00900                            lifetime, (lifetime - (u32) now.sec) / 86400);
00901                 break;
00902         case PAC_TYPE_A_ID:
00903                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - A-ID",
00904                                   pos, len);
00905                 entry->a_id = pos;
00906                 entry->a_id_len = len;
00907                 break;
00908         case PAC_TYPE_I_ID:
00909                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - I-ID",
00910                                   pos, len);
00911                 entry->i_id = pos;
00912                 entry->i_id_len = len;
00913                 break;
00914         case PAC_TYPE_A_ID_INFO:
00915                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: PAC-Info - A-ID-Info",
00916                                   pos, len);
00917                 entry->a_id_info = pos;
00918                 entry->a_id_info_len = len;
00919                 break;
00920         case PAC_TYPE_PAC_TYPE:
00921                 /* RFC 5422, Section 4.2.6 - PAC-Type TLV */
00922                 if (len != 2) {
00923                         wpa_printf(MSG_INFO, "EAP-FAST: Invalid PAC-Type "
00924                                    "length %lu (expected 2)",
00925                                    (unsigned long) len);
00926                         wpa_hexdump_ascii(MSG_DEBUG,
00927                                           "EAP-FAST: PAC-Info - PAC-Type",
00928                                           pos, len);
00929                         return -1;
00930                 }
00931                 pac_type = WPA_GET_BE16(pos);
00932                 if (pac_type != PAC_TYPE_TUNNEL_PAC &&
00933                     pac_type != PAC_TYPE_USER_AUTHORIZATION &&
00934                     pac_type != PAC_TYPE_MACHINE_AUTHENTICATION) {
00935                         wpa_printf(MSG_INFO, "EAP-FAST: Unsupported PAC Type "
00936                                    "%d", pac_type);
00937                         return -1;
00938                 }
00939 
00940                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info - PAC-Type %d",
00941                            pac_type);
00942                 entry->pac_type = pac_type;
00943                 break;
00944         default:
00945                 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored unknown PAC-Info "
00946                            "type %d", type);
00947                 break;
00948         }
00949 
00950         return 0;
00951 }
00952 
00953 
00954 static int eap_fast_process_pac_info(struct eap_fast_pac *entry)
00955 {
00956         struct pac_tlv_hdr *hdr;
00957         u8 *pos;
00958         size_t left, len;
00959         int type;
00960 
00961         /* RFC 5422, Section 4.2.4 */
00962 
00963         /* PAC-Type defaults to Tunnel PAC (Type 1) */
00964         entry->pac_type = PAC_TYPE_TUNNEL_PAC;
00965 
00966         pos = entry->pac_info;
00967         left = entry->pac_info_len;
00968         while (left > sizeof(*hdr)) {
00969                 hdr = (struct pac_tlv_hdr *) pos;
00970                 type = be_to_host16(hdr->type);
00971                 len = be_to_host16(hdr->len);
00972                 pos += sizeof(*hdr);
00973                 left -= sizeof(*hdr);
00974                 if (len > left) {
00975                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info overrun "
00976                                    "(type=%d len=%lu left=%lu)",
00977                                    type, (unsigned long) len,
00978                                    (unsigned long) left);
00979                         return -1;
00980                 }
00981 
00982                 if (eap_fast_parse_pac_info(entry, type, pos, len) < 0)
00983                         return -1;
00984 
00985                 pos += len;
00986                 left -= len;
00987         }
00988 
00989         if (entry->a_id == NULL || entry->a_id_info == NULL) {
00990                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Info does not include "
00991                            "all the required fields");
00992                 return -1;
00993         }
00994 
00995         return 0;
00996 }
00997 
00998 
00999 static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm,
01000                                             struct eap_fast_data *data,
01001                                             struct eap_method_ret *ret,
01002                                             u8 *pac, size_t pac_len)
01003 {
01004         struct eap_peer_config *config = eap_get_config(sm);
01005         struct eap_fast_pac entry;
01006 
01007         os_memset(&entry, 0, sizeof(entry));
01008         if (eap_fast_process_pac_tlv(&entry, pac, pac_len) ||
01009             eap_fast_process_pac_info(&entry))
01010                 return NULL;
01011 
01012         eap_fast_add_pac(&data->pac, &data->current_pac, &entry);
01013         eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len);
01014         if (data->use_pac_binary_format)
01015                 eap_fast_save_pac_bin(sm, data->pac, config->pac_file);
01016         else
01017                 eap_fast_save_pac(sm, data->pac, config->pac_file);
01018 
01019         if (data->provisioning) {
01020                 if (data->anon_provisioning) {
01021                         /*
01022                          * Unauthenticated provisioning does not provide keying
01023                          * material and must end with an EAP-Failure.
01024                          * Authentication will be done separately after this.
01025                          */
01026                         data->success = 0;
01027                         ret->decision = DECISION_FAIL;
01028                 } else {
01029                         /*
01030                          * Server may or may not allow authenticated
01031                          * provisioning also for key generation.
01032                          */
01033                         ret->decision = DECISION_COND_SUCC;
01034                 }
01035                 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
01036                            "- Provisioning completed successfully");
01037         } else {
01038                 /*
01039                  * This is PAC refreshing, i.e., normal authentication that is
01040                  * expected to be completed with an EAP-Success.
01041                  */
01042                 wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV "
01043                            "- PAC refreshing completed successfully");
01044                 ret->decision = DECISION_UNCOND_SUCC;
01045         }
01046         ret->methodState = METHOD_DONE;
01047         return eap_fast_tlv_pac_ack();
01048 }
01049 
01050 
01051 static int eap_fast_parse_decrypted(struct wpabuf *decrypted,
01052                                     struct eap_fast_tlv_parse *tlv,
01053                                     struct wpabuf **resp)
01054 {
01055         int mandatory, tlv_type, len, res;
01056         u8 *pos, *end;
01057 
01058         os_memset(tlv, 0, sizeof(*tlv));
01059 
01060         /* Parse TLVs from the decrypted Phase 2 data */
01061         pos = wpabuf_mhead(decrypted);
01062         end = pos + wpabuf_len(decrypted);
01063         while (pos + 4 < end) {
01064                 mandatory = pos[0] & 0x80;
01065                 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
01066                 pos += 2;
01067                 len = WPA_GET_BE16(pos);
01068                 pos += 2;
01069                 if (pos + len > end) {
01070                         wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
01071                         return -1;
01072                 }
01073                 wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: "
01074                            "TLV type %d length %d%s",
01075                            tlv_type, len, mandatory ? " (mandatory)" : "");
01076 
01077                 res = eap_fast_parse_tlv(tlv, tlv_type, pos, len);
01078                 if (res == -2)
01079                         break;
01080                 if (res < 0) {
01081                         if (mandatory) {
01082                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
01083                                            "mandatory TLV type %d", tlv_type);
01084                                 *resp = eap_fast_tlv_nak(0, tlv_type);
01085                                 break;
01086                         } else {
01087                                 wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "
01088                                            "unknown optional TLV type %d",
01089                                            tlv_type);
01090                         }
01091                 }
01092 
01093                 pos += len;
01094         }
01095 
01096         return 0;
01097 }
01098 
01099 
01100 static int eap_fast_encrypt_response(struct eap_sm *sm,
01101                                      struct eap_fast_data *data,
01102                                      struct wpabuf *resp,
01103                                      u8 identifier, struct wpabuf **out_data)
01104 {
01105         if (resp == NULL)
01106                 return 0;
01107 
01108         wpa_hexdump_buf(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
01109                         resp);
01110         if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,
01111                                  data->fast_version, identifier,
01112                                  resp, out_data)) {
01113                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
01114                            "frame");
01115         }
01116         wpabuf_free(resp);
01117 
01118         return 0;
01119 }
01120 
01121 
01122 static struct wpabuf * eap_fast_pac_request(void)
01123 {
01124         struct wpabuf *tmp;
01125         u8 *pos, *pos2;
01126 
01127         tmp = wpabuf_alloc(sizeof(struct eap_tlv_hdr) +
01128                            sizeof(struct eap_tlv_request_action_tlv) +
01129                            sizeof(struct eap_tlv_pac_type_tlv));
01130         if (tmp == NULL)
01131                 return NULL;
01132 
01133         pos = wpabuf_put(tmp, 0);
01134         pos2 = eap_fast_write_pac_request(pos, PAC_TYPE_TUNNEL_PAC);
01135         wpabuf_put(tmp, pos2 - pos);
01136         return tmp;
01137 }
01138 
01139 
01140 static int eap_fast_process_decrypted(struct eap_sm *sm,
01141                                       struct eap_fast_data *data,
01142                                       struct eap_method_ret *ret,
01143                                       const struct eap_hdr *req,
01144                                       struct wpabuf *decrypted,
01145                                       struct wpabuf **out_data)
01146 {
01147         struct wpabuf *resp = NULL, *tmp;
01148         struct eap_fast_tlv_parse tlv;
01149         int failed = 0;
01150 
01151         if (eap_fast_parse_decrypted(decrypted, &tlv, &resp) < 0)
01152                 return 0;
01153         if (resp)
01154                 return eap_fast_encrypt_response(sm, data, resp,
01155                                                  req->identifier, out_data);
01156 
01157         if (tlv.result == EAP_TLV_RESULT_FAILURE) {
01158                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
01159                 return eap_fast_encrypt_response(sm, data, resp,
01160                                                  req->identifier, out_data);
01161         }
01162 
01163         if (tlv.iresult == EAP_TLV_RESULT_FAILURE) {
01164                 resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);
01165                 return eap_fast_encrypt_response(sm, data, resp,
01166                                                  req->identifier, out_data);
01167         }
01168 
01169         if (tlv.crypto_binding) {
01170                 tmp = eap_fast_process_crypto_binding(sm, data, ret,
01171                                                       tlv.crypto_binding,
01172                                                       tlv.crypto_binding_len);
01173                 if (tmp == NULL)
01174                         failed = 1;
01175                 else
01176                         resp = wpabuf_concat(resp, tmp);
01177         }
01178 
01179         if (tlv.iresult == EAP_TLV_RESULT_SUCCESS) {
01180                 tmp = eap_fast_tlv_result(failed ? EAP_TLV_RESULT_FAILURE :
01181                                           EAP_TLV_RESULT_SUCCESS, 1);
01182                 resp = wpabuf_concat(resp, tmp);
01183         }
01184 
01185         if (tlv.eap_payload_tlv) {
01186                 tmp = eap_fast_process_eap_payload_tlv(
01187                         sm, data, ret, req, tlv.eap_payload_tlv,
01188                         tlv.eap_payload_tlv_len);
01189                 resp = wpabuf_concat(resp, tmp);
01190         }
01191 
01192         if (tlv.pac && tlv.result != EAP_TLV_RESULT_SUCCESS) {
01193                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "
01194                            "acknowledging success");
01195                 failed = 1;
01196         } else if (tlv.pac && tlv.result == EAP_TLV_RESULT_SUCCESS) {
01197                 tmp = eap_fast_process_pac(sm, data, ret, tlv.pac,
01198                                            tlv.pac_len);
01199                 resp = wpabuf_concat(resp, tmp);
01200         }
01201 
01202         if (data->current_pac == NULL && data->provisioning &&
01203             !data->anon_provisioning && !tlv.pac &&
01204             (tlv.iresult == EAP_TLV_RESULT_SUCCESS ||
01205              tlv.result == EAP_TLV_RESULT_SUCCESS)) {
01206                 /*
01207                  * Need to request Tunnel PAC when using authenticated
01208                  * provisioning.
01209                  */
01210                 wpa_printf(MSG_DEBUG, "EAP-FAST: Request Tunnel PAC");
01211                 tmp = eap_fast_pac_request();
01212                 resp = wpabuf_concat(resp, tmp);
01213         }
01214 
01215         if (tlv.result == EAP_TLV_RESULT_SUCCESS && !failed) {
01216                 tmp = eap_fast_tlv_result(EAP_TLV_RESULT_SUCCESS, 0);
01217                 resp = wpabuf_concat(tmp, resp);
01218         } else if (failed) {
01219                 tmp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
01220                 resp = wpabuf_concat(tmp, resp);
01221         }
01222 
01223         if (resp && tlv.result == EAP_TLV_RESULT_SUCCESS && !failed &&
01224             tlv.crypto_binding && data->phase2_success) {
01225                 if (data->anon_provisioning) {
01226                         wpa_printf(MSG_DEBUG, "EAP-FAST: Unauthenticated "
01227                                    "provisioning completed successfully.");
01228                         ret->methodState = METHOD_DONE;
01229                         ret->decision = DECISION_FAIL;
01230                 } else {
01231                         wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "
01232                                    "completed successfully.");
01233                         if (data->provisioning)
01234                                 ret->methodState = METHOD_MAY_CONT;
01235                         else
01236                                 ret->methodState = METHOD_DONE;
01237                         ret->decision = DECISION_UNCOND_SUCC;
01238                 }
01239         }
01240 
01241         if (resp == NULL) {
01242                 wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "
01243                            "empty response packet");
01244                 resp = wpabuf_alloc(1);
01245         }
01246 
01247         return eap_fast_encrypt_response(sm, data, resp, req->identifier,
01248                                          out_data);
01249 }
01250 
01251 
01252 static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
01253                             struct eap_method_ret *ret,
01254                             const struct eap_hdr *req,
01255                             const struct wpabuf *in_data,
01256                             struct wpabuf **out_data)
01257 {
01258         struct wpabuf *in_decrypted;
01259         int res;
01260 
01261         wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"
01262                    " Phase 2", (unsigned long) wpabuf_len(in_data));
01263 
01264         if (data->pending_phase2_req) {
01265                 wpa_printf(MSG_DEBUG, "EAP-FAST: Pending Phase 2 request - "
01266                            "skip decryption and use old data");
01267                 /* Clear TLS reassembly state. */
01268                 eap_peer_tls_reset_input(&data->ssl);
01269 
01270                 in_decrypted = data->pending_phase2_req;
01271                 data->pending_phase2_req = NULL;
01272                 goto continue_req;
01273         }
01274 
01275         if (wpabuf_len(in_data) == 0) {
01276                 /* Received TLS ACK - requesting more fragments */
01277                 return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,
01278                                             data->fast_version,
01279                                             req->identifier, NULL, out_data);
01280         }
01281 
01282         res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
01283         if (res)
01284                 return res;
01285 
01286 continue_req:
01287         wpa_hexdump_buf(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
01288                         in_decrypted);
01289 
01290         if (wpabuf_len(in_decrypted) < 4) {
01291                 wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
01292                            "TLV frame (len=%lu)",
01293                            (unsigned long) wpabuf_len(in_decrypted));
01294                 wpabuf_free(in_decrypted);
01295                 return -1;
01296         }
01297 
01298         res = eap_fast_process_decrypted(sm, data, ret, req,
01299                                          in_decrypted, out_data);
01300 
01301         wpabuf_free(in_decrypted);
01302 
01303         return res;
01304 }
01305 
01306 
01307 static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len)
01308 {
01309         const u8 *a_id;
01310         struct pac_tlv_hdr *hdr;
01311 
01312         /*
01313          * Parse authority identity (A-ID) from the EAP-FAST/Start. This
01314          * supports both raw A-ID and one inside an A-ID TLV.
01315          */
01316         a_id = buf;
01317         *id_len = len;
01318         if (len > sizeof(*hdr)) {
01319                 int tlen;
01320                 hdr = (struct pac_tlv_hdr *) buf;
01321                 tlen = be_to_host16(hdr->len);
01322                 if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&
01323                     sizeof(*hdr) + tlen <= len) {
01324                         wpa_printf(MSG_DEBUG, "EAP-FAST: A-ID was in TLV "
01325                                    "(Start)");
01326                         a_id = (u8 *) (hdr + 1);
01327                         *id_len = tlen;
01328                 }
01329         }
01330         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: A-ID", a_id, *id_len);
01331 
01332         return a_id;
01333 }
01334 
01335 
01336 static void eap_fast_select_pac(struct eap_fast_data *data,
01337                                 const u8 *a_id, size_t a_id_len)
01338 {
01339         data->current_pac = eap_fast_get_pac(data->pac, a_id, a_id_len,
01340                                              PAC_TYPE_TUNNEL_PAC);
01341         if (data->current_pac == NULL) {
01342                 /*
01343                  * Tunnel PAC was not available for this A-ID. Try to use
01344                  * Machine Authentication PAC, if one is available.
01345                  */
01346                 data->current_pac = eap_fast_get_pac(
01347                         data->pac, a_id, a_id_len,
01348                         PAC_TYPE_MACHINE_AUTHENTICATION);
01349         }
01350 
01351         if (data->current_pac) {
01352                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC found for this A-ID "
01353                            "(PAC-Type %d)", data->current_pac->pac_type);
01354                 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-FAST: A-ID-Info",
01355                                   data->current_pac->a_id_info,
01356                                   data->current_pac->a_id_info_len);
01357         }
01358 }
01359 
01360 
01361 static int eap_fast_use_pac_opaque(struct eap_sm *sm,
01362                                    struct eap_fast_data *data,
01363                                    struct eap_fast_pac *pac)
01364 {
01365         u8 *tlv;
01366         size_t tlv_len, olen;
01367         struct eap_tlv_hdr *ehdr;
01368 
01369         olen = pac->pac_opaque_len;
01370         tlv_len = sizeof(*ehdr) + olen;
01371         tlv = os_malloc(tlv_len);
01372         if (tlv) {
01373                 ehdr = (struct eap_tlv_hdr *) tlv;
01374                 ehdr->tlv_type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
01375                 ehdr->length = host_to_be16(olen);
01376                 os_memcpy(ehdr + 1, pac->pac_opaque, olen);
01377         }
01378         if (tlv == NULL ||
01379             tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
01380                                             TLS_EXT_PAC_OPAQUE,
01381                                             tlv, tlv_len) < 0) {
01382                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to add PAC-Opaque TLS "
01383                            "extension");
01384                 os_free(tlv);
01385                 return -1;
01386         }
01387         os_free(tlv);
01388 
01389         return 0;
01390 }
01391 
01392 
01393 static int eap_fast_clear_pac_opaque_ext(struct eap_sm *sm,
01394                                          struct eap_fast_data *data)
01395 {
01396         if (tls_connection_client_hello_ext(sm->ssl_ctx, data->ssl.conn,
01397                                             TLS_EXT_PAC_OPAQUE, NULL, 0) < 0) {
01398                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to remove PAC-Opaque "
01399                            "TLS extension");
01400                 return -1;
01401         }
01402         return 0;
01403 }
01404 
01405 
01406 static int eap_fast_set_provisioning_ciphers(struct eap_sm *sm,
01407                                              struct eap_fast_data *data)
01408 {
01409         u8 ciphers[5];
01410         int count = 0;
01411 
01412         if (data->provisioning_allowed & EAP_FAST_PROV_UNAUTH) {
01413                 wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling unauthenticated "
01414                            "provisioning TLS cipher suites");
01415                 ciphers[count++] = TLS_CIPHER_ANON_DH_AES128_SHA;
01416         }
01417 
01418         if (data->provisioning_allowed & EAP_FAST_PROV_AUTH) {
01419                 wpa_printf(MSG_DEBUG, "EAP-FAST: Enabling authenticated "
01420                            "provisioning TLS cipher suites");
01421                 ciphers[count++] = TLS_CIPHER_RSA_DHE_AES128_SHA;
01422                 ciphers[count++] = TLS_CIPHER_AES128_SHA;
01423                 ciphers[count++] = TLS_CIPHER_RC4_SHA;
01424         }
01425 
01426         ciphers[count++] = TLS_CIPHER_NONE;
01427 
01428         if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn,
01429                                            ciphers)) {
01430                 wpa_printf(MSG_INFO, "EAP-FAST: Could not configure TLS "
01431                            "cipher suites for provisioning");
01432                 return -1;
01433         }
01434 
01435         return 0;
01436 }
01437 
01438 
01439 static int eap_fast_process_start(struct eap_sm *sm,
01440                                   struct eap_fast_data *data, u8 flags,
01441                                   const u8 *pos, size_t left)
01442 {
01443         const u8 *a_id;
01444         size_t a_id_len;
01445 
01446         /* EAP-FAST Version negotiation (section 3.1) */
01447         wpa_printf(MSG_DEBUG, "EAP-FAST: Start (server ver=%d, own ver=%d)",
01448                    flags & EAP_TLS_VERSION_MASK, data->fast_version);
01449         if ((flags & EAP_TLS_VERSION_MASK) < data->fast_version)
01450                 data->fast_version = flags & EAP_TLS_VERSION_MASK;
01451         wpa_printf(MSG_DEBUG, "EAP-FAST: Using FAST version %d",
01452                    data->fast_version);
01453 
01454         a_id = eap_fast_get_a_id(pos, left, &a_id_len);
01455         eap_fast_select_pac(data, a_id, a_id_len);
01456 
01457         if (data->resuming && data->current_pac) {
01458                 wpa_printf(MSG_DEBUG, "EAP-FAST: Trying to resume session - "
01459                            "do not add PAC-Opaque to TLS ClientHello");
01460                 if (eap_fast_clear_pac_opaque_ext(sm, data) < 0)
01461                         return -1;
01462         } else if (data->current_pac) {
01463                 /*
01464                  * PAC found for the A-ID and we are not resuming an old
01465                  * session, so add PAC-Opaque extension to ClientHello.
01466                  */
01467                 if (eap_fast_use_pac_opaque(sm, data, data->current_pac) < 0)
01468                         return -1;
01469         } else {
01470                 /* No PAC found, so we must provision one. */
01471                 if (!data->provisioning_allowed) {
01472                         wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found and "
01473                                    "provisioning disabled");
01474                         return -1;
01475                 }
01476                 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC found - "
01477                            "starting provisioning");
01478                 if (eap_fast_set_provisioning_ciphers(sm, data) < 0 ||
01479                     eap_fast_clear_pac_opaque_ext(sm, data) < 0)
01480                         return -1;
01481                 data->provisioning = 1;
01482         }
01483 
01484         return 0;
01485 }
01486 
01487 
01488 static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
01489                                         struct eap_method_ret *ret,
01490                                         const struct wpabuf *reqData)
01491 {
01492         const struct eap_hdr *req;
01493         size_t left;
01494         int res;
01495         u8 flags, id;
01496         struct wpabuf *resp;
01497         const u8 *pos;
01498         struct eap_fast_data *data = priv;
01499 
01500         pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
01501                                         reqData, &left, &flags);
01502         if (pos == NULL)
01503                 return NULL;
01504 
01505         req = wpabuf_head(reqData);
01506         id = req->identifier;
01507 
01508         if (flags & EAP_TLS_FLAGS_START) {
01509                 if (eap_fast_process_start(sm, data, flags, pos, left) < 0)
01510                         return NULL;
01511 
01512                 left = 0; /* A-ID is not used in further packet processing */
01513         }
01514 
01515         resp = NULL;
01516         if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01517             !data->resuming) {
01518                 /* Process tunneled (encrypted) phase 2 data. */
01519                 struct wpabuf msg;
01520                 wpabuf_set(&msg, pos, left);
01521                 res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp);
01522                 if (res < 0) {
01523                         ret->methodState = METHOD_DONE;
01524                         ret->decision = DECISION_FAIL;
01525                         /*
01526                          * Ack possible Alert that may have caused failure in
01527                          * decryption.
01528                          */
01529                         res = 1;
01530                 }
01531         } else {
01532                 /* Continue processing TLS handshake (phase 1). */
01533                 res = eap_peer_tls_process_helper(sm, &data->ssl,
01534                                                   EAP_TYPE_FAST,
01535                                                   data->fast_version, id, pos,
01536                                                   left, &resp);
01537 
01538                 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
01539                         char cipher[80];
01540                         wpa_printf(MSG_DEBUG,
01541                                    "EAP-FAST: TLS done, proceed to Phase 2");
01542                         if (data->provisioning &&
01543                             (!(data->provisioning_allowed &
01544                                EAP_FAST_PROV_AUTH) ||
01545                              tls_get_cipher(sm->ssl_ctx, data->ssl.conn,
01546                                             cipher, sizeof(cipher)) < 0 ||
01547                              os_strstr(cipher, "ADH-") ||
01548                              os_strstr(cipher, "anon"))) {
01549                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Using "
01550                                            "anonymous (unauthenticated) "
01551                                            "provisioning");
01552                                 data->anon_provisioning = 1;
01553                         } else
01554                                 data->anon_provisioning = 0;
01555                         data->resuming = 0;
01556                         eap_fast_derive_keys(sm, data);
01557                 }
01558 
01559                 if (res == 2) {
01560                         struct wpabuf msg;
01561                         /*
01562                          * Application data included in the handshake message.
01563                          */
01564                         wpabuf_free(data->pending_phase2_req);
01565                         data->pending_phase2_req = resp;
01566                         resp = NULL;
01567                         wpabuf_set(&msg, pos, left);
01568                         res = eap_fast_decrypt(sm, data, ret, req, &msg,
01569                                                &resp);
01570                 }
01571         }
01572 
01573         if (res == 1) {
01574                 wpabuf_free(resp);
01575                 return eap_peer_tls_build_ack(id, EAP_TYPE_FAST,
01576                                               data->fast_version);
01577         }
01578 
01579         return resp;
01580 }
01581 
01582 
01583 #if 0 /* FIX */
01584 static Boolean eap_fast_has_reauth_data(struct eap_sm *sm, void *priv)
01585 {
01586         struct eap_fast_data *data = priv;
01587         return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
01588 }
01589 
01590 
01591 static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
01592 {
01593         struct eap_fast_data *data = priv;
01594         os_free(data->key_block_p);
01595         data->key_block_p = NULL;
01596         wpabuf_free(data->pending_phase2_req);
01597         data->pending_phase2_req = NULL;
01598 }
01599 
01600 
01601 static void * eap_fast_init_for_reauth(struct eap_sm *sm, void *priv)
01602 {
01603         struct eap_fast_data *data = priv;
01604         if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
01605                 os_free(data);
01606                 return NULL;
01607         }
01608         if (data->phase2_priv && data->phase2_method &&
01609             data->phase2_method->init_for_reauth)
01610                 data->phase2_method->init_for_reauth(sm, data->phase2_priv);
01611         data->phase2_success = 0;
01612         data->resuming = 1;
01613         data->provisioning = 0;
01614         data->anon_provisioning = 0;
01615         data->simck_idx = 0;
01616         return priv;
01617 }
01618 #endif
01619 
01620 
01621 static int eap_fast_get_status(struct eap_sm *sm, void *priv, char *buf,
01622                                size_t buflen, int verbose)
01623 {
01624         struct eap_fast_data *data = priv;
01625         int len, ret;
01626 
01627         len = eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
01628         if (data->phase2_method) {
01629                 ret = os_snprintf(buf + len, buflen - len,
01630                                   "EAP-FAST Phase2 method=%s\n",
01631                                   data->phase2_method->name);
01632                 if (ret < 0 || (size_t) ret >= buflen - len)
01633                         return len;
01634                 len += ret;
01635         }
01636         return len;
01637 }
01638 
01639 
01640 static Boolean eap_fast_isKeyAvailable(struct eap_sm *sm, void *priv)
01641 {
01642         struct eap_fast_data *data = priv;
01643         return data->success;
01644 }
01645 
01646 
01647 static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
01648 {
01649         struct eap_fast_data *data = priv;
01650         u8 *key;
01651 
01652         if (!data->success)
01653                 return NULL;
01654 
01655         key = os_malloc(EAP_FAST_KEY_LEN);
01656         if (key == NULL)
01657                 return NULL;
01658 
01659         *len = EAP_FAST_KEY_LEN;
01660         os_memcpy(key, data->key_data, EAP_FAST_KEY_LEN);
01661 
01662         return key;
01663 }
01664 
01665 
01666 static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
01667 {
01668         struct eap_fast_data *data = priv;
01669         u8 *key;
01670 
01671         if (!data->success)
01672                 return NULL;
01673 
01674         key = os_malloc(EAP_EMSK_LEN);
01675         if (key == NULL)
01676                 return NULL;
01677 
01678         *len = EAP_EMSK_LEN;
01679         os_memcpy(key, data->emsk, EAP_EMSK_LEN);
01680 
01681         return key;
01682 }
01683 
01684 
01685 int eap_peer_fast_register(void)
01686 {
01687         struct eap_method *eap;
01688         int ret;
01689 
01690         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
01691                                     EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
01692         if (eap == NULL)
01693                 return -1;
01694 
01695         eap->init = eap_fast_init;
01696         eap->deinit = eap_fast_deinit;
01697         eap->process = eap_fast_process;
01698         eap->isKeyAvailable = eap_fast_isKeyAvailable;
01699         eap->getKey = eap_fast_getKey;
01700         eap->get_status = eap_fast_get_status;
01701 #if 0
01702         eap->has_reauth_data = eap_fast_has_reauth_data;
01703         eap->deinit_for_reauth = eap_fast_deinit_for_reauth;
01704         eap->init_for_reauth = eap_fast_init_for_reauth;
01705 #endif
01706         eap->get_emsk = eap_fast_get_emsk;
01707 
01708         ret = eap_peer_method_register(eap);
01709         if (ret)
01710                 eap_peer_method_free(eap);
01711         return ret;
01712 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34