aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-12-20 09:39:45 (GMT)
committerJouni Malinen <j@w1.fi>2010-01-09 19:16:49 (GMT)
commit3fd721aa5990169f2c6d410315d2f8a65b4809f5 (patch)
tree567ab788d7fb54bf0fe70d672568b98450898e4a
parenta81ca7ee2a0a53d5bc9c19fa7e8e910e95a89964 (diff)
downloadhostap-06-3fd721aa5990169f2c6d410315d2f8a65b4809f5.zip
hostap-06-3fd721aa5990169f2c6d410315d2f8a65b4809f5.tar.gz
hostap-06-3fd721aa5990169f2c6d410315d2f8a65b4809f5.tar.bz2
EAP-FAST server: Piggyback Phase 2 start with end of Phase 1
If Finished message from peer has been received before the server Finished message, start Phase 2 with the same message to avoid extra roundtrip when the peer does not have anything to send after the server Finished message. (cherry picked from commit c479e41f53b10ff91f4c1e183c441da76d47f05e)
-rw-r--r--src/eap_server/eap_fast.c77
1 files changed, 61 insertions, 16 deletions
diff --git a/src/eap_server/eap_fast.c b/src/eap_server/eap_fast.c
index b474c99..c06f396 100644
--- a/src/eap_server/eap_fast.c
+++ b/src/eap_server/eap_fast.c
@@ -73,6 +73,10 @@ struct eap_fast_data {
};
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+ struct eap_fast_data *data);
+
+
static const char * eap_fast_state_txt(int state)
{
switch (state) {
@@ -804,11 +808,48 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
}
+static int eap_fast_encrypt_phase2(struct eap_sm *sm,
+ struct eap_fast_data *data,
+ struct wpabuf *plain, int piggyback)
+{
+ struct wpabuf *encr;
+
+ wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
+ plain);
+ encr = eap_server_tls_encrypt(sm, &data->ssl, wpabuf_mhead(plain),
+ wpabuf_len(plain));
+ wpabuf_free(plain);
+
+ if (data->ssl.out_buf && piggyback) {
+ wpa_printf(MSG_DEBUG, "EAP-FAST: Piggyback Phase 2 data "
+ "(len=%d) with last Phase 1 Message (len=%d "
+ "used=%d)",
+ (int) wpabuf_len(encr),
+ (int) wpabuf_len(data->ssl.out_buf),
+ (int) data->ssl.out_used);
+ if (wpabuf_resize(&data->ssl.out_buf, wpabuf_len(encr)) < 0) {
+ wpa_printf(MSG_WARNING, "EAP-FAST: Failed to resize "
+ "output buffer");
+ wpabuf_free(encr);
+ return -1;
+ }
+ wpabuf_put_buf(data->ssl.out_buf, encr);
+ wpabuf_free(encr);
+ } else {
+ wpabuf_free(data->ssl.out_buf);
+ data->ssl.out_used = 0;
+ data->ssl.out_buf = encr;
+ }
+
+ return 0;
+}
+
+
static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
struct eap_fast_data *data = priv;
struct wpabuf *req = NULL;
- struct wpabuf *encr;
+ int piggyback = 0;
if (data->ssl.state == FRAG_ACK) {
return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
@@ -827,6 +868,19 @@ static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
if (eap_fast_phase1_done(sm, data) < 0)
return NULL;
+ if (data->state == PHASE2_START) {
+ /*
+ * Try to generate Phase 2 data to piggyback
+ * with the end of Phase 1 to avoid extra
+ * roundtrip.
+ */
+ wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
+ "Phase 2");
+ if (eap_fast_process_phase2_start(sm, data))
+ break;
+ req = eap_fast_build_phase2_req(sm, data, id);
+ piggyback = 1;
+ }
}
break;
case PHASE2_ID:
@@ -856,18 +910,9 @@ static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
return NULL;
}
- if (req) {
- wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 "
- "TLVs", req);
- encr = eap_server_tls_encrypt(sm, &data->ssl,
- wpabuf_mhead(req),
- wpabuf_len(req));
- wpabuf_free(req);
-
- wpabuf_free(data->ssl.out_buf);
- data->ssl.out_used = 0;
- data->ssl.out_buf = encr;
- }
+ if (req &&
+ eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
+ return NULL;
return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
data->fast_version, id);
@@ -1443,8 +1488,8 @@ static int eap_fast_process_phase1(struct eap_sm *sm,
}
-static void eap_fast_process_phase2_start(struct eap_sm *sm,
- struct eap_fast_data *data)
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+ struct eap_fast_data *data)
{
u8 next_type;
@@ -1474,7 +1519,7 @@ static void eap_fast_process_phase2_start(struct eap_sm *sm,
next_type = EAP_TYPE_IDENTITY;
}
- eap_fast_phase2_init(sm, data, next_type);
+ return eap_fast_phase2_init(sm, data, next_type);
}