summaryrefslogtreecommitdiff
path: root/src/eap_peer
diff options
context:
space:
mode:
authorRui Paulo <rpaulo@FreeBSD.org>2015-10-14 04:30:17 +0000
committerRui Paulo <rpaulo@FreeBSD.org>2015-10-14 04:30:17 +0000
commitb834757ea3bcd1bba3381ff7cab216458d8f7efb (patch)
treedadb24e00f30aa959ea0981e649b18c668304498 /src/eap_peer
parentfbffd80fb2ba16c68f799da68a119d5e69643604 (diff)
Notes
Diffstat (limited to 'src/eap_peer')
-rw-r--r--src/eap_peer/Makefile18
-rw-r--r--src/eap_peer/eap.c14
-rw-r--r--src/eap_peer/eap.h2
-rw-r--r--src/eap_peer/eap_aka.c2
-rw-r--r--src/eap_peer/eap_eke.c105
-rw-r--r--src/eap_peer/eap_fast.c78
-rw-r--r--src/eap_peer/eap_gpsk.c27
-rw-r--r--src/eap_peer/eap_i.h8
-rw-r--r--src/eap_peer/eap_mschapv2.c6
-rw-r--r--src/eap_peer/eap_pax.c2
-rw-r--r--src/eap_peer/eap_peap.c18
-rw-r--r--src/eap_peer/eap_pwd.c116
-rw-r--r--src/eap_peer/eap_sake.c25
-rw-r--r--src/eap_peer/eap_sim.c2
-rw-r--r--src/eap_peer/eap_tls.c18
-rw-r--r--src/eap_peer/eap_tls_common.c137
-rw-r--r--src/eap_peer/eap_tls_common.h2
-rw-r--r--src/eap_peer/eap_ttls.c41
-rw-r--r--src/eap_peer/eap_wsc.c3
19 files changed, 392 insertions, 232 deletions
diff --git a/src/eap_peer/Makefile b/src/eap_peer/Makefile
index f79519b718499..6531ccd5dac0b 100644
--- a/src/eap_peer/Makefile
+++ b/src/eap_peer/Makefile
@@ -1,11 +1,23 @@
-all:
- @echo Nothing to be made.
+all: libeap_peer.a
clean:
- rm -f *~ *.o *.so *.d *.gcno *.gcda *.gcov
+ rm -f *~ *.o *.so *.d *.gcno *.gcda *.gcov libeap_peer.a
install:
if ls *.so >/dev/null 2>&1; then \
install -d $(DESTDIR)$(LIBDIR)/wpa_supplicant && \
cp *.so $(DESTDIR)$(LIBDIR)/wpa_supplicant \
; fi
+
+include ../lib.rules
+
+CFLAGS += -DIEEE8021X_EAPOL
+
+LIB_OBJS= \
+ eap.o \
+ eap_methods.o
+
+libeap_peer.a: $(LIB_OBJS)
+ $(AR) crT $@ $?
+
+-include $(OBJS:%.o=%.d)
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 35433f3bd8e41..56c24b5503200 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -584,7 +584,7 @@ static int eap_peer_erp_reauth_start(struct eap_sm *sm,
wpa_printf(MSG_DEBUG, "EAP: Valid ERP key found %s (SEQ=%u)",
erp->keyname_nai, erp->next_seq);
- msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_ERP_TYPE_REAUTH,
+ msg = eap_msg_alloc(EAP_VENDOR_IETF, (EapType) EAP_ERP_TYPE_REAUTH,
1 + 2 + 2 + os_strlen(erp->keyname_nai) + 1 + 16,
EAP_CODE_INITIATE, hdr->identifier);
if (msg == NULL)
@@ -708,7 +708,7 @@ SM_STATE(EAP, SEND_RESPONSE)
wpabuf_free(sm->lastRespData);
if (sm->eapRespData) {
if (sm->workaround)
- os_memcpy(sm->last_md5, sm->req_md5, 16);
+ os_memcpy(sm->last_sha1, sm->req_sha1, 20);
sm->lastId = sm->reqId;
sm->lastRespData = wpabuf_dup(sm->eapRespData);
eapol_set_bool(sm, EAPOL_eapResp, TRUE);
@@ -914,12 +914,12 @@ static int eap_peer_req_is_duplicate(struct eap_sm *sm)
duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
if (sm->workaround && duplicate &&
- os_memcmp(sm->req_md5, sm->last_md5, 16) != 0) {
+ os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) {
/*
* RFC 4137 uses (reqId == lastId) as the only verification for
* duplicate EAP requests. However, this misses cases where the
* AS is incorrectly using the same id again; and
- * unfortunately, such implementations exist. Use MD5 hash as
+ * unfortunately, such implementations exist. Use SHA1 hash as
* an extra verification for the packets being duplicate to
* workaround these issues.
*/
@@ -1765,7 +1765,7 @@ static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
if (sm->workaround) {
const u8 *addr[1];
addr[0] = wpabuf_head(req);
- md5_vector(1, addr, &plen, sm->req_md5);
+ sha1_vector(1, addr, &plen, sm->req_sha1);
}
switch (hdr->code) {
@@ -1911,7 +1911,7 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
* structure remains alive while the EAP state machine is active.
*/
struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
- struct eapol_callbacks *eapol_cb,
+ const struct eapol_callbacks *eapol_cb,
void *msg_ctx, struct eap_config *conf)
{
struct eap_sm *sm;
@@ -2400,7 +2400,7 @@ static int eap_allowed_phase2_type(int vendor, int type)
u32 eap_get_phase2_type(const char *name, int *vendor)
{
int v;
- u8 type = eap_peer_get_type(name, &v);
+ u32 type = eap_peer_get_type(name, &v);
if (eap_allowed_phase2_type(v, type)) {
*vendor = v;
return type;
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index 702463b9d5146..1a645af8b2003 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -307,7 +307,7 @@ struct eap_config {
};
struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
- struct eapol_callbacks *eapol_cb,
+ const struct eapol_callbacks *eapol_cb,
void *msg_ctx, struct eap_config *conf);
void eap_peer_sm_deinit(struct eap_sm *sm);
int eap_peer_sm_step(struct eap_sm *sm);
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 0662ae7383674..dc9e8cc34d4af 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -1296,7 +1296,7 @@ static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
&len);
- if (pos == NULL || len < 1) {
+ if (pos == NULL || len < 3) {
ret->ignore = TRUE;
return NULL;
}
diff --git a/src/eap_peer/eap_eke.c b/src/eap_peer/eap_eke.c
index 9fec66c068679..dfbda5644f6fc 100644
--- a/src/eap_peer/eap_eke.c
+++ b/src/eap_peer/eap_eke.c
@@ -195,15 +195,14 @@ static int eap_eke_supp_mac(u8 mac)
static struct wpabuf * eap_eke_build_fail(struct eap_eke_data *data,
struct eap_method_ret *ret,
- const struct wpabuf *reqData,
- u32 failure_code)
+ u8 id, u32 failure_code)
{
struct wpabuf *resp;
wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Failure/Response - code=0x%x",
failure_code);
- resp = eap_eke_build_msg(data, eap_get_id(reqData), 4, EAP_EKE_FAILURE);
+ resp = eap_eke_build_msg(data, id, 4, EAP_EKE_FAILURE);
if (resp)
wpabuf_put_be32(resp, failure_code);
@@ -230,9 +229,10 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
const u8 *pos, *end;
const u8 *prop = NULL;
u8 idtype;
+ u8 id = eap_get_id(reqData);
if (data->state != IDENTITY) {
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -240,7 +240,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
if (payload_len < 2 + 4) {
wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -253,7 +253,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
if (pos + num_prop * 4 > end) {
wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data (num_prop=%u)",
num_prop);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -293,7 +293,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
if (prop == NULL) {
wpa_printf(MSG_DEBUG, "EAP-EKE: No acceptable proposal found");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_NO_PROPOSAL_CHOSEN);
}
@@ -301,7 +301,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
if (pos == end) {
wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data to include IDType/Identity");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -312,7 +312,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
os_free(data->serverid);
data->serverid = os_malloc(end - pos);
if (data->serverid == NULL) {
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
os_memcpy(data->serverid, pos, end - pos);
@@ -320,11 +320,11 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-ID/Response");
- resp = eap_eke_build_msg(data, eap_get_id(reqData),
+ resp = eap_eke_build_msg(data, id,
2 + 4 + 1 + data->peerid_len,
EAP_EKE_ID);
if (resp == NULL) {
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -339,7 +339,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data,
data->msgs = wpabuf_alloc(wpabuf_len(reqData) + wpabuf_len(resp));
if (data->msgs == NULL) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpabuf_put_buf(data->msgs, reqData);
@@ -366,10 +366,11 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
u8 pub[EAP_EKE_MAX_DH_LEN];
const u8 *password;
size_t password_len;
+ u8 id = eap_get_id(reqData);
if (data->state != COMMIT) {
wpa_printf(MSG_DEBUG, "EAP-EKE: EAP-EKE-Commit/Request received in unexpected state (%d)", data->state);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -378,7 +379,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
password = eap_get_config_password(sm, &password_len);
if (password == NULL) {
wpa_printf(MSG_INFO, "EAP-EKE: No password configured!");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PASSWD_NOT_FOUND);
}
@@ -387,7 +388,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (pos + data->sess.dhcomp_len > end) {
wpa_printf(MSG_DEBUG, "EAP-EKE: Too short EAP-EKE-Commit");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -405,7 +406,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
data->serverid, data->serverid_len,
data->peerid, data->peerid_len, key) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive key");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -416,7 +417,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (eap_eke_dh_init(data->sess.dhgroup, data->dh_priv, pub) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to initialize DH");
os_memset(key, 0, sizeof(key));
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -424,7 +425,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
{
wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive shared secret");
os_memset(key, 0, sizeof(key));
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -433,18 +434,18 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
data->peerid, data->peerid_len) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive Ke/Ki");
os_memset(key, 0, sizeof(key));
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Commit/Response");
- resp = eap_eke_build_msg(data, eap_get_id(reqData),
+ resp = eap_eke_build_msg(data, id,
data->sess.dhcomp_len + data->sess.pnonce_len,
EAP_EKE_COMMIT);
if (resp == NULL) {
os_memset(key, 0, sizeof(key));
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -453,7 +454,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (eap_eke_dhcomp(&data->sess, key, pub, rpos) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to build DHComponent_P");
os_memset(key, 0, sizeof(key));
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
os_memset(key, 0, sizeof(key));
@@ -463,7 +464,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (random_get_bytes(data->nonce_p, data->sess.nonce_len)) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Nonce_P",
@@ -472,7 +473,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (eap_eke_prot(&data->sess, data->nonce_p, data->sess.nonce_len,
wpabuf_put(resp, 0), &prot_len) < 0) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpa_hexdump(MSG_DEBUG, "EAP-EKE: PNonce_P",
@@ -484,7 +485,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm,
if (wpabuf_resize(&data->msgs, wpabuf_len(reqData) + wpabuf_len(resp))
< 0) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpabuf_put_buf(data->msgs, reqData);
@@ -509,11 +510,12 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
u8 auth_s[EAP_EKE_MAX_HASH_LEN];
size_t decrypt_len;
u8 *auth;
+ u8 id = eap_get_id(reqData);
if (data->state != CONFIRM) {
wpa_printf(MSG_DEBUG, "EAP-EKE: EAP-EKE-Confirm/Request received in unexpected state (%d)",
data->state);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -524,7 +526,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
if (pos + data->sess.pnonce_ps_len + data->sess.prf_len > end) {
wpa_printf(MSG_DEBUG, "EAP-EKE: Too short EAP-EKE-Confirm");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PROTO_ERROR);
}
@@ -532,19 +534,19 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
if (eap_eke_decrypt_prot(&data->sess, pos, data->sess.pnonce_ps_len,
nonces, &decrypt_len) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to decrypt PNonce_PS");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_AUTHENTICATION_FAIL);
}
if (decrypt_len != (size_t) 2 * data->sess.nonce_len) {
wpa_printf(MSG_INFO, "EAP-EKE: PNonce_PS protected data length does not match length of Nonce_P and Nonce_S");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_AUTHENTICATION_FAIL);
}
wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Received Nonce_P | Nonce_S",
nonces, 2 * data->sess.nonce_len);
if (os_memcmp(data->nonce_p, nonces, data->sess.nonce_len) != 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Received Nonce_P does not match transmitted Nonce_P");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_AUTHENTICATION_FAIL);
}
@@ -556,30 +558,30 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
if (eap_eke_derive_ka(&data->sess, data->serverid, data->serverid_len,
data->peerid, data->peerid_len,
data->nonce_p, data->nonce_s) < 0) {
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
if (eap_eke_auth(&data->sess, "EAP-EKE server", data->msgs, auth_s) < 0)
{
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_S", auth_s, data->sess.prf_len);
if (os_memcmp_const(auth_s, pos + data->sess.pnonce_ps_len,
data->sess.prf_len) != 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Auth_S does not match");
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_AUTHENTICATION_FAIL);
}
wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Confirm/Response");
- resp = eap_eke_build_msg(data, eap_get_id(reqData),
+ resp = eap_eke_build_msg(data, id,
data->sess.pnonce_len + data->sess.prf_len,
EAP_EKE_CONFIRM);
if (resp == NULL) {
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -587,7 +589,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
if (eap_eke_prot(&data->sess, data->nonce_s, data->sess.nonce_len,
wpabuf_put(resp, 0), &prot_len) < 0) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpabuf_put(resp, prot_len);
@@ -595,7 +597,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
auth = wpabuf_put(resp, data->sess.prf_len);
if (eap_eke_auth(&data->sess, "EAP-EKE peer", data->msgs, auth) < 0) {
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_P", auth, data->sess.prf_len);
@@ -606,7 +608,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data,
data->msk, data->emsk) < 0) {
wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive MSK/EMSK");
wpabuf_free(resp);
- return eap_eke_build_fail(data, ret, reqData,
+ return eap_eke_build_fail(data, ret, id,
EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
}
@@ -638,7 +640,8 @@ static struct wpabuf * eap_eke_process_failure(struct eap_eke_data *data,
wpa_printf(MSG_INFO, "EAP-EKE: Failure-Code 0x%x", code);
}
- return eap_eke_build_fail(data, ret, reqData, EAP_EKE_FAIL_NO_ERROR);
+ return eap_eke_build_fail(data, ret, eap_get_id(reqData),
+ EAP_EKE_FAIL_NO_ERROR);
}
@@ -741,6 +744,29 @@ static u8 * eap_eke_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
}
+static u8 * eap_eke_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
+{
+ struct eap_eke_data *data = priv;
+ u8 *sid;
+ size_t sid_len;
+
+ if (data->state != SUCCESS)
+ return NULL;
+
+ sid_len = 1 + 2 * data->sess.nonce_len;
+ sid = os_malloc(sid_len);
+ if (sid == NULL)
+ return NULL;
+ sid[0] = EAP_TYPE_EKE;
+ os_memcpy(sid + 1, data->nonce_p, data->sess.nonce_len);
+ os_memcpy(sid + 1 + data->sess.nonce_len, data->nonce_s,
+ data->sess.nonce_len);
+ *len = sid_len;
+
+ return sid;
+}
+
+
int eap_peer_eke_register(void)
{
struct eap_method *eap;
@@ -757,6 +783,7 @@ int eap_peer_eke_register(void)
eap->isKeyAvailable = eap_eke_isKeyAvailable;
eap->getKey = eap_eke_getKey;
eap->get_emsk = eap_eke_get_emsk;
+ eap->getSessionId = eap_eke_get_session_id;
ret = eap_peer_method_register(eap);
if (ret)
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 68d7fba8892ef..4cbe3bacb0a61 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -267,8 +267,8 @@ static int eap_fast_derive_msk(struct eap_fast_data *data)
}
-static void eap_fast_derive_key_auth(struct eap_sm *sm,
- struct eap_fast_data *data)
+static int eap_fast_derive_key_auth(struct eap_sm *sm,
+ struct eap_fast_data *data)
{
u8 *sks;
@@ -281,7 +281,7 @@ static void eap_fast_derive_key_auth(struct eap_sm *sm,
if (sks == NULL) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
"session_key_seed");
- return;
+ return -1;
}
/*
@@ -294,11 +294,12 @@ static void eap_fast_derive_key_auth(struct eap_sm *sm,
data->simck_idx = 0;
os_memcpy(data->simck, sks, EAP_FAST_SIMCK_LEN);
os_free(sks);
+ return 0;
}
-static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
- struct eap_fast_data *data)
+static int eap_fast_derive_key_provisioning(struct eap_sm *sm,
+ struct eap_fast_data *data)
{
os_free(data->key_block_p);
data->key_block_p = (struct eap_fast_key_block_provisioning *)
@@ -307,7 +308,7 @@ static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
sizeof(*data->key_block_p));
if (data->key_block_p == NULL) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
- return;
+ return -1;
}
/*
* RFC 4851, Section 5.2:
@@ -326,15 +327,19 @@ static void eap_fast_derive_key_provisioning(struct eap_sm *sm,
wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: client_challenge",
data->key_block_p->client_challenge,
sizeof(data->key_block_p->client_challenge));
+ return 0;
}
-static void eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
+static int eap_fast_derive_keys(struct eap_sm *sm, struct eap_fast_data *data)
{
+ int res;
+
if (data->anon_provisioning)
- eap_fast_derive_key_provisioning(sm, data);
+ res = eap_fast_derive_key_provisioning(sm, data);
else
- eap_fast_derive_key_auth(sm, data);
+ res = eap_fast_derive_key_auth(sm, data);
+ return res;
}
@@ -1172,7 +1177,7 @@ static struct wpabuf * eap_fast_pac_request(void)
static int eap_fast_process_decrypted(struct eap_sm *sm,
struct eap_fast_data *data,
struct eap_method_ret *ret,
- const struct eap_hdr *req,
+ u8 identifier,
struct wpabuf *decrypted,
struct wpabuf **out_data)
{
@@ -1184,18 +1189,18 @@ static int eap_fast_process_decrypted(struct eap_sm *sm,
return 0;
if (resp)
return eap_fast_encrypt_response(sm, data, resp,
- req->identifier, out_data);
+ identifier, out_data);
if (tlv.result == EAP_TLV_RESULT_FAILURE) {
resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
return eap_fast_encrypt_response(sm, data, resp,
- req->identifier, out_data);
+ identifier, out_data);
}
if (tlv.iresult == EAP_TLV_RESULT_FAILURE) {
resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);
return eap_fast_encrypt_response(sm, data, resp,
- req->identifier, out_data);
+ identifier, out_data);
}
if (tlv.crypto_binding) {
@@ -1277,14 +1282,13 @@ static int eap_fast_process_decrypted(struct eap_sm *sm,
resp = wpabuf_alloc(1);
}
- return eap_fast_encrypt_response(sm, data, resp, req->identifier,
+ return eap_fast_encrypt_response(sm, data, resp, identifier,
out_data);
}
static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
- struct eap_method_ret *ret,
- const struct eap_hdr *req,
+ struct eap_method_ret *ret, u8 identifier,
const struct wpabuf *in_data,
struct wpabuf **out_data)
{
@@ -1309,7 +1313,7 @@ static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
/* Received TLS ACK - requesting more fragments */
return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,
data->fast_version,
- req->identifier, NULL, out_data);
+ identifier, NULL, out_data);
}
res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
@@ -1328,7 +1332,7 @@ continue_req:
return -1;
}
- res = eap_fast_process_decrypted(sm, data, ret, req,
+ res = eap_fast_process_decrypted(sm, data, ret, identifier,
in_decrypted, out_data);
wpabuf_free(in_decrypted);
@@ -1340,7 +1344,7 @@ continue_req:
static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len)
{
const u8 *a_id;
- struct pac_tlv_hdr *hdr;
+ const struct pac_tlv_hdr *hdr;
/*
* Parse authority identity (A-ID) from the EAP-FAST/Start. This
@@ -1350,13 +1354,13 @@ static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len)
*id_len = len;
if (len > sizeof(*hdr)) {
int tlen;
- hdr = (struct pac_tlv_hdr *) buf;
+ hdr = (const struct pac_tlv_hdr *) buf;
tlen = be_to_host16(hdr->len);
if (be_to_host16(hdr->type) == PAC_TYPE_A_ID &&
sizeof(*hdr) + tlen <= len) {
wpa_printf(MSG_DEBUG, "EAP-FAST: A-ID was in TLV "
"(Start)");
- a_id = (u8 *) (hdr + 1);
+ a_id = (const u8 *) (hdr + 1);
*id_len = tlen;
}
}
@@ -1529,6 +1533,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
struct wpabuf *resp;
const u8 *pos;
struct eap_fast_data *data = priv;
+ struct wpabuf msg;
pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
reqData, &left, &flags);
@@ -1545,13 +1550,13 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
left = 0; /* A-ID is not used in further packet processing */
}
+ wpabuf_set(&msg, pos, left);
+
resp = NULL;
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
!data->resuming) {
/* Process tunneled (encrypted) phase 2 data. */
- struct wpabuf msg;
- wpabuf_set(&msg, pos, left);
- res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp);
+ res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp);
if (res < 0) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
@@ -1565,8 +1570,15 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
/* Continue processing TLS handshake (phase 1). */
res = eap_peer_tls_process_helper(sm, &data->ssl,
EAP_TYPE_FAST,
- data->fast_version, id, pos,
- left, &resp);
+ data->fast_version, id, &msg,
+ &resp);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-FAST: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return resp;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
char cipher[80];
@@ -1586,20 +1598,24 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
} else
data->anon_provisioning = 0;
data->resuming = 0;
- eap_fast_derive_keys(sm, data);
+ if (eap_fast_derive_keys(sm, data) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-FAST: Could not derive keys");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ wpabuf_free(resp);
+ return NULL;
+ }
}
if (res == 2) {
- struct wpabuf msg;
/*
* Application data included in the handshake message.
*/
wpabuf_free(data->pending_phase2_req);
data->pending_phase2_req = resp;
resp = NULL;
- wpabuf_set(&msg, pos, left);
- res = eap_fast_decrypt(sm, data, ret, req, &msg,
- &resp);
+ res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp);
}
}
diff --git a/src/eap_peer/eap_gpsk.c b/src/eap_peer/eap_gpsk.c
index c54bf116477c8..902b4ba26d6e4 100644
--- a/src/eap_peer/eap_gpsk.c
+++ b/src/eap_peer/eap_gpsk.c
@@ -274,7 +274,7 @@ static const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
static struct wpabuf * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
struct eap_gpsk_data *data,
struct eap_method_ret *ret,
- const struct wpabuf *reqData,
+ u8 identifier,
const u8 *payload,
size_t payload_len)
{
@@ -301,7 +301,7 @@ static struct wpabuf * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
return NULL;
}
- resp = eap_gpsk_send_gpsk_2(data, eap_get_id(reqData),
+ resp = eap_gpsk_send_gpsk_2(data, identifier,
csuite_list, csuite_list_len);
if (resp == NULL)
return NULL;
@@ -583,7 +583,7 @@ static const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
static struct wpabuf * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
struct eap_gpsk_data *data,
struct eap_method_ret *ret,
- const struct wpabuf *reqData,
+ u8 identifier,
const u8 *payload,
size_t payload_len)
{
@@ -615,7 +615,7 @@ static struct wpabuf * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
(unsigned long) (end - pos));
}
- resp = eap_gpsk_send_gpsk_4(data, eap_get_id(reqData));
+ resp = eap_gpsk_send_gpsk_4(data, identifier);
if (resp == NULL)
return NULL;
@@ -670,6 +670,7 @@ static struct wpabuf * eap_gpsk_process(struct eap_sm *sm, void *priv,
struct wpabuf *resp;
const u8 *pos;
size_t len;
+ u8 opcode, id;
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqData, &len);
if (pos == NULL || len < 1) {
@@ -677,25 +678,27 @@ static struct wpabuf * eap_gpsk_process(struct eap_sm *sm, void *priv,
return NULL;
}
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", *pos);
+ id = eap_get_id(reqData);
+ opcode = *pos++;
+ len--;
+ wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", opcode);
ret->ignore = FALSE;
ret->methodState = METHOD_MAY_CONT;
ret->decision = DECISION_FAIL;
ret->allowNotifications = FALSE;
- switch (*pos) {
+ switch (opcode) {
case EAP_GPSK_OPCODE_GPSK_1:
- resp = eap_gpsk_process_gpsk_1(sm, data, ret, reqData,
- pos + 1, len - 1);
+ resp = eap_gpsk_process_gpsk_1(sm, data, ret, id, pos, len);
break;
case EAP_GPSK_OPCODE_GPSK_3:
- resp = eap_gpsk_process_gpsk_3(sm, data, ret, reqData,
- pos + 1, len - 1);
+ resp = eap_gpsk_process_gpsk_3(sm, data, ret, id, pos, len);
break;
default:
- wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignoring message with "
- "unknown opcode %d", *pos);
+ wpa_printf(MSG_DEBUG,
+ "EAP-GPSK: Ignoring message with unknown opcode %d",
+ opcode);
ret->ignore = TRUE;
return NULL;
}
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 2d7fdea227747..99b44dae4e34e 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -328,7 +328,7 @@ struct eap_sm {
/* not defined in RFC 4137 */
Boolean changed;
void *eapol_ctx;
- struct eapol_callbacks *eapol_cb;
+ const struct eapol_callbacks *eapol_cb;
void *eap_method_priv;
int init_phase2;
int fast_reauth;
@@ -338,9 +338,9 @@ struct eap_sm {
Boolean rxResp /* LEAP only */;
Boolean leap_done;
Boolean peap_done;
- u8 req_md5[16]; /* MD5() of the current EAP packet */
- u8 last_md5[16]; /* MD5() of the previously received EAP packet; used
- * in duplicate request detection. */
+ u8 req_sha1[20]; /* SHA1() of the current EAP packet */
+ u8 last_sha1[20]; /* SHA1() of the previously received EAP packet; used
+ * in duplicate request detection. */
void *msg_ctx;
void *scard_ctx;
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index 9e486e7d18fac..6acf1e8ad390a 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -511,6 +511,11 @@ static struct wpabuf * eap_mschapv2_change_password(
struct eap_sm *sm, struct eap_mschapv2_data *data,
struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id)
{
+#ifdef CONFIG_NO_RC4
+ wpa_printf(MSG_ERROR,
+ "EAP-MSCHAPV2: RC4 not support in the build - cannot change password");
+ return NULL;
+#else /* CONFIG_NO_RC4 */
struct wpabuf *resp;
int ms_len;
const u8 *username, *password, *new_password;
@@ -628,6 +633,7 @@ static struct wpabuf * eap_mschapv2_change_password(
fail:
wpabuf_free(resp);
return NULL;
+#endif /* CONFIG_NO_RC4 */
}
diff --git a/src/eap_peer/eap_pax.c b/src/eap_peer/eap_pax.c
index 6d1ff208ac7ef..c920bcd3182f8 100644
--- a/src/eap_peer/eap_pax.c
+++ b/src/eap_peer/eap_pax.c
@@ -333,7 +333,7 @@ static struct wpabuf * eap_pax_process(struct eap_sm *sm, void *priv,
u16 flen, mlen;
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, reqData, &len);
- if (pos == NULL || len < EAP_PAX_ICV_LEN) {
+ if (pos == NULL || len < sizeof(*req) + EAP_PAX_ICV_LEN) {
ret->ignore = TRUE;
return NULL;
}
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 86a18bb866de4..98a48a6cf5d31 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -968,6 +968,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
struct wpabuf *resp;
const u8 *pos;
struct eap_peap_data *data = priv;
+ struct wpabuf msg;
pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_PEAP, ret,
reqData, &left, &flags);
@@ -998,18 +999,25 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
* should always be, anyway */
}
+ wpabuf_set(&msg, pos, left);
+
resp = NULL;
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
!data->resuming) {
- struct wpabuf msg;
- wpabuf_set(&msg, pos, left);
res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp);
} else {
res = eap_peer_tls_process_helper(sm, &data->ssl,
EAP_TYPE_PEAP,
- data->peap_version, id, pos,
- left, &resp);
+ data->peap_version, id, &msg,
+ &resp);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return resp;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
char *label;
wpa_printf(MSG_DEBUG,
@@ -1077,14 +1085,12 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
}
if (res == 2) {
- struct wpabuf msg;
/*
* Application data included in the handshake message.
*/
wpabuf_free(data->pending_phase2_req);
data->pending_phase2_req = resp;
resp = NULL;
- wpabuf_set(&msg, pos, left);
res = eap_peap_decrypt(sm, data, ret, req, &msg,
&resp);
}
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 059bbeecb72da..1f785443ee5ac 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -10,6 +10,7 @@
#include "common.h"
#include "crypto/sha256.h"
+#include "crypto/ms_funcs.h"
#include "eap_peer/eap_i.h"
#include "eap_common/eap_pwd_common.h"
@@ -25,6 +26,7 @@ struct eap_pwd_data {
size_t id_server_len;
u8 *password;
size_t password_len;
+ int password_hash;
u16 group_num;
EAP_PWD_group *grp;
@@ -86,8 +88,9 @@ static void * eap_pwd_init(struct eap_sm *sm)
const u8 *identity, *password;
size_t identity_len, password_len;
int fragment_size;
+ int pwhash;
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (password == NULL) {
wpa_printf(MSG_INFO, "EAP-PWD: No password configured!");
return NULL;
@@ -129,6 +132,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
}
os_memcpy(data->password, password, password_len);
data->password_len = password_len;
+ data->password_hash = pwhash;
data->out_frag_pos = data->in_frag_pos = 0;
data->inbuf = data->outbuf = NULL;
@@ -216,6 +220,10 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
struct eap_pwd_id *id;
+ const u8 *password;
+ size_t password_len;
+ u8 pwhashhash[16];
+ int res;
if (data->state != PWD_ID_Req) {
ret->ignore = TRUE;
@@ -231,6 +239,9 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
id = (struct eap_pwd_id *) payload;
data->group_num = be_to_host16(id->group_num);
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u",
+ data->group_num, id->random_function, id->prf, id->prep);
if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
(id->prf != EAP_PWD_DEFAULT_PRF)) {
ret->ignore = TRUE;
@@ -238,6 +249,22 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
return;
}
+ if (id->prep != EAP_PWD_PREP_NONE &&
+ id->prep != EAP_PWD_PREP_MS) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Unsupported password pre-processing technique (Prep=%u)",
+ id->prep);
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
+ if (id->prep == EAP_PWD_PREP_NONE && data->password_hash) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Unhashed password not available");
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d",
data->group_num);
@@ -260,12 +287,46 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
return;
}
+ if (id->prep == EAP_PWD_PREP_MS) {
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR,
+ "EAP-PWD (peer): MS password hash not supported in FIPS mode");
+ eap_pwd_state(data, FAILURE);
+ return;
+#else /* CONFIG_FIPS */
+ if (data->password_hash) {
+ res = hash_nt_password_hash(data->password, pwhashhash);
+ } else {
+ u8 pwhash[16];
+
+ res = nt_password_hash(data->password,
+ data->password_len, pwhash);
+ if (res == 0)
+ res = hash_nt_password_hash(pwhash, pwhashhash);
+ os_memset(pwhash, 0, sizeof(pwhash));
+ }
+
+ if (res) {
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
+ password = pwhashhash;
+ password_len = sizeof(pwhashhash);
+#endif /* CONFIG_FIPS */
+ } else {
+ password = data->password;
+ password_len = data->password_len;
+ }
+
/* compute PWE */
- if (compute_password_element(data->grp, data->group_num,
- data->password, data->password_len,
- data->id_server, data->id_server_len,
- data->id_peer, data->id_peer_len,
- id->token)) {
+ res = compute_password_element(data->grp, data->group_num,
+ password, password_len,
+ data->id_server, data->id_server_len,
+ data->id_peer, data->id_peer_len,
+ id->token);
+ os_memset(pwhashhash, 0, sizeof(pwhashhash));
+ if (res) {
wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE");
eap_pwd_state(data, FAILURE);
return;
@@ -301,6 +362,23 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL;
u16 offset;
u8 *ptr, *scalar = NULL, *element = NULL;
+ size_t prime_len, order_len;
+
+ if (data->state != PWD_Commit_Req) {
+ ret->ignore = TRUE;
+ goto fin;
+ }
+
+ prime_len = BN_num_bytes(data->grp->prime);
+ order_len = BN_num_bytes(data->grp->order);
+
+ if (payload_len != 2 * prime_len + order_len) {
+ wpa_printf(MSG_INFO,
+ "EAP-pwd: Unexpected Commit payload length %u (expected %u)",
+ (unsigned int) payload_len,
+ (unsigned int) (2 * prime_len + order_len));
+ goto fin;
+ }
if (((data->private_value = BN_new()) == NULL) ||
((data->my_element = EC_POINT_new(data->grp->group)) == NULL) ||
@@ -500,6 +578,18 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
int offset;
+ if (data->state != PWD_Confirm_Req) {
+ ret->ignore = TRUE;
+ goto fin;
+ }
+
+ if (payload_len != SHA256_MAC_LEN) {
+ wpa_printf(MSG_INFO,
+ "EAP-pwd: Unexpected Confirm payload length %u (expected %u)",
+ (unsigned int) payload_len, SHA256_MAC_LEN);
+ goto fin;
+ }
+
/*
* first build up the ciphersuite which is group | random_function |
* prf
@@ -783,17 +873,30 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
* if it's the first fragment there'll be a length field
*/
if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) {
+ if (len < 2) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-pwd: Frame too short to contain Total-Length field");
+ ret->ignore = TRUE;
+ return NULL;
+ }
tot_len = WPA_GET_BE16(pos);
wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments whose "
"total length = %d", tot_len);
if (tot_len > 15000)
return NULL;
+ if (data->inbuf) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-pwd: Unexpected new fragment start when previous fragment is still in use");
+ ret->ignore = TRUE;
+ return NULL;
+ }
data->inbuf = wpabuf_alloc(tot_len);
if (data->inbuf == NULL) {
wpa_printf(MSG_INFO, "Out of memory to buffer "
"fragments!");
return NULL;
}
+ data->in_frag_pos = 0;
pos += sizeof(u16);
len -= sizeof(u16);
}
@@ -873,6 +976,7 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
/*
* we have output! Do we need to fragment it?
*/
+ lm_exch = EAP_PWD_GET_EXCHANGE(lm_exch);
len = wpabuf_len(data->outbuf);
if ((len + EAP_PWD_HDR_SIZE) > data->mtu) {
resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, data->mtu,
diff --git a/src/eap_peer/eap_sake.c b/src/eap_peer/eap_sake.c
index 7d14907433e50..c4f9843febb35 100644
--- a/src/eap_peer/eap_sake.c
+++ b/src/eap_peer/eap_sake.c
@@ -141,7 +141,7 @@ static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data,
static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm,
struct eap_sake_data *data,
struct eap_method_ret *ret,
- const struct wpabuf *reqData,
+ u8 id,
const u8 *payload,
size_t payload_len)
{
@@ -166,8 +166,7 @@ static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm,
wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity");
- resp = eap_sake_build_msg(data, eap_get_id(reqData),
- 2 + data->peerid_len,
+ resp = eap_sake_build_msg(data, id, 2 + data->peerid_len,
EAP_SAKE_SUBTYPE_IDENTITY);
if (resp == NULL)
return NULL;
@@ -185,7 +184,7 @@ static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm,
static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm,
struct eap_sake_data *data,
struct eap_method_ret *ret,
- const struct wpabuf *reqData,
+ u8 id,
const u8 *payload,
size_t payload_len)
{
@@ -247,8 +246,7 @@ static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm,
rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN;
if (data->peerid)
rlen += 2 + data->peerid_len;
- resp = eap_sake_build_msg(data, eap_get_id(reqData), rlen,
- EAP_SAKE_SUBTYPE_CHALLENGE);
+ resp = eap_sake_build_msg(data, id, rlen, EAP_SAKE_SUBTYPE_CHALLENGE);
if (resp == NULL)
return NULL;
@@ -285,6 +283,7 @@ static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm,
static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm,
struct eap_sake_data *data,
struct eap_method_ret *ret,
+ u8 id,
const struct wpabuf *reqData,
const u8 *payload,
size_t payload_len)
@@ -323,14 +322,13 @@ static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm,
ret->allowNotifications = FALSE;
wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending "
"Response/Auth-Reject");
- return eap_sake_build_msg(data, eap_get_id(reqData), 0,
+ return eap_sake_build_msg(data, id, 0,
EAP_SAKE_SUBTYPE_AUTH_REJECT);
}
wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm");
- resp = eap_sake_build_msg(data, eap_get_id(reqData),
- 2 + EAP_SAKE_MIC_LEN,
+ resp = eap_sake_build_msg(data, id, 2 + EAP_SAKE_MIC_LEN,
EAP_SAKE_SUBTYPE_CONFIRM);
if (resp == NULL)
return NULL;
@@ -367,7 +365,7 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv,
struct wpabuf *resp;
const u8 *pos, *end;
size_t len;
- u8 subtype, session_id;
+ u8 subtype, session_id, id;
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len);
if (pos == NULL || len < sizeof(struct eap_sake_hdr)) {
@@ -377,6 +375,7 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv,
req = (const struct eap_sake_hdr *) pos;
end = pos + len;
+ id = eap_get_id(reqData);
subtype = req->subtype;
session_id = req->session_id;
pos = (const u8 *) (req + 1);
@@ -402,15 +401,15 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv,
switch (subtype) {
case EAP_SAKE_SUBTYPE_IDENTITY:
- resp = eap_sake_process_identity(sm, data, ret, reqData,
+ resp = eap_sake_process_identity(sm, data, ret, id,
pos, end - pos);
break;
case EAP_SAKE_SUBTYPE_CHALLENGE:
- resp = eap_sake_process_challenge(sm, data, ret, reqData,
+ resp = eap_sake_process_challenge(sm, data, ret, id,
pos, end - pos);
break;
case EAP_SAKE_SUBTYPE_CONFIRM:
- resp = eap_sake_process_confirm(sm, data, ret, reqData,
+ resp = eap_sake_process_confirm(sm, data, ret, id, reqData,
pos, end - pos);
break;
default:
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index bd06df78db4c4..99a2816ce61ed 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -1042,7 +1042,7 @@ static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv,
}
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len);
- if (pos == NULL || len < 1) {
+ if (pos == NULL || len < 3) {
ret->ignore = TRUE;
return NULL;
}
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index 5aa3fd5912563..66a027a626e0d 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -156,20 +156,6 @@ static struct wpabuf * eap_tls_failure(struct eap_sm *sm,
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
- if (res == -1) {
- struct eap_peer_config *config = eap_get_config(sm);
- if (config) {
- /*
- * The TLS handshake failed. So better forget the old
- * PIN. It may be wrong, we cannot be sure but trying
- * the wrong one again might block it on the card--so
- * better ask the user again.
- */
- os_free(config->pin);
- config->pin = NULL;
- }
- }
-
if (resp) {
/*
* This is likely an alert message, so send it instead of just
@@ -228,6 +214,7 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
u8 flags, id;
const u8 *pos;
struct eap_tls_data *data = priv;
+ struct wpabuf msg;
pos = eap_peer_tls_process_init(sm, &data->ssl, data->eap_type, ret,
reqData, &left, &flags);
@@ -242,8 +229,9 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
}
resp = NULL;
+ wpabuf_set(&msg, pos, left);
res = eap_peer_tls_process_helper(sm, &data->ssl, data->eap_type, 0,
- id, pos, left, &resp);
+ id, &msg, &resp);
if (res < 0) {
return eap_tls_failure(sm, data, ret, res, resp, id);
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 8710781618eff..af2b7541d7016 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -68,6 +68,10 @@ static void eap_tls_params_flags(struct tls_connection_params *params,
params->flags |= TLS_CONN_DISABLE_SESSION_TICKET;
if (os_strstr(txt, "tls_disable_session_ticket=0"))
params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET;
+ if (os_strstr(txt, "tls_disable_tlsv1_0=1"))
+ params->flags |= TLS_CONN_DISABLE_TLSv1_0;
+ if (os_strstr(txt, "tls_disable_tlsv1_0=0"))
+ params->flags &= ~TLS_CONN_DISABLE_TLSv1_0;
if (os_strstr(txt, "tls_disable_tlsv1_1=1"))
params->flags |= TLS_CONN_DISABLE_TLSv1_1;
if (os_strstr(txt, "tls_disable_tlsv1_1=0"))
@@ -196,28 +200,25 @@ static int eap_tls_init_connection(struct eap_sm *sm,
}
res = tls_connection_set_params(data->ssl_ctx, data->conn, params);
- if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
+ if (res == TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN) {
/*
- * At this point with the pkcs11 engine the PIN might be wrong.
- * We reset the PIN in the configuration to be sure to not use
- * it again and the calling function must request a new one.
+ * At this point with the pkcs11 engine the PIN is wrong. We
+ * reset the PIN in the configuration to be sure to not use it
+ * again and the calling function must request a new one.
*/
+ wpa_printf(MSG_INFO,
+ "TLS: Bad PIN provided, requesting a new one");
os_free(config->pin);
config->pin = NULL;
+ eap_sm_request_pin(sm);
+ sm->ignore = TRUE;
+ } else if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
+ wpa_printf(MSG_INFO, "TLS: Failed to initialize engine");
} else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) {
wpa_printf(MSG_INFO, "TLS: Failed to load private key");
- /*
- * We do not know exactly but maybe the PIN was wrong,
- * so ask for a new one.
- */
- os_free(config->pin);
- config->pin = NULL;
- eap_sm_request_pin(sm);
sm->ignore = TRUE;
- tls_connection_deinit(data->ssl_ctx, data->conn);
- data->conn = NULL;
- return -1;
- } else if (res) {
+ }
+ if (res) {
wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
"parameters");
tls_connection_deinit(data->ssl_ctx, data->conn);
@@ -313,53 +314,19 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
const char *label, size_t len)
{
-#ifndef CONFIG_FIPS
- struct tls_keys keys;
-#endif /* CONFIG_FIPS */
- u8 *rnd = NULL, *out;
+ u8 *out;
out = os_malloc(len);
if (out == NULL)
return NULL;
- /* First, try to use TLS library function for PRF, if available. */
- if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len)
- == 0)
- return out;
-
-#ifndef CONFIG_FIPS
- /*
- * TLS library did not support key generation, so get the needed TLS
- * session parameters and use an internal implementation of TLS PRF to
- * derive the key.
- */
- if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys))
- goto fail;
-
- if (keys.client_random == NULL || keys.server_random == NULL ||
- keys.master_key == NULL)
- goto fail;
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
- os_memcpy(rnd, keys.client_random, keys.client_random_len);
- os_memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
- goto fail;
+ if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, 0,
+ out, len)) {
+ os_free(out);
+ return NULL;
+ }
- os_free(rnd);
return out;
-
-fail:
-#endif /* CONFIG_FIPS */
- os_free(out);
- os_free(rnd);
- return NULL;
}
@@ -380,10 +347,10 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
struct eap_ssl_data *data, u8 eap_type,
size_t *len)
{
- struct tls_keys keys;
+ struct tls_random keys;
u8 *out;
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
+ if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys))
return NULL;
if (keys.client_random == NULL || keys.server_random == NULL)
@@ -514,22 +481,19 @@ static const struct wpabuf * eap_peer_tls_data_reassemble(
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @data: Data for TLS processing
* @in_data: Message received from the server
- * @in_len: Length of in_data
* @out_data: Buffer for returning a pointer to application data (if available)
* Returns: 0 on success, 1 if more input data is needed, 2 if application data
* is available, -1 on failure
*/
static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
- const u8 *in_data, size_t in_len,
+ const struct wpabuf *in_data,
struct wpabuf **out_data)
{
const struct wpabuf *msg;
int need_more_input;
struct wpabuf *appl_data;
- struct wpabuf buf;
- wpabuf_set(&buf, in_data, in_len);
- msg = eap_peer_tls_data_reassemble(data, &buf, &need_more_input);
+ msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input);
if (msg == NULL)
return need_more_input ? 1 : -1;
@@ -649,7 +613,6 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
* @peap_version: Version number for EAP-PEAP/TTLS
* @id: EAP identifier for the response
* @in_data: Message received from the server
- * @in_len: Length of in_data
* @out_data: Buffer for returning a pointer to the response message
* Returns: 0 on success, 1 if more input data is needed, 2 if application data
* is available, or -1 on failure
@@ -672,14 +635,15 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
*/
int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
EapType eap_type, int peap_version,
- u8 id, const u8 *in_data, size_t in_len,
+ u8 id, const struct wpabuf *in_data,
struct wpabuf **out_data)
{
int ret = 0;
*out_data = NULL;
- if (data->tls_out && wpabuf_len(data->tls_out) > 0 && in_len > 0) {
+ if (data->tls_out && wpabuf_len(data->tls_out) > 0 &&
+ wpabuf_len(in_data) > 0) {
wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output "
"fragments are waiting to be sent out");
return -1;
@@ -690,8 +654,7 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
* No more data to send out - expect to receive more data from
* the AS.
*/
- int res = eap_tls_process_input(sm, data, in_data, in_len,
- out_data);
+ int res = eap_tls_process_input(sm, data, in_data, out_data);
if (res) {
/*
* Input processing failed (res = -1) or more data is
@@ -719,12 +682,18 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
if (tls_connection_get_failed(data->ssl_ctx, data->conn)) {
/* TLS processing has failed - return error */
wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
- "report error");
+ "report error (len=%u)",
+ (unsigned int) wpabuf_len(data->tls_out));
ret = -1;
/* TODO: clean pin if engine used? */
+ if (wpabuf_len(data->tls_out) == 0) {
+ wpabuf_free(data->tls_out);
+ data->tls_out = NULL;
+ return -1;
+ }
}
- if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) {
+ if (wpabuf_len(data->tls_out) == 0) {
/*
* TLS negotiation should now be complete since all other cases
* needing more data should have been caught above based on
@@ -790,20 +759,24 @@ int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data)
int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
char *buf, size_t buflen, int verbose)
{
- char name[128];
+ char version[20], name[128];
int len = 0, ret;
- if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) == 0)
- {
- ret = os_snprintf(buf + len, buflen - len,
- "EAP TLS cipher=%s\n"
- "tls_session_reused=%d\n",
- name, tls_connection_resumed(data->ssl_ctx,
- data->conn));
- if (os_snprintf_error(buflen - len, ret))
- return len;
- len += ret;
- }
+ if (tls_get_version(data->ssl_ctx, data->conn, version,
+ sizeof(version)) < 0)
+ version[0] = '\0';
+ if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) < 0)
+ name[0] = '\0';
+
+ ret = os_snprintf(buf + len, buflen - len,
+ "eap_tls_version=%s\n"
+ "EAP TLS cipher=%s\n"
+ "tls_session_reused=%d\n",
+ version, name,
+ tls_connection_resumed(data->ssl_ctx, data->conn));
+ if (os_snprintf_error(buflen - len, ret))
+ return len;
+ len += ret;
return len;
}
@@ -1032,7 +1005,7 @@ int eap_peer_select_phase2_methods(struct eap_peer_config *config,
{
char *start, *pos, *buf;
struct eap_method_type *methods = NULL, *_methods;
- u8 method;
+ u32 method;
size_t num_methods = 0, prefix_len;
if (config == NULL || config->phase2 == NULL)
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 390c2165927cb..acd2b783617fe 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -100,7 +100,7 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
size_t *len);
int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
EapType eap_type, int peap_version,
- u8 id, const u8 *in_data, size_t in_len,
+ u8 id, const struct wpabuf *in_data,
struct wpabuf **out_data);
struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type,
int peap_version);
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index b5c028b5276d5..b186c9156a741 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -175,7 +175,8 @@ static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
}
avp->avp_code = host_to_be32(avp_code);
- avp->avp_length = host_to_be32((flags << 24) | (u32) (hdrlen + len));
+ avp->avp_length = host_to_be32(((u32) flags << 24) |
+ (u32) (hdrlen + len));
return avphdr + hdrlen;
}
@@ -253,11 +254,13 @@ static int eap_ttls_v0_derive_key(struct eap_sm *sm,
}
+#ifndef CONFIG_FIPS
static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
struct eap_ttls_data *data, size_t len)
{
return eap_peer_tls_derive_key(sm, &data->ssl, "ttls challenge", len);
}
+#endif /* CONFIG_FIPS */
static void eap_ttls_phase2_select_eap_method(struct eap_ttls_data *data,
@@ -428,6 +431,10 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPV2 not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
#ifdef EAP_MSCHAPv2
struct wpabuf *msg;
u8 *buf, *pos, *challenge, *peer_challenge;
@@ -510,6 +517,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAPv2 not included in the build");
return -1;
#endif /* EAP_MSCHAPv2 */
+#endif /* CONFIG_FIPS */
}
@@ -518,6 +526,10 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: MSCHAP not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
struct wpabuf *msg;
u8 *buf, *pos, *challenge;
const u8 *identity, *password;
@@ -592,6 +604,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
ret->decision = DECISION_COND_SUCC;
return 0;
+#endif /* CONFIG_FIPS */
}
@@ -654,6 +667,10 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
struct eap_method_ret *ret,
struct wpabuf **resp)
{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "EAP-TTLS: CHAP not supported in FIPS build");
+ return -1;
+#else /* CONFIG_FIPS */
struct wpabuf *msg;
u8 *buf, *pos, *challenge;
const u8 *identity, *password;
@@ -722,6 +739,7 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
ret->decision = DECISION_COND_SUCC;
return 0;
+#endif /* CONFIG_FIPS */
}
@@ -1385,14 +1403,20 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
struct eap_ttls_data *data,
struct eap_method_ret *ret,
u8 identifier,
- const u8 *in_data, size_t in_len,
+ const struct wpabuf *in_data,
struct wpabuf **out_data)
{
int res;
res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
data->ttls_version, identifier,
- in_data, in_len, out_data);
+ in_data, out_data);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS processing failed");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return -1;
+ }
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
@@ -1419,15 +1443,13 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
}
if (res == 2) {
- struct wpabuf msg;
/*
* Application data included in the handshake message.
*/
wpabuf_free(data->pending_phase2_req);
data->pending_phase2_req = *out_data;
*out_data = NULL;
- wpabuf_set(&msg, in_data, in_len);
- res = eap_ttls_decrypt(sm, data, ret, identifier, &msg,
+ res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
out_data);
}
@@ -1477,6 +1499,7 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
struct wpabuf *resp;
const u8 *pos;
struct eap_ttls_data *data = priv;
+ struct wpabuf msg;
pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
reqData, &left, &flags);
@@ -1497,15 +1520,15 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
left = 0;
}
+ wpabuf_set(&msg, pos, left);
+
resp = NULL;
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
!data->resuming) {
- struct wpabuf msg;
- wpabuf_set(&msg, pos, left);
res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
} else {
res = eap_ttls_process_handshake(sm, data, ret, id,
- pos, left, &resp);
+ &msg, &resp);
}
eap_ttls_check_auth_status(sm, data, ret);
diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c
index 7ce0a53d0b299..7ac99c7ce727b 100644
--- a/src/eap_peer/eap_wsc.c
+++ b/src/eap_peer/eap_wsc.c
@@ -557,6 +557,9 @@ send_msg:
if (data->out_buf == NULL) {
wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to receive "
"message from WPS");
+ eap_wsc_state(data, FAIL);
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
return NULL;
}
data->out_used = 0;