]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP peer: Clear temporary message buffers before freeing
authorJouni Malinen <jouni@codeaurora.org>
Tue, 5 Feb 2019 18:26:50 +0000 (20:26 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 5 Feb 2019 21:34:30 +0000 (23:34 +0200)
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>
src/eap_peer/eap_fast.c
src/eap_peer/eap_peap.c
src/eap_peer/eap_ttls.c

index 74cec7dd583f8b660b8a8cd034fbe8b4393185dd..94ce57d6219f207937035da4facfedaab7e1ecc3 100644 (file)
@@ -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;
 }
 
index 0a756b1d7cce524ca9a9dee6aa1e40e728fbb6ec..650bea6ada2f4235e23b018505a1166cb0b38884 100644 (file)
@@ -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;
 }
index f18788ce8cb5c86b57b0fc2af2424a39d8c6c20a..5d267010e2fbd04473e8b297dfc1f82ea8ab6618 100644 (file)
@@ -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