eap_fast.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "aes_wrap.h"
00020 #include "sha1.h"
00021 #include "eap_i.h"
00022 #include "eap_tls_common.h"
00023 #include "tls.h"
00024 #include "eap_common/eap_tlv_common.h"
00025 #include "eap_common/eap_fast_common.h"
00026 
00027 
00028 static void eap_fast_reset(struct eap_sm *sm, void *priv);
00029 
00030 
00031 /* Private PAC-Opaque TLV types */
00032 #define PAC_OPAQUE_TYPE_PAD 0
00033 #define PAC_OPAQUE_TYPE_KEY 1
00034 #define PAC_OPAQUE_TYPE_LIFETIME 2
00035 #define PAC_OPAQUE_TYPE_IDENTITY 3
00036 
00037 struct eap_fast_data {
00038         struct eap_ssl_data ssl;
00039         enum {
00040                 START, PHASE1, PHASE2_START, PHASE2_ID, PHASE2_METHOD,
00041                 CRYPTO_BINDING, REQUEST_PAC, SUCCESS, FAILURE
00042         } state;
00043 
00044         int fast_version;
00045         const struct eap_method *phase2_method;
00046         void *phase2_priv;
00047         int force_version;
00048         int peer_version;
00049 
00050         u8 crypto_binding_nonce[32];
00051         int final_result;
00052 
00053         struct eap_fast_key_block_provisioning *key_block_p;
00054 
00055         u8 simck[EAP_FAST_SIMCK_LEN];
00056         u8 cmk[EAP_FAST_CMK_LEN];
00057         int simck_idx;
00058 
00059         u8 pac_opaque_encr[16];
00060         u8 *srv_id;
00061         size_t srv_id_len;
00062         char *srv_id_info;
00063 
00064         int anon_provisioning;
00065         int send_new_pac; /* server triggered re-keying of Tunnel PAC */
00066         struct wpabuf *pending_phase2_resp;
00067         u8 *identity; /* from PAC-Opaque */
00068         size_t identity_len;
00069         int eap_seq;
00070         int tnc_started;
00071 
00072         int pac_key_lifetime;
00073         int pac_key_refresh_time;
00074 };
00075 
00076 
00077 static const char * eap_fast_state_txt(int state)
00078 {
00079         switch (state) {
00080         case START:
00081                 return "START";
00082         case PHASE1:
00083                 return "PHASE1";
00084         case PHASE2_START:
00085                 return "PHASE2_START";
00086         case PHASE2_ID:
00087                 return "PHASE2_ID";
00088         case PHASE2_METHOD:
00089                 return "PHASE2_METHOD";
00090         case CRYPTO_BINDING:
00091                 return "CRYPTO_BINDING";
00092         case REQUEST_PAC:
00093                 return "REQUEST_PAC";
00094         case SUCCESS:
00095                 return "SUCCESS";
00096         case FAILURE:
00097                 return "FAILURE";
00098         default:
00099                 return "Unknown?!";
00100         }
00101 }
00102 
00103 
00104 static void eap_fast_state(struct eap_fast_data *data, int state)
00105 {
00106         wpa_printf(MSG_DEBUG, "EAP-FAST: %s -> %s",
00107                    eap_fast_state_txt(data->state),
00108                    eap_fast_state_txt(state));
00109         data->state = state;
00110 }
00111 
00112 
00113 static EapType eap_fast_req_failure(struct eap_sm *sm,
00114                                     struct eap_fast_data *data)
00115 {
00116         /* TODO: send Result TLV(FAILURE) */
00117         eap_fast_state(data, FAILURE);
00118         return EAP_TYPE_NONE;
00119 }
00120 
00121 
00122 static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
00123                                       const u8 *client_random,
00124                                       const u8 *server_random,
00125                                       u8 *master_secret)
00126 {
00127         struct eap_fast_data *data = ctx;
00128         const u8 *pac_opaque;
00129         size_t pac_opaque_len;
00130         u8 *buf, *pos, *end, *pac_key = NULL;
00131         os_time_t lifetime = 0;
00132         struct os_time now;
00133         u8 *identity = NULL;
00134         size_t identity_len = 0;
00135 
00136         wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback");
00137         wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket (PAC-Opaque)",
00138                     ticket, len);
00139 
00140         if (len < 4 || WPA_GET_BE16(ticket) != PAC_TYPE_PAC_OPAQUE) {
00141                 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid "
00142                            "SessionTicket");
00143                 return 0;
00144         }
00145 
00146         pac_opaque_len = WPA_GET_BE16(ticket + 2);
00147         pac_opaque = ticket + 4;
00148         if (pac_opaque_len < 8 || pac_opaque_len % 8 ||
00149             pac_opaque_len > len - 4) {
00150                 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignore invalid PAC-Opaque "
00151                            "(len=%lu left=%lu)",
00152                            (unsigned long) pac_opaque_len,
00153                            (unsigned long) len);
00154                 return 0;
00155         }
00156         wpa_hexdump(MSG_DEBUG, "EAP-FAST: Received PAC-Opaque",
00157                     pac_opaque, pac_opaque_len);
00158 
00159         buf = os_malloc(pac_opaque_len - 8);
00160         if (buf == NULL) {
00161                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
00162                            "for decrypting PAC-Opaque");
00163                 return 0;
00164         }
00165 
00166         if (aes_unwrap(data->pac_opaque_encr, (pac_opaque_len - 8) / 8,
00167                        pac_opaque, buf) < 0) {
00168                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to decrypt "
00169                            "PAC-Opaque");
00170                 os_free(buf);
00171                 /*
00172                  * This may have been caused by server changing the PAC-Opaque
00173                  * encryption key, so just ignore this PAC-Opaque instead of
00174                  * failing the authentication completely. Provisioning can now
00175                  * be used to provision a new PAC.
00176                  */
00177                 return 0;
00178         }
00179 
00180         end = buf + pac_opaque_len - 8;
00181         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Decrypted PAC-Opaque",
00182                         buf, end - buf);
00183 
00184         pos = buf;
00185         while (pos + 1 < end) {
00186                 if (pos + 2 + pos[1] > end)
00187                         break;
00188 
00189                 switch (*pos) {
00190                 case PAC_OPAQUE_TYPE_PAD:
00191                         pos = end;
00192                         break;
00193                 case PAC_OPAQUE_TYPE_KEY:
00194                         if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
00195                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
00196                                            "PAC-Key length %d", pos[1]);
00197                                 os_free(buf);
00198                                 return -1;
00199                         }
00200                         pac_key = pos + 2;
00201                         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
00202                                         "decrypted PAC-Opaque",
00203                                         pac_key, EAP_FAST_PAC_KEY_LEN);
00204                         break;
00205                 case PAC_OPAQUE_TYPE_LIFETIME:
00206                         if (pos[1] != 4) {
00207                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
00208                                            "PAC-Key lifetime length %d",
00209                                            pos[1]);
00210                                 os_free(buf);
00211                                 return -1;
00212                         }
00213                         lifetime = WPA_GET_BE32(pos + 2);
00214                         break;
00215                 case PAC_OPAQUE_TYPE_IDENTITY:
00216                         identity = pos + 2;
00217                         identity_len = pos[1];
00218                         break;
00219                 }
00220 
00221                 pos += 2 + pos[1];
00222         }
00223 
00224         if (pac_key == NULL) {
00225                 wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key included in "
00226                            "PAC-Opaque");
00227                 os_free(buf);
00228                 return -1;
00229         }
00230 
00231         if (identity) {
00232                 wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Identity from "
00233                                   "PAC-Opaque", identity, identity_len);
00234                 os_free(data->identity);
00235                 data->identity = os_malloc(identity_len);
00236                 if (data->identity) {
00237                         os_memcpy(data->identity, identity, identity_len);
00238                         data->identity_len = identity_len;
00239                 }
00240         }
00241 
00242         if (os_get_time(&now) < 0 || lifetime <= 0 || now.sec > lifetime) {
00243                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key not valid anymore "
00244                            "(lifetime=%ld now=%ld)", lifetime, now.sec);
00245                 data->send_new_pac = 2;
00246                 /*
00247                  * Allow PAC to be used to allow a PAC update with some level
00248                  * of server authentication (i.e., do not fall back to full TLS
00249                  * handshake since we cannot be sure that the peer would be
00250                  * able to validate server certificate now). However, reject
00251                  * the authentication since the PAC was not valid anymore. Peer
00252                  * can connect again with the newly provisioned PAC after this.
00253                  */
00254         } else if (lifetime - now.sec < data->pac_key_refresh_time) {
00255                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Key soft timeout; send "
00256                            "an update if authentication succeeds");
00257                 data->send_new_pac = 1;
00258         }
00259 
00260         eap_fast_derive_master_secret(pac_key, server_random, client_random,
00261                                       master_secret);
00262 
00263         os_free(buf);
00264 
00265         return 1;
00266 }
00267 
00268 
00269 static void eap_fast_derive_key_auth(struct eap_sm *sm,
00270                                      struct eap_fast_data *data)
00271 {
00272         u8 *sks;
00273 
00274         /* RFC 4851, Section 5.1:
00275          * Extra key material after TLS key_block: session_key_seed[40]
00276          */
00277 
00278         sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion",
00279                                   EAP_FAST_SKS_LEN);
00280         if (sks == NULL) {
00281                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
00282                            "session_key_seed");
00283                 return;
00284         }
00285 
00286         /*
00287          * RFC 4851, Section 5.2:
00288          * S-IMCK[0] = session_key_seed
00289          */
00290         wpa_hexdump_key(MSG_DEBUG,
00291                         "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
00292                         sks, EAP_FAST_SKS_LEN);
00293         data->simck_idx = 0;
00294         os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
00295         os_free(sks);
00296 }
00297 
00298 
00299 static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
00300                                              struct eap_fast_data *data)
00301 {
00302         os_free(data->key_block_p);
00303         data->key_block_p = (struct eap_fast_key_block_provisioning *)
00304                 eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
00305                                     "key expansion",
00306                                     sizeof(*data->key_block_p));
00307         if (data->key_block_p == NULL) {
00308                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
00309                 return;
00310         }
00311         /*
00312          * RFC 4851, Section 5.2:
00313          * S-IMCK[0] = session_key_seed
00314          */
00315         wpa_hexdump_key(MSG_DEBUG,
00316                         "EAP-FAST: session_key_seed (SKS = S-IMCK[0])",
00317                         data->key_block_p->session_key_seed,
00318                         sizeof(data->key_block_p->session_key_seed));
00319         data->simck_idx = 0;
00320         os_memcpy(data->simck, data->key_block_p->session_key_seed,
00321                   EAP_FAST_SIMCK_LEN);
00322         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: server_challenge",
00323                         data->key_block_p->server_challenge,
00324                         sizeof(data->key_block_p->server_challenge));
00325         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
00326                         data->key_block_p->client_challenge,
00327                         sizeof(data->key_block_p->client_challenge));
00328 }
00329 
00330 
00331 static int eap_fast_get_phase2_key(struct eap_sm *sm,
00332                                    struct eap_fast_data *data,
00333                                    u8 *isk, size_t isk_len)
00334 {
00335         u8 *key;
00336         size_t key_len;
00337 
00338         os_memset(isk, 0, isk_len);
00339 
00340         if (data->phase2_method == NULL || data->phase2_priv == NULL) {
00341                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
00342                            "available");
00343                 return -1;
00344         }
00345 
00346         if (data->phase2_method->getKey == NULL)
00347                 return 0;
00348 
00349         if ((key = data->phase2_method->getKey(sm, data->phase2_priv,
00350                                                &key_len)) == NULL) {
00351                 wpa_printf(MSG_DEBUG, "EAP-FAST: Could not get key material "
00352                            "from Phase 2");
00353                 return -1;
00354         }
00355 
00356         if (key_len > isk_len)
00357                 key_len = isk_len;
00358         if (key_len == 32 &&
00359             data->phase2_method->vendor == EAP_VENDOR_IETF &&
00360             data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
00361                 /*
00362                  * EAP-FAST uses reverse order for MS-MPPE keys when deriving
00363                  * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
00364                  * ISK for EAP-FAST cryptobinding.
00365                  */
00366                 os_memcpy(isk, key + 16, 16);
00367                 os_memcpy(isk + 16, key, 16);
00368         } else
00369                 os_memcpy(isk, key, key_len);
00370         os_free(key);
00371 
00372         return 0;
00373 }
00374 
00375 
00376 static int eap_fast_update_icmk(struct eap_sm *sm, struct eap_fast_data *data)
00377 {
00378         u8 isk[32], imck[60];
00379 
00380         wpa_printf(MSG_DEBUG, "EAP-FAST: Deriving ICMK[%d] (S-IMCK and CMK)",
00381                    data->simck_idx + 1);
00382 
00383         /*
00384          * RFC 4851, Section 5.2:
00385          * IMCK[j] = T-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
00386          *                 MSK[j], 60)
00387          * S-IMCK[j] = first 40 octets of IMCK[j]
00388          * CMK[j] = last 20 octets of IMCK[j]
00389          */
00390 
00391         if (eap_fast_get_phase2_key(sm, data, isk, sizeof(isk)) < 0)
00392                 return -1;
00393         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: ISK[j]", isk, sizeof(isk));
00394         sha1_t_prf(data->simck, EAP_FAST_SIMCK_LEN,
00395                    "Inner Methods Compound Keys",
00396                    isk, sizeof(isk), imck, sizeof(imck));
00397         data->simck_idx++;
00398         os_memcpy(data->simck, imck, EAP_FAST_SIMCK_LEN);
00399         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: S-IMCK[j]",
00400                         data->simck, EAP_FAST_SIMCK_LEN);
00401         os_memcpy(data->cmk, imck + EAP_FAST_SIMCK_LEN, EAP_FAST_CMK_LEN);
00402         wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: CMK[j]",
00403                         data->cmk, EAP_FAST_CMK_LEN);
00404 
00405         return 0;
00406 }
00407 
00408 
00409 static void * eap_fast_init(struct eap_sm *sm)
00410 {
00411         struct eap_fast_data *data;
00412         u8 ciphers[5] = {
00413                 TLS_CIPHER_ANON_DH_AES128_SHA,
00414                 TLS_CIPHER_AES128_SHA,
00415                 TLS_CIPHER_RSA_DHE_AES128_SHA,
00416                 TLS_CIPHER_RC4_SHA,
00417                 TLS_CIPHER_NONE
00418         };
00419 
00420         data = os_zalloc(sizeof(*data));
00421         if (data == NULL)
00422                 return NULL;
00423         data->fast_version = EAP_FAST_VERSION;
00424         data->force_version = -1;
00425         if (sm->user && sm->user->force_version >= 0) {
00426                 data->force_version = sm->user->force_version;
00427                 wpa_printf(MSG_DEBUG, "EAP-FAST: forcing version %d",
00428                            data->force_version);
00429                 data->fast_version = data->force_version;
00430         }
00431         data->state = START;
00432 
00433         if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
00434                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL.");
00435                 eap_fast_reset(sm, data);
00436                 return NULL;
00437         }
00438 
00439         if (tls_connection_set_cipher_list(sm->ssl_ctx, data->ssl.conn,
00440                                            ciphers) < 0) {
00441                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to set TLS cipher "
00442                            "suites");
00443                 eap_fast_reset(sm, data);
00444                 return NULL;
00445         }
00446 
00447         if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
00448                                                  eap_fast_session_ticket_cb,
00449                                                  data) < 0) {
00450                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket "
00451                            "callback");
00452                 eap_fast_reset(sm, data);
00453                 return NULL;
00454         }
00455 
00456         if (sm->pac_opaque_encr_key == NULL) {
00457                 wpa_printf(MSG_INFO, "EAP-FAST: No PAC-Opaque encryption key "
00458                            "configured");
00459                 eap_fast_reset(sm, data);
00460                 return NULL;
00461         }
00462         os_memcpy(data->pac_opaque_encr, sm->pac_opaque_encr_key,
00463                   sizeof(data->pac_opaque_encr));
00464 
00465         if (sm->eap_fast_a_id == NULL) {
00466                 wpa_printf(MSG_INFO, "EAP-FAST: No A-ID configured");
00467                 eap_fast_reset(sm, data);
00468                 return NULL;
00469         }
00470         data->srv_id = os_malloc(sm->eap_fast_a_id_len);
00471         if (data->srv_id == NULL) {
00472                 eap_fast_reset(sm, data);
00473                 return NULL;
00474         }
00475         os_memcpy(data->srv_id, sm->eap_fast_a_id, sm->eap_fast_a_id_len);
00476         data->srv_id_len = sm->eap_fast_a_id_len;
00477 
00478         if (sm->eap_fast_a_id_info == NULL) {
00479                 wpa_printf(MSG_INFO, "EAP-FAST: No A-ID-Info configured");
00480                 eap_fast_reset(sm, data);
00481                 return NULL;
00482         }
00483         data->srv_id_info = os_strdup(sm->eap_fast_a_id_info);
00484         if (data->srv_id_info == NULL) {
00485                 eap_fast_reset(sm, data);
00486                 return NULL;
00487         }
00488 
00489         /* PAC-Key lifetime in seconds (hard limit) */
00490         data->pac_key_lifetime = sm->pac_key_lifetime;
00491 
00492         /*
00493          * PAC-Key refresh time in seconds (soft limit on remaining hard
00494          * limit). The server will generate a new PAC-Key when this number of
00495          * seconds (or fewer) of the lifetime remains.
00496          */
00497         data->pac_key_refresh_time = sm->pac_key_refresh_time;
00498 
00499         return data;
00500 }
00501 
00502 
00503 static void eap_fast_reset(struct eap_sm *sm, void *priv)
00504 {
00505         struct eap_fast_data *data = priv;
00506         if (data == NULL)
00507                 return;
00508         if (data->phase2_priv && data->phase2_method)
00509                 data->phase2_method->reset(sm, data->phase2_priv);
00510         eap_server_tls_ssl_deinit(sm, &data->ssl);
00511         os_free(data->srv_id);
00512         os_free(data->srv_id_info);
00513         os_free(data->key_block_p);
00514         wpabuf_free(data->pending_phase2_resp);
00515         os_free(data->identity);
00516         os_free(data);
00517 }
00518 
00519 
00520 static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
00521                                             struct eap_fast_data *data, u8 id)
00522 {
00523         struct wpabuf *req;
00524 
00525         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
00526                             1 + sizeof(struct pac_tlv_hdr) + data->srv_id_len,
00527                             EAP_CODE_REQUEST, id);
00528         if (req == NULL) {
00529                 wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
00530                            " request");
00531                 eap_fast_state(data, FAILURE);
00532                 return NULL;
00533         }
00534 
00535         wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version);
00536 
00537         /* RFC 4851, 4.1.1. Authority ID Data */
00538         eap_fast_put_tlv(req, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
00539 
00540         eap_fast_state(data, PHASE1);
00541 
00542         return req;
00543 }
00544 
00545 
00546 static int eap_fast_phase1_done(struct eap_sm *sm, struct eap_fast_data *data)
00547 {
00548         char cipher[64];
00549 
00550         wpa_printf(MSG_DEBUG, "EAP-FAST: Phase1 done, starting Phase2");
00551 
00552         if (tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher))
00553             < 0) {
00554                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to get cipher "
00555                            "information");
00556                 eap_fast_state(data, FAILURE);
00557                 return -1;
00558         }
00559         data->anon_provisioning = os_strstr(cipher, "ADH") != NULL;
00560                     
00561         if (data->anon_provisioning) {
00562                 wpa_printf(MSG_DEBUG, "EAP-FAST: Anonymous provisioning");
00563                 eap_fast_derive_key_provisioning(sm, data);
00564         } else
00565                 eap_fast_derive_key_auth(sm, data);
00566 
00567         eap_fast_state(data, PHASE2_START);
00568 
00569         return 0;
00570 }
00571 
00572 
00573 static struct wpabuf * eap_fast_build_phase2_req(struct eap_sm *sm,
00574                                                  struct eap_fast_data *data,
00575                                                  u8 id)
00576 {
00577         struct wpabuf *req;
00578 
00579         if (data->phase2_priv == NULL) {
00580                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 method not "
00581                            "initialized");
00582                 return NULL;
00583         }
00584         req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
00585         if (req == NULL)
00586                 return NULL;
00587 
00588         wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-FAST: Phase 2 EAP-Request", req);
00589         return eap_fast_tlv_eap_payload(req);
00590 }
00591 
00592 
00593 static struct wpabuf * eap_fast_build_crypto_binding(
00594         struct eap_sm *sm, struct eap_fast_data *data)
00595 {
00596         struct wpabuf *buf;
00597         struct eap_tlv_result_tlv *result;
00598         struct eap_tlv_crypto_binding_tlv *binding;
00599 
00600         buf = wpabuf_alloc(2 * sizeof(*result) + sizeof(*binding));
00601         if (buf == NULL)
00602                 return NULL;
00603 
00604         if (data->send_new_pac || data->anon_provisioning ||
00605             data->phase2_method)
00606                 data->final_result = 0;
00607         else
00608                 data->final_result = 1;
00609 
00610         if (!data->final_result || data->eap_seq > 1) {
00611                 /* Intermediate-Result */
00612                 wpa_printf(MSG_DEBUG, "EAP-FAST: Add Intermediate-Result TLV "
00613                            "(status=SUCCESS)");
00614                 result = wpabuf_put(buf, sizeof(*result));
00615                 result->tlv_type = host_to_be16(
00616                         EAP_TLV_TYPE_MANDATORY |
00617                         EAP_TLV_INTERMEDIATE_RESULT_TLV);
00618                 result->length = host_to_be16(2);
00619                 result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
00620         }
00621 
00622         if (data->final_result) {
00623                 /* Result TLV */
00624                 wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV "
00625                            "(status=SUCCESS)");
00626                 result = wpabuf_put(buf, sizeof(*result));
00627                 result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
00628                                                 EAP_TLV_RESULT_TLV);
00629                 result->length = host_to_be16(2);
00630                 result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
00631         }
00632 
00633         /* Crypto-Binding TLV */
00634         binding = wpabuf_put(buf, sizeof(*binding));
00635         binding->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
00636                                          EAP_TLV_CRYPTO_BINDING_TLV);
00637         binding->length = host_to_be16(sizeof(*binding) -
00638                                        sizeof(struct eap_tlv_hdr));
00639         binding->version = EAP_FAST_VERSION;
00640         binding->received_version = data->peer_version;
00641         binding->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST;
00642         if (os_get_random(binding->nonce, sizeof(binding->nonce)) < 0) {
00643                 wpabuf_free(buf);
00644                 return NULL;
00645         }
00646 
00647         /*
00648          * RFC 4851, Section 4.2.8:
00649          * The nonce in a request MUST have its least significant bit set to 0.
00650          */
00651         binding->nonce[sizeof(binding->nonce) - 1] &= ~0x01;
00652 
00653         os_memcpy(data->crypto_binding_nonce, binding->nonce,
00654                   sizeof(binding->nonce));
00655 
00656         /*
00657          * RFC 4851, Section 5.3:
00658          * CMK = CMK[j]
00659          * Compound-MAC = HMAC-SHA1( CMK, Crypto-Binding TLV )
00660          */
00661 
00662         hmac_sha1(data->cmk, EAP_FAST_CMK_LEN,
00663                   (u8 *) binding, sizeof(*binding),
00664                   binding->compound_mac);
00665 
00666         wpa_printf(MSG_DEBUG, "EAP-FAST: Add Crypto-Binding TLV: Version %d "
00667                    "Received Version %d SubType %d",
00668                    binding->version, binding->received_version,
00669                    binding->subtype);
00670         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
00671                     binding->nonce, sizeof(binding->nonce));
00672         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
00673                     binding->compound_mac, sizeof(binding->compound_mac));
00674 
00675         return buf;
00676 }
00677 
00678 
00679 static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
00680                                           struct eap_fast_data *data)
00681 {
00682         u8 pac_key[EAP_FAST_PAC_KEY_LEN];
00683         u8 *pac_buf, *pac_opaque;
00684         struct wpabuf *buf;
00685         u8 *pos;
00686         size_t buf_len, srv_id_info_len, pac_len;
00687         struct eap_tlv_hdr *pac_tlv;
00688         struct pac_tlv_hdr *pac_info;
00689         struct eap_tlv_result_tlv *result;
00690         struct os_time now;
00691 
00692         if (os_get_random(pac_key, EAP_FAST_PAC_KEY_LEN) < 0 ||
00693             os_get_time(&now) < 0)
00694                 return NULL;
00695         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Generated PAC-Key",
00696                         pac_key, EAP_FAST_PAC_KEY_LEN);
00697 
00698         pac_len = (2 + EAP_FAST_PAC_KEY_LEN) + (2 + 4) +
00699                 (2 + sm->identity_len) + 8;
00700         pac_buf = os_malloc(pac_len);
00701         if (pac_buf == NULL)
00702                 return NULL;
00703 
00704         srv_id_info_len = os_strlen(data->srv_id_info);
00705 
00706         pos = pac_buf;
00707         *pos++ = PAC_OPAQUE_TYPE_KEY;
00708         *pos++ = EAP_FAST_PAC_KEY_LEN;
00709         os_memcpy(pos, pac_key, EAP_FAST_PAC_KEY_LEN);
00710         pos += EAP_FAST_PAC_KEY_LEN;
00711 
00712         *pos++ = PAC_OPAQUE_TYPE_LIFETIME;
00713         *pos++ = 4;
00714         WPA_PUT_BE32(pos, now.sec + data->pac_key_lifetime);
00715         pos += 4;
00716 
00717         if (sm->identity) {
00718                 *pos++ = PAC_OPAQUE_TYPE_IDENTITY;
00719                 *pos++ = sm->identity_len;
00720                 os_memcpy(pos, sm->identity, sm->identity_len);
00721                 pos += sm->identity_len;
00722         }
00723 
00724         pac_len = pos - pac_buf;
00725         while (pac_len % 8) {
00726                 *pos++ = PAC_OPAQUE_TYPE_PAD;
00727                 pac_len++;
00728         }
00729 
00730         pac_opaque = os_malloc(pac_len + 8);
00731         if (pac_opaque == NULL) {
00732                 os_free(pac_buf);
00733                 return NULL;
00734         }
00735         if (aes_wrap(data->pac_opaque_encr, pac_len / 8, pac_buf,
00736                      pac_opaque) < 0) {
00737                 os_free(pac_buf);
00738                 os_free(pac_opaque);
00739                 return NULL;
00740         }
00741         os_free(pac_buf);
00742 
00743         pac_len += 8;
00744         wpa_hexdump(MSG_DEBUG, "EAP-FAST: PAC-Opaque",
00745                     pac_opaque, pac_len);
00746 
00747         buf_len = sizeof(*pac_tlv) +
00748                 sizeof(struct pac_tlv_hdr) + EAP_FAST_PAC_KEY_LEN +
00749                 sizeof(struct pac_tlv_hdr) + pac_len +
00750                 data->srv_id_len + srv_id_info_len + 100 + sizeof(*result);
00751         buf = wpabuf_alloc(buf_len);
00752         if (buf == NULL) {
00753                 os_free(pac_opaque);
00754                 return NULL;
00755         }
00756 
00757         /* Result TLV */
00758         wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)");
00759         result = wpabuf_put(buf, sizeof(*result));
00760         WPA_PUT_BE16((u8 *) &result->tlv_type,
00761                      EAP_TLV_TYPE_MANDATORY | EAP_TLV_RESULT_TLV);
00762         WPA_PUT_BE16((u8 *) &result->length, 2);
00763         WPA_PUT_BE16((u8 *) &result->status, EAP_TLV_RESULT_SUCCESS);
00764 
00765         /* PAC TLV */
00766         wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV");
00767         pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
00768         pac_tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
00769                                          EAP_TLV_PAC_TLV);
00770 
00771         /* PAC-Key */
00772         eap_fast_put_tlv(buf, PAC_TYPE_PAC_KEY, pac_key, EAP_FAST_PAC_KEY_LEN);
00773 
00774         /* PAC-Opaque */
00775         eap_fast_put_tlv(buf, PAC_TYPE_PAC_OPAQUE, pac_opaque, pac_len);
00776         os_free(pac_opaque);
00777 
00778         /* PAC-Info */
00779         pac_info = wpabuf_put(buf, sizeof(*pac_info));
00780         pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
00781 
00782         /* PAC-Lifetime (inside PAC-Info) */
00783         eap_fast_put_tlv_hdr(buf, PAC_TYPE_CRED_LIFETIME, 4);
00784         wpabuf_put_be32(buf, now.sec + data->pac_key_lifetime);
00785 
00786         /* A-ID (inside PAC-Info) */
00787         eap_fast_put_tlv(buf, PAC_TYPE_A_ID, data->srv_id, data->srv_id_len);
00788         
00789         /* Note: headers may be misaligned after A-ID */
00790 
00791         /* A-ID-Info (inside PAC-Info) */
00792         eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
00793                          srv_id_info_len);
00794 
00795         /* PAC-Type (inside PAC-Info) */
00796         eap_fast_put_tlv_hdr(buf, PAC_TYPE_PAC_TYPE, 2);
00797         wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
00798 
00799         /* Update PAC-Info and PAC TLV Length fields */
00800         pos = wpabuf_put(buf, 0);
00801         pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
00802         pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));
00803 
00804         return buf;
00805 }
00806 
00807 
00808 static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
00809 {
00810         struct eap_fast_data *data = priv;
00811         struct wpabuf *req = NULL;
00812         struct wpabuf *encr;
00813 
00814         if (data->ssl.state == FRAG_ACK) {
00815                 return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
00816                                                 data->fast_version);
00817         }
00818 
00819         if (data->ssl.state == WAIT_FRAG_ACK) {
00820                 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
00821                                                 data->fast_version, id);
00822         }
00823 
00824         switch (data->state) {
00825         case START:
00826                 return eap_fast_build_start(sm, data, id);
00827         case PHASE1:
00828                 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
00829                         if (eap_fast_phase1_done(sm, data) < 0)
00830                                 return NULL;
00831                 }
00832                 break;
00833         case PHASE2_ID:
00834         case PHASE2_METHOD:
00835                 req = eap_fast_build_phase2_req(sm, data, id);
00836                 break;
00837         case CRYPTO_BINDING:
00838                 req = eap_fast_build_crypto_binding(sm, data);
00839                 if (data->phase2_method) {
00840                         /*
00841                          * Include the start of the next EAP method in the
00842                          * sequence in the same message with Crypto-Binding to
00843                          * save a round-trip.
00844                          */
00845                         struct wpabuf *eap;
00846                         eap = eap_fast_build_phase2_req(sm, data, id);
00847                         req = wpabuf_concat(req, eap);
00848                         eap_fast_state(data, PHASE2_METHOD);
00849                 }
00850                 break;
00851         case REQUEST_PAC:
00852                 req = eap_fast_build_pac(sm, data);
00853                 break;
00854         default:
00855                 wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
00856                            __func__, data->state);
00857                 return NULL;
00858         }
00859 
00860         if (req) {
00861                 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 "
00862                                     "TLVs", req);
00863                 encr = eap_server_tls_encrypt(sm, &data->ssl,
00864                                               wpabuf_mhead(req),
00865                                               wpabuf_len(req));
00866                 wpabuf_free(req);
00867 
00868                 wpabuf_free(data->ssl.out_buf);
00869                 data->ssl.out_used = 0;
00870                 data->ssl.out_buf = encr;
00871         }
00872 
00873         return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
00874                                         data->fast_version, id);
00875 }
00876 
00877 
00878 static Boolean eap_fast_check(struct eap_sm *sm, void *priv,
00879                               struct wpabuf *respData)
00880 {
00881         const u8 *pos;
00882         size_t len;
00883 
00884         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData, &len);
00885         if (pos == NULL || len < 1) {
00886                 wpa_printf(MSG_INFO, "EAP-FAST: Invalid frame");
00887                 return TRUE;
00888         }
00889 
00890         return FALSE;
00891 }
00892 
00893 
00894 static int eap_fast_phase2_init(struct eap_sm *sm, struct eap_fast_data *data,
00895                                 EapType eap_type)
00896 {
00897         if (data->phase2_priv && data->phase2_method) {
00898                 data->phase2_method->reset(sm, data->phase2_priv);
00899                 data->phase2_method = NULL;
00900                 data->phase2_priv = NULL;
00901         }
00902         data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
00903                                                         eap_type);
00904         if (!data->phase2_method)
00905                 return -1;
00906 
00907         if (data->key_block_p) {
00908                 sm->auth_challenge = data->key_block_p->server_challenge;
00909                 sm->peer_challenge = data->key_block_p->client_challenge;
00910         }
00911         sm->init_phase2 = 1;
00912         data->phase2_priv = data->phase2_method->init(sm);
00913         sm->init_phase2 = 0;
00914         sm->auth_challenge = NULL;
00915         sm->peer_challenge = NULL;
00916 
00917         return data->phase2_priv == NULL ? -1 : 0;
00918 }
00919 
00920 
00921 static void eap_fast_process_phase2_response(struct eap_sm *sm,
00922                                              struct eap_fast_data *data,
00923                                              u8 *in_data, size_t in_len)
00924 {
00925         u8 next_type = EAP_TYPE_NONE;
00926         struct eap_hdr *hdr;
00927         u8 *pos;
00928         size_t left;
00929         struct wpabuf buf;
00930         const struct eap_method *m = data->phase2_method;
00931         void *priv = data->phase2_priv;
00932 
00933         if (priv == NULL) {
00934                 wpa_printf(MSG_DEBUG, "EAP-FAST: %s - Phase2 not "
00935                            "initialized?!", __func__);
00936                 return;
00937         }
00938 
00939         hdr = (struct eap_hdr *) in_data;
00940         pos = (u8 *) (hdr + 1);
00941 
00942         if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
00943                 left = in_len - sizeof(*hdr);
00944                 wpa_hexdump(MSG_DEBUG, "EAP-FAST: Phase2 type Nak'ed; "
00945                             "allowed types", pos + 1, left - 1);
00946 #ifdef EAP_SERVER_TNC
00947                 if (m && m->vendor == EAP_VENDOR_IETF &&
00948                     m->method == EAP_TYPE_TNC) {
00949                         wpa_printf(MSG_DEBUG, "EAP-FAST: Peer Nak'ed required "
00950                                    "TNC negotiation");
00951                         next_type = eap_fast_req_failure(sm, data);
00952                         eap_fast_phase2_init(sm, data, next_type);
00953                         return;
00954                 }
00955 #endif /* EAP_SERVER_TNC */
00956                 eap_sm_process_nak(sm, pos + 1, left - 1);
00957                 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
00958                     sm->user->methods[sm->user_eap_method_index].method !=
00959                     EAP_TYPE_NONE) {
00960                         next_type = sm->user->methods[
00961                                 sm->user_eap_method_index++].method;
00962                         wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d",
00963                                    next_type);
00964                 } else {
00965                         next_type = eap_fast_req_failure(sm, data);
00966                 }
00967                 eap_fast_phase2_init(sm, data, next_type);
00968                 return;
00969         }
00970 
00971         wpabuf_set(&buf, in_data, in_len);
00972 
00973         if (m->check(sm, priv, &buf)) {
00974                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 check() asked to "
00975                            "ignore the packet");
00976                 next_type = eap_fast_req_failure(sm, data);
00977                 return;
00978         }
00979 
00980         m->process(sm, priv, &buf);
00981 
00982         if (!m->isDone(sm, priv))
00983                 return;
00984 
00985         if (!m->isSuccess(sm, priv)) {
00986                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method failed");
00987                 next_type = eap_fast_req_failure(sm, data);
00988                 eap_fast_phase2_init(sm, data, next_type);
00989                 return;
00990         }
00991 
00992         switch (data->state) {
00993         case PHASE2_ID:
00994                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
00995                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: Phase2 "
00996                                           "Identity not found in the user "
00997                                           "database",
00998                                           sm->identity, sm->identity_len);
00999                         next_type = eap_fast_req_failure(sm, data);
01000                         break;
01001                 }
01002 
01003                 eap_fast_state(data, PHASE2_METHOD);
01004                 if (data->anon_provisioning) {
01005                         /*
01006                          * Only EAP-MSCHAPv2 is allowed for anonymous
01007                          * provisioning.
01008                          */
01009                         next_type = EAP_TYPE_MSCHAPV2;
01010                         sm->user_eap_method_index = 0;
01011                 } else {
01012                         next_type = sm->user->methods[0].method;
01013                         sm->user_eap_method_index = 1;
01014                 }
01015                 wpa_printf(MSG_DEBUG, "EAP-FAST: try EAP type %d", next_type);
01016                 break;
01017         case PHASE2_METHOD:
01018         case CRYPTO_BINDING:
01019                 eap_fast_update_icmk(sm, data);
01020                 eap_fast_state(data, CRYPTO_BINDING);
01021                 data->eap_seq++;
01022                 next_type = EAP_TYPE_NONE;
01023 #ifdef EAP_SERVER_TNC
01024                 if (sm->tnc && !data->tnc_started) {
01025                         wpa_printf(MSG_DEBUG, "EAP-FAST: Initialize TNC");
01026                         next_type = EAP_TYPE_TNC;
01027                         data->tnc_started = 1;
01028                 }
01029 #endif /* EAP_SERVER_TNC */
01030                 break;
01031         case FAILURE:
01032                 break;
01033         default:
01034                 wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
01035                            __func__, data->state);
01036                 break;
01037         }
01038 
01039         eap_fast_phase2_init(sm, data, next_type);
01040 }
01041 
01042 
01043 static void eap_fast_process_phase2_eap(struct eap_sm *sm,
01044                                         struct eap_fast_data *data,
01045                                         u8 *in_data, size_t in_len)
01046 {
01047         struct eap_hdr *hdr;
01048         size_t len;
01049 
01050         hdr = (struct eap_hdr *) in_data;
01051         if (in_len < (int) sizeof(*hdr)) {
01052                 wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
01053                            "EAP frame (len=%lu)", (unsigned long) in_len);
01054                 eap_fast_req_failure(sm, data);
01055                 return;
01056         }
01057         len = be_to_host16(hdr->length);
01058         if (len > in_len) {
01059                 wpa_printf(MSG_INFO, "EAP-FAST: Length mismatch in "
01060                            "Phase 2 EAP frame (len=%lu hdr->length=%lu)",
01061                            (unsigned long) in_len, (unsigned long) len);
01062                 eap_fast_req_failure(sm, data);
01063                 return;
01064         }
01065         wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: code=%d "
01066                    "identifier=%d length=%lu", hdr->code, hdr->identifier,
01067                    (unsigned long) len);
01068         switch (hdr->code) {
01069         case EAP_CODE_RESPONSE:
01070                 eap_fast_process_phase2_response(sm, data, (u8 *) hdr, len);
01071                 break;
01072         default:
01073                 wpa_printf(MSG_INFO, "EAP-FAST: Unexpected code=%d in "
01074                            "Phase 2 EAP header", hdr->code);
01075                 break;
01076         }
01077 }
01078 
01079 
01080 static int eap_fast_parse_tlvs(u8 *data, size_t data_len,
01081                                struct eap_fast_tlv_parse *tlv)
01082 {
01083         int mandatory, tlv_type, len, res;
01084         u8 *pos, *end;
01085 
01086         os_memset(tlv, 0, sizeof(*tlv));
01087 
01088         pos = data;
01089         end = data + data_len;
01090         while (pos + 4 < end) {
01091                 mandatory = pos[0] & 0x80;
01092                 tlv_type = WPA_GET_BE16(pos) & 0x3fff;
01093                 pos += 2;
01094                 len = WPA_GET_BE16(pos);
01095                 pos += 2;
01096                 if (pos + len > end) {
01097                         wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow");
01098                         return -1;
01099                 }
01100                 wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: "
01101                            "TLV type %d length %d%s",
01102                            tlv_type, len, mandatory ? " (mandatory)" : "");
01103 
01104                 res = eap_fast_parse_tlv(tlv, tlv_type, pos, len);
01105                 if (res == -2)
01106                         break;
01107                 if (res < 0) {
01108                         if (mandatory) {
01109                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
01110                                            "mandatory TLV type %d", tlv_type);
01111                                 /* TODO: generate Nak TLV */
01112                                 break;
01113                         } else {
01114                                 wpa_printf(MSG_DEBUG, "EAP-FAST: Ignored "
01115                                            "unknown optional TLV type %d",
01116                                            tlv_type);
01117                         }
01118                 }
01119 
01120                 pos += len;
01121         }
01122 
01123         return 0;
01124 }
01125 
01126 
01127 static int eap_fast_validate_crypto_binding(
01128         struct eap_fast_data *data, struct eap_tlv_crypto_binding_tlv *b,
01129         size_t bind_len)
01130 {
01131         u8 cmac[SHA1_MAC_LEN];
01132 
01133         wpa_printf(MSG_DEBUG, "EAP-FAST: Reply Crypto-Binding TLV: "
01134                    "Version %d Received Version %d SubType %d",
01135                    b->version, b->received_version, b->subtype);
01136         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: NONCE",
01137                     b->nonce, sizeof(b->nonce));
01138         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
01139                     b->compound_mac, sizeof(b->compound_mac));
01140 
01141         if (b->version != EAP_FAST_VERSION ||
01142             b->received_version != EAP_FAST_VERSION) {
01143                 wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected version "
01144                            "in Crypto-Binding: version %d "
01145                            "received_version %d", b->version,
01146                            b->received_version);
01147                 return -1;
01148         }
01149 
01150         if (b->subtype != EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE) {
01151                 wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected subtype in "
01152                            "Crypto-Binding: %d", b->subtype);
01153                 return -1;
01154         }
01155 
01156         if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 ||
01157             (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) {
01158                 wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in "
01159                            "Crypto-Binding");
01160                 return -1;
01161         }
01162 
01163         os_memcpy(cmac, b->compound_mac, sizeof(cmac));
01164         os_memset(b->compound_mac, 0, sizeof(cmac));
01165         wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Crypto-Binding TLV for "
01166                     "Compound MAC calculation",
01167                     (u8 *) b, bind_len);
01168         hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len,
01169                   b->compound_mac);
01170         if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) {
01171                 wpa_hexdump(MSG_MSGDUMP,
01172                             "EAP-FAST: Calculated Compound MAC",
01173                             b->compound_mac, sizeof(cmac));
01174                 wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not "
01175                            "match");
01176                 return -1;
01177         }
01178 
01179         return 0;
01180 }
01181 
01182 
01183 static int eap_fast_pac_type(u8 *pac, size_t len, u16 type)
01184 {
01185         struct eap_tlv_pac_type_tlv *tlv;
01186 
01187         if (pac == NULL || len != sizeof(*tlv))
01188                 return 0;
01189 
01190         tlv = (struct eap_tlv_pac_type_tlv *) pac;
01191 
01192         return be_to_host16(tlv->tlv_type) == PAC_TYPE_PAC_TYPE &&
01193                 be_to_host16(tlv->length) == 2 &&
01194                 be_to_host16(tlv->pac_type) == type;
01195 }
01196 
01197 
01198 static void eap_fast_process_phase2_tlvs(struct eap_sm *sm,
01199                                          struct eap_fast_data *data,
01200                                          u8 *in_data, size_t in_len)
01201 {
01202         struct eap_fast_tlv_parse tlv;
01203         int check_crypto_binding = data->state == CRYPTO_BINDING;
01204 
01205         if (eap_fast_parse_tlvs(in_data, in_len, &tlv) < 0) {
01206                 wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to parse received "
01207                            "Phase 2 TLVs");
01208                 return;
01209         }
01210 
01211         if (tlv.result == EAP_TLV_RESULT_FAILURE) {
01212                 wpa_printf(MSG_DEBUG, "EAP-FAST: Result TLV indicated "
01213                            "failure");
01214                 eap_fast_state(data, FAILURE);
01215                 return;
01216         }
01217 
01218         if (data->state == REQUEST_PAC) {
01219                 u16 type, len, res;
01220                 if (tlv.pac == NULL || tlv.pac_len < 6) {
01221                         wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC "
01222                                    "Acknowledgement received");
01223                         eap_fast_state(data, FAILURE);
01224                         return;
01225                 }
01226 
01227                 type = WPA_GET_BE16(tlv.pac);
01228                 len = WPA_GET_BE16(tlv.pac + 2);
01229                 res = WPA_GET_BE16(tlv.pac + 4);
01230 
01231                 if (type != PAC_TYPE_PAC_ACKNOWLEDGEMENT || len != 2 ||
01232                     res != EAP_TLV_RESULT_SUCCESS) {
01233                         wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV did not "
01234                                    "contain acknowledgement");
01235                         eap_fast_state(data, FAILURE);
01236                         return;
01237                 }
01238 
01239                 wpa_printf(MSG_DEBUG, "EAP-FAST: PAC-Acknowledgement received "
01240                            "- PAC provisioning succeeded");
01241                 eap_fast_state(data, (data->anon_provisioning ||
01242                                       data->send_new_pac == 2) ?
01243                                FAILURE : SUCCESS);
01244                 return;
01245         }
01246 
01247         if (check_crypto_binding) {
01248                 if (tlv.crypto_binding == NULL) {
01249                         wpa_printf(MSG_DEBUG, "EAP-FAST: No Crypto-Binding "
01250                                    "TLV received");
01251                         eap_fast_state(data, FAILURE);
01252                         return;
01253                 }
01254 
01255                 if (data->final_result &&
01256                     tlv.result != EAP_TLV_RESULT_SUCCESS) {
01257                         wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
01258                                    "without Success Result");
01259                         eap_fast_state(data, FAILURE);
01260                         return;
01261                 }
01262 
01263                 if (!data->final_result &&
01264                     tlv.iresult != EAP_TLV_RESULT_SUCCESS) {
01265                         wpa_printf(MSG_DEBUG, "EAP-FAST: Crypto-Binding TLV "
01266                                    "without intermediate Success Result");
01267                         eap_fast_state(data, FAILURE);
01268                         return;
01269                 }
01270 
01271                 if (eap_fast_validate_crypto_binding(data, tlv.crypto_binding,
01272                                                      tlv.crypto_binding_len)) {
01273                         eap_fast_state(data, FAILURE);
01274                         return;
01275                 }
01276 
01277                 wpa_printf(MSG_DEBUG, "EAP-FAST: Valid Crypto-Binding TLV "
01278                            "received");
01279                 if (data->final_result) {
01280                         wpa_printf(MSG_DEBUG, "EAP-FAST: Authentication "
01281                                    "completed successfully");
01282                 }
01283 
01284                 if (data->anon_provisioning &&
01285                     sm->eap_fast_prov != ANON_PROV &&
01286                     sm->eap_fast_prov != BOTH_PROV) {
01287                         wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
01288                                    "use unauthenticated provisioning which is "
01289                                    "disabled");
01290                         eap_fast_state(data, FAILURE);
01291                         return;
01292                 }
01293 
01294                 if (sm->eap_fast_prov != AUTH_PROV &&
01295                     sm->eap_fast_prov != BOTH_PROV &&
01296                     tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
01297                     eap_fast_pac_type(tlv.pac, tlv.pac_len,
01298                                       PAC_TYPE_TUNNEL_PAC)) {
01299                         wpa_printf(MSG_DEBUG, "EAP-FAST: Client is trying to "
01300                                    "use authenticated provisioning which is "
01301                                    "disabled");
01302                         eap_fast_state(data, FAILURE);
01303                         return;
01304                 }
01305 
01306                 if (data->anon_provisioning ||
01307                     (tlv.request_action == EAP_TLV_ACTION_PROCESS_TLV &&
01308                      eap_fast_pac_type(tlv.pac, tlv.pac_len,
01309                                        PAC_TYPE_TUNNEL_PAC))) {
01310                         wpa_printf(MSG_DEBUG, "EAP-FAST: Requested a new "
01311                                    "Tunnel PAC");
01312                         eap_fast_state(data, REQUEST_PAC);
01313                 } else if (data->send_new_pac) {
01314                         wpa_printf(MSG_DEBUG, "EAP-FAST: Server triggered "
01315                                    "re-keying of Tunnel PAC");
01316                         eap_fast_state(data, REQUEST_PAC);
01317                 } else if (data->final_result)
01318                         eap_fast_state(data, SUCCESS);
01319         }
01320 
01321         if (tlv.eap_payload_tlv) {
01322                 eap_fast_process_phase2_eap(sm, data, tlv.eap_payload_tlv,
01323                                             tlv.eap_payload_tlv_len);
01324         }
01325 }
01326 
01327 
01328 static void eap_fast_process_phase2(struct eap_sm *sm,
01329                                     struct eap_fast_data *data,
01330                                     struct wpabuf *in_buf)
01331 {
01332         u8 *in_decrypted;
01333         int len_decrypted;
01334         size_t buf_len;
01335         u8 *in_data;
01336         size_t in_len;
01337 
01338         in_data = wpabuf_mhead(in_buf);
01339         in_len = wpabuf_len(in_buf);
01340 
01341         wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"
01342                    " Phase 2", (unsigned long) in_len);
01343 
01344         if (data->pending_phase2_resp) {
01345                 wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 response - "
01346                            "skip decryption and use old data");
01347                 eap_fast_process_phase2_tlvs(
01348                         sm, data, wpabuf_mhead(data->pending_phase2_resp),
01349                         wpabuf_len(data->pending_phase2_resp));
01350                 wpabuf_free(data->pending_phase2_resp);
01351                 data->pending_phase2_resp = NULL;
01352                 return;
01353         }
01354 
01355         buf_len = in_len;
01356         /*
01357          * Even though we try to disable TLS compression, it is possible that
01358          * this cannot be done with all TLS libraries. Add extra buffer space
01359          * to handle the possibility of the decrypted data being longer than
01360          * input data.
01361          */
01362         buf_len += 500;
01363         buf_len *= 3;
01364         in_decrypted = os_malloc(buf_len);
01365         if (in_decrypted == NULL) {
01366                 wpa_printf(MSG_WARNING, "EAP-FAST: Failed to allocate memory "
01367                            "for decryption");
01368                 return;
01369         }
01370 
01371         len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
01372                                                in_data, in_len,
01373                                                in_decrypted, buf_len);
01374         if (len_decrypted < 0) {
01375                 wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
01376                            "data");
01377                 os_free(in_decrypted);
01378                 eap_fast_state(data, FAILURE);
01379                 return;
01380         }
01381 
01382         wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Decrypted Phase 2 TLVs",
01383                         in_decrypted, len_decrypted);
01384 
01385         eap_fast_process_phase2_tlvs(sm, data, in_decrypted, len_decrypted);
01386 
01387         if (sm->method_pending == METHOD_PENDING_WAIT) {
01388                 wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method is in "
01389                            "pending wait state - save decrypted response");
01390                 wpabuf_free(data->pending_phase2_resp);
01391                 data->pending_phase2_resp = wpabuf_alloc_copy(in_decrypted,
01392                                                               len_decrypted);
01393         }
01394 
01395         os_free(in_decrypted);
01396 }
01397 
01398 
01399 static int eap_fast_process_version(struct eap_sm *sm, void *priv,
01400                                     int peer_version)
01401 {
01402         struct eap_fast_data *data = priv;
01403 
01404         data->peer_version = peer_version;
01405 
01406         if (data->force_version >= 0 && peer_version != data->force_version) {
01407                 wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
01408                            " version (forced=%d peer=%d) - reject",
01409                            data->force_version, peer_version);
01410                 return -1;
01411         }
01412 
01413         if (peer_version < data->fast_version) {
01414                 wpa_printf(MSG_DEBUG, "EAP-FAST: peer ver=%d, own ver=%d; "
01415                            "use version %d",
01416                            peer_version, data->fast_version, peer_version);
01417                 data->fast_version = peer_version;
01418         }
01419 
01420         return 0;
01421 }
01422 
01423 
01424 static int eap_fast_process_phase1(struct eap_sm *sm,
01425                                    struct eap_fast_data *data)
01426 {
01427         if (eap_server_tls_phase1(sm, &data->ssl) < 0) {
01428                 wpa_printf(MSG_INFO, "EAP-FAST: TLS processing failed");
01429                 eap_fast_state(data, FAILURE);
01430                 return -1;
01431         }
01432 
01433         if (!tls_connection_established(sm->ssl_ctx, data->ssl.conn) ||
01434             wpabuf_len(data->ssl.out_buf) > 0)
01435                 return 1;
01436 
01437         /*
01438          * Phase 1 was completed with the received message (e.g., when using
01439          * abbreviated handshake), so Phase 2 can be started immediately
01440          * without having to send through an empty message to the peer.
01441          */
01442 
01443         return eap_fast_phase1_done(sm, data);
01444 }
01445 
01446 
01447 static void eap_fast_process_phase2_start(struct eap_sm *sm,
01448                                           struct eap_fast_data *data)
01449 {
01450         u8 next_type;
01451 
01452         if (data->identity) {
01453                 os_free(sm->identity);
01454                 sm->identity = data->identity;
01455                 data->identity = NULL;
01456                 sm->identity_len = data->identity_len;
01457                 data->identity_len = 0;
01458                 sm->require_identity_match = 1;
01459                 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
01460                         wpa_hexdump_ascii(MSG_DEBUG, "EAP-FAST: "
01461                                           "Phase2 Identity not found "
01462                                           "in the user database",
01463                                           sm->identity, sm->identity_len);
01464                         next_type = eap_fast_req_failure(sm, data);
01465                 } else {
01466                         wpa_printf(MSG_DEBUG, "EAP-FAST: Identity already "
01467                                    "known - skip Phase 2 Identity Request");
01468                         next_type = sm->user->methods[0].method;
01469                         sm->user_eap_method_index = 1;
01470                 }
01471 
01472                 eap_fast_state(data, PHASE2_METHOD);
01473         } else {
01474                 eap_fast_state(data, PHASE2_ID);
01475                 next_type = EAP_TYPE_IDENTITY;
01476         }
01477 
01478         eap_fast_phase2_init(sm, data, next_type);
01479 }
01480 
01481 
01482 static void eap_fast_process_msg(struct eap_sm *sm, void *priv,
01483                                  const struct wpabuf *respData)
01484 {
01485         struct eap_fast_data *data = priv;
01486 
01487         switch (data->state) {
01488         case PHASE1:
01489                 if (eap_fast_process_phase1(sm, data))
01490                         break;
01491 
01492                 /* fall through to PHASE2_START */
01493         case PHASE2_START:
01494                 eap_fast_process_phase2_start(sm, data);
01495                 break;
01496         case PHASE2_ID:
01497         case PHASE2_METHOD:
01498         case CRYPTO_BINDING:
01499         case REQUEST_PAC:
01500                 eap_fast_process_phase2(sm, data, data->ssl.in_buf);
01501                 break;
01502         default:
01503                 wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected state %d in %s",
01504                            data->state, __func__);
01505                 break;
01506         }
01507 }
01508 
01509 
01510 static void eap_fast_process(struct eap_sm *sm, void *priv,
01511                              struct wpabuf *respData)
01512 {
01513         struct eap_fast_data *data = priv;
01514         if (eap_server_tls_process(sm, &data->ssl, respData, data,
01515                                    EAP_TYPE_FAST, eap_fast_process_version,
01516                                    eap_fast_process_msg) < 0)
01517                 eap_fast_state(data, FAILURE);
01518 }
01519 
01520 
01521 static Boolean eap_fast_isDone(struct eap_sm *sm, void *priv)
01522 {
01523         struct eap_fast_data *data = priv;
01524         return data->state == SUCCESS || data->state == FAILURE;
01525 }
01526 
01527 
01528 static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len)
01529 {
01530         struct eap_fast_data *data = priv;
01531         u8 *eapKeyData;
01532 
01533         if (data->state != SUCCESS)
01534                 return NULL;
01535 
01536         eapKeyData = os_malloc(EAP_FAST_KEY_LEN);
01537         if (eapKeyData == NULL)
01538                 return NULL;
01539 
01540         eap_fast_derive_eap_msk(data->simck, eapKeyData);
01541         *len = EAP_FAST_KEY_LEN;
01542 
01543         return eapKeyData;
01544 }
01545 
01546 
01547 static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
01548 {
01549         struct eap_fast_data *data = priv;
01550         u8 *eapKeyData;
01551 
01552         if (data->state != SUCCESS)
01553                 return NULL;
01554 
01555         eapKeyData = os_malloc(EAP_EMSK_LEN);
01556         if (eapKeyData == NULL)
01557                 return NULL;
01558 
01559         eap_fast_derive_eap_emsk(data->simck, eapKeyData);
01560         *len = EAP_EMSK_LEN;
01561 
01562         return eapKeyData;
01563 }
01564 
01565 
01566 static Boolean eap_fast_isSuccess(struct eap_sm *sm, void *priv)
01567 {
01568         struct eap_fast_data *data = priv;
01569         return data->state == SUCCESS;
01570 }
01571 
01572 
01573 int eap_server_fast_register(void)
01574 {
01575         struct eap_method *eap;
01576         int ret;
01577 
01578         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
01579                                       EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
01580         if (eap == NULL)
01581                 return -1;
01582 
01583         eap->init = eap_fast_init;
01584         eap->reset = eap_fast_reset;
01585         eap->buildReq = eap_fast_buildReq;
01586         eap->check = eap_fast_check;
01587         eap->process = eap_fast_process;
01588         eap->isDone = eap_fast_isDone;
01589         eap->getKey = eap_fast_getKey;
01590         eap->get_emsk = eap_fast_get_emsk;
01591         eap->isSuccess = eap_fast_isSuccess;
01592 
01593         ret = eap_server_method_register(eap);
01594         if (ret)
01595                 eap_server_method_free(eap);
01596         return ret;
01597 }
01598 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:51 2009 for hostapd by  doxygen 1.6.1