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


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:25:13