mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 18:28:23 -05:00
EAP peer: Clear temporary message buffers before freeing
These buffers in TLS-based EAP methods might contain keys or password (e.g., when using TTLS-PAP or PEAP-GTC), so clear them explicitly to avoid leaving such material into heap memory unnecessarily. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
8f99a3c26a
commit
789b48bb48
@ -250,8 +250,8 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv)
|
||||
os_memset(data->key_data, 0, EAP_FAST_KEY_LEN);
|
||||
os_memset(data->emsk, 0, EAP_EMSK_LEN);
|
||||
os_free(data->session_id);
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
@ -486,7 +486,7 @@ static int eap_fast_phase2_request(struct eap_sm *sm,
|
||||
(config->pending_req_identity || config->pending_req_password ||
|
||||
config->pending_req_otp || config->pending_req_new_password ||
|
||||
config->pending_req_sim)) {
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
|
||||
} else if (*resp == NULL)
|
||||
return -1;
|
||||
@ -801,7 +801,7 @@ static struct wpabuf * eap_fast_process_crypto_binding(
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
data->phase2_success = 0;
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -815,7 +815,7 @@ static struct wpabuf * eap_fast_process_crypto_binding(
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "EAP-FAST: Failed to derive "
|
||||
"Session-Id");
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1150,7 +1150,7 @@ static int eap_fast_encrypt_response(struct eap_sm *sm,
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
|
||||
"frame");
|
||||
}
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1328,14 +1328,14 @@ continue_req:
|
||||
wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
|
||||
"TLV frame (len=%lu)",
|
||||
(unsigned long) wpabuf_len(in_decrypted));
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = eap_fast_process_decrypted(sm, data, ret, identifier,
|
||||
in_decrypted, out_data);
|
||||
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1613,7 +1613,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
if (sm->waiting_ext_cert_check) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-FAST: Waiting external server certificate validation");
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = resp;
|
||||
return NULL;
|
||||
}
|
||||
@ -1641,7 +1641,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
"EAP-FAST: Could not derive keys");
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1650,7 +1650,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
/*
|
||||
* Application data included in the handshake message.
|
||||
*/
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = resp;
|
||||
resp = NULL;
|
||||
res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp);
|
||||
@ -1658,7 +1658,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
|
||||
}
|
||||
|
||||
if (res == 1) {
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return eap_peer_tls_build_ack(id, EAP_TYPE_FAST,
|
||||
data->fast_version);
|
||||
}
|
||||
@ -1684,9 +1684,9 @@ static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
|
||||
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
|
||||
os_free(data->key_block_p);
|
||||
data->key_block_p = NULL;
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = NULL;
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = NULL;
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,8 @@ static void eap_peap_deinit(struct eap_sm *sm, void *priv)
|
||||
eap_peer_tls_ssl_deinit(sm, &data->ssl);
|
||||
eap_peap_free_key(data);
|
||||
os_free(data->session_id);
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
bin_clear_free(data, sizeof(*data));
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ static struct wpabuf * eap_tlv_build_result(struct eap_sm *sm,
|
||||
wpabuf_put_be16(msg, status); /* Status */
|
||||
|
||||
if (crypto_tlv_used && eap_tlv_add_cryptobinding(sm, data, msg)) {
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -654,11 +654,11 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
|
||||
if (*resp == NULL) {
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
wpabuf_free(buf);
|
||||
wpabuf_clear_free(buf);
|
||||
return -1;
|
||||
}
|
||||
wpabuf_put_buf(*resp, buf);
|
||||
wpabuf_free(buf);
|
||||
wpabuf_clear_free(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -731,7 +731,7 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
|
||||
(config->pending_req_identity || config->pending_req_password ||
|
||||
config->pending_req_otp || config->pending_req_new_password ||
|
||||
config->pending_req_sim)) {
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
|
||||
}
|
||||
|
||||
@ -810,7 +810,7 @@ continue_req:
|
||||
struct wpabuf *nmsg = wpabuf_alloc(sizeof(struct eap_hdr) +
|
||||
wpabuf_len(in_decrypted));
|
||||
if (nmsg == NULL) {
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return 0;
|
||||
}
|
||||
nhdr = wpabuf_put(nmsg, sizeof(*nhdr));
|
||||
@ -820,7 +820,7 @@ continue_req:
|
||||
nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
|
||||
wpabuf_len(in_decrypted));
|
||||
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
in_decrypted = nmsg;
|
||||
}
|
||||
|
||||
@ -829,7 +829,7 @@ continue_req:
|
||||
wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
|
||||
"EAP frame (len=%lu)",
|
||||
(unsigned long) wpabuf_len(in_decrypted));
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return 0;
|
||||
}
|
||||
len = be_to_host16(hdr->length);
|
||||
@ -838,7 +838,7 @@ continue_req:
|
||||
"Phase 2 EAP frame (len=%lu hdr->length=%lu)",
|
||||
(unsigned long) wpabuf_len(in_decrypted),
|
||||
(unsigned long) len);
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return 0;
|
||||
}
|
||||
if (len < wpabuf_len(in_decrypted)) {
|
||||
@ -855,7 +855,7 @@ continue_req:
|
||||
case EAP_CODE_REQUEST:
|
||||
if (eap_peap_phase2_request(sm, data, ret, in_decrypted,
|
||||
&resp)) {
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
wpa_printf(MSG_INFO, "EAP-PEAP: Phase2 Request "
|
||||
"processing failed");
|
||||
return 0;
|
||||
@ -875,7 +875,7 @@ continue_req:
|
||||
"completed successfully");
|
||||
ret->methodState = METHOD_DONE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return 0;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Version 1 - "
|
||||
@ -885,7 +885,7 @@ continue_req:
|
||||
ret->methodState = METHOD_DONE;
|
||||
data->phase2_success = 1;
|
||||
if (data->peap_outer_success == 2) {
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Use TLS ACK "
|
||||
"to finish authentication");
|
||||
return 1;
|
||||
@ -931,7 +931,7 @@ continue_req:
|
||||
break;
|
||||
}
|
||||
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
|
||||
if (resp) {
|
||||
int skip_change2 = 0;
|
||||
@ -958,7 +958,7 @@ continue_req:
|
||||
wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt "
|
||||
"a Phase 2 frame");
|
||||
}
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1059,7 +1059,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
|
||||
if (sm->waiting_ext_cert_check) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PEAP: Waiting external server certificate validation");
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = resp;
|
||||
return NULL;
|
||||
}
|
||||
@ -1140,7 +1140,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
|
||||
/*
|
||||
* Application data included in the handshake message.
|
||||
*/
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = resp;
|
||||
resp = NULL;
|
||||
res = eap_peap_decrypt(sm, data, ret, req, &msg,
|
||||
@ -1153,7 +1153,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
|
||||
}
|
||||
|
||||
if (res == 1) {
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return eap_peer_tls_build_ack(id, EAP_TYPE_PEAP,
|
||||
data->peap_version);
|
||||
}
|
||||
@ -1177,9 +1177,9 @@ static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv)
|
||||
if (data->phase2_priv && data->phase2_method &&
|
||||
data->phase2_method->deinit_for_reauth)
|
||||
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = NULL;
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = NULL;
|
||||
data->crypto_binding_used = 0;
|
||||
}
|
||||
|
@ -196,8 +196,8 @@ static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
|
||||
eap_peer_tls_ssl_deinit(sm, &data->ssl);
|
||||
eap_ttls_free_key(data);
|
||||
os_free(data->session_id);
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
os_free(data);
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
|
||||
|
||||
msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
|
||||
if (msg == NULL) {
|
||||
wpabuf_free(*resp);
|
||||
wpabuf_clear_free(*resp);
|
||||
*resp = NULL;
|
||||
return -1;
|
||||
}
|
||||
@ -258,7 +258,7 @@ static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
|
||||
os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
|
||||
pos += wpabuf_len(*resp);
|
||||
AVP_PAD(avp, pos);
|
||||
wpabuf_free(*resp);
|
||||
wpabuf_clear_free(*resp);
|
||||
wpabuf_put(msg, pos - avp);
|
||||
*resp = msg;
|
||||
return 0;
|
||||
@ -510,7 +510,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
|
||||
challenge = eap_ttls_implicit_challenge(
|
||||
sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
|
||||
if (challenge == NULL) {
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
|
||||
"implicit challenge");
|
||||
return -1;
|
||||
@ -529,7 +529,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
|
||||
*pos++ = 0; /* Flags */
|
||||
if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
|
||||
os_free(challenge);
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
|
||||
"random data for peer challenge");
|
||||
return -1;
|
||||
@ -543,7 +543,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
|
||||
peer_challenge, pos, data->auth_response,
|
||||
data->master_key)) {
|
||||
os_free(challenge);
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
|
||||
"response");
|
||||
return -1;
|
||||
@ -604,7 +604,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
|
||||
challenge = eap_ttls_implicit_challenge(
|
||||
sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
|
||||
if (challenge == NULL) {
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
|
||||
"implicit challenge");
|
||||
return -1;
|
||||
@ -628,7 +628,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
|
||||
if (challenge_response(challenge, password, pos)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"EAP-TTLS/MSCHAP: Failed derive password hash");
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
os_free(challenge);
|
||||
return -1;
|
||||
}
|
||||
@ -641,7 +641,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
|
||||
pos)) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"EAP-TTLS/MSCHAP: Failed derive password");
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
os_free(challenge);
|
||||
return -1;
|
||||
}
|
||||
@ -760,7 +760,7 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
|
||||
challenge = eap_ttls_implicit_challenge(
|
||||
sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
|
||||
if (challenge == NULL) {
|
||||
wpabuf_free(msg);
|
||||
wpabuf_clear_free(msg);
|
||||
wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
|
||||
"implicit challenge");
|
||||
return -1;
|
||||
@ -1073,10 +1073,10 @@ static int eap_ttls_encrypt_response(struct eap_sm *sm,
|
||||
resp, out_data)) {
|
||||
wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
|
||||
"frame");
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return -1;
|
||||
}
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1297,7 +1297,7 @@ static int eap_ttls_process_decrypted(struct eap_sm *sm,
|
||||
config->pending_req_otp ||
|
||||
config->pending_req_new_password ||
|
||||
config->pending_req_sim) {
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = wpabuf_dup(in_decrypted);
|
||||
}
|
||||
|
||||
@ -1340,7 +1340,7 @@ static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
|
||||
* processing when EAP request is re-processed after
|
||||
* user input.
|
||||
*/
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = wpabuf_alloc(0);
|
||||
}
|
||||
|
||||
@ -1413,7 +1413,7 @@ static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
|
||||
in_decrypted = data->pending_phase2_req;
|
||||
data->pending_phase2_req = NULL;
|
||||
if (wpabuf_len(in_decrypted) == 0) {
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
return eap_ttls_implicit_identity_request(
|
||||
sm, data, ret, identifier, out_data);
|
||||
}
|
||||
@ -1449,7 +1449,7 @@ continue_req:
|
||||
&parse, in_decrypted, out_data);
|
||||
|
||||
done:
|
||||
wpabuf_free(in_decrypted);
|
||||
wpabuf_clear_free(in_decrypted);
|
||||
os_free(parse.eapdata);
|
||||
|
||||
if (retval < 0) {
|
||||
@ -1509,7 +1509,7 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
|
||||
if (sm->waiting_ext_cert_check) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-TTLS: Waiting external server certificate validation");
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = *out_data;
|
||||
*out_data = NULL;
|
||||
return 0;
|
||||
@ -1543,7 +1543,7 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
|
||||
/*
|
||||
* Application data included in the handshake message.
|
||||
*/
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = *out_data;
|
||||
*out_data = NULL;
|
||||
res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
|
||||
@ -1646,7 +1646,7 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
|
||||
/* FIX: what about res == -1? Could just move all error processing into
|
||||
* the other functions and get rid of this res==1 case here. */
|
||||
if (res == 1) {
|
||||
wpabuf_free(resp);
|
||||
wpabuf_clear_free(resp);
|
||||
return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
|
||||
data->ttls_version);
|
||||
}
|
||||
@ -1669,9 +1669,9 @@ static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
|
||||
if (data->phase2_priv && data->phase2_method &&
|
||||
data->phase2_method->deinit_for_reauth)
|
||||
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
|
||||
wpabuf_free(data->pending_phase2_req);
|
||||
wpabuf_clear_free(data->pending_phase2_req);
|
||||
data->pending_phase2_req = NULL;
|
||||
wpabuf_free(data->pending_resp);
|
||||
wpabuf_clear_free(data->pending_resp);
|
||||
data->pending_resp = NULL;
|
||||
data->decision_succ = DECISION_FAIL;
|
||||
#ifdef EAP_TNC
|
||||
|
Loading…
Reference in New Issue
Block a user