Cumulative patch from commit e376290c667e970d751acc916e0efe2ed16292ed

e376290 HS 2.0R2: Add update_identifier field to network
5bc2857 Fix some sparse warnings about u16 vs. le16
42619d6 Fix CTRL-EVENT-REGDOM-CHANGE event init= value
a520bf4 Mark function static
0cb79d3 dbus: Fix indentation level to match code logic
8f03ac9 Mark functions static
6891f0e Allow SCAN command to specify scan_ssid=1 SSIDs
18389ab WPS: Clear keys/PINs explicitly
b7175b4 Clear hostapd configuration keys explicitly
d1ecca6 HS 2.0 R2: Clear hs20-osu-client configuration keys explicitly
0a13e06 EAP server: Clear keying material on deinit
f534ee0 EAP peer: Clear keying material on deinit
19c48da Clear wpa_supplicant configuration keys explicitly
28bfa29 EAP-AKA: Remove unnecessary dead increment
62493df EAP-GPSK: Avoid dead increment by checking pos pointer
164a453 FT: Debug print extra response data
70bfc77 PCSC: Debug print extra response data
5dbbf36 Interworking: Remove unnecessary dead increment
a1e46f3 Check for no key_mgmt/proto/auth_alg entries in config writer
290ea6a Remove unnecessary tracking of first entry
d3fa2bb WFD: Explicit limit for subelement length (CID 68127)
745ef18 HS 2.0: Verify assoc_req_ie buffer size for indication elements
0233dca SAE: Use os_memcmp_const() for hash/password comparisons
34ef46c WEP shared key: Use os_memcmp_const() for hash/password comparisons
3e4b77c EAP-GTC: Use os_memcmp_const() for hash/password comparisons
a6eae3f EAP-MSCHAPv2: Use os_memcmp_const() for hash/password comparisons
30411b3 EAP-TTLS: Use os_memcmp_const() for hash/password comparisons
a564d9c EAP-MD5: Use os_memcmp_const() for hash/password comparisons
4685482 EAP-PSK: Use os_memcmp_const() for hash/password comparisons
cba0f86 EAP-PEAP: Use os_memcmp_const() for hash/password comparisons
7b1e745 EAP-LEAP: Use os_memcmp_const() for hash/password comparisons
8f92826 EAP-GPSK: Use os_memcmp_const() for hash/password comparisons
e1550d4 EAP-PAX: Use os_memcmp_const() for hash/password comparisons
c434503 EAP-FAST: Use os_memcmp_const() for hash/password comparisons
dddf7bb EAP-EKE: Use os_memcmp_const() for hash/password comparisons
dfb5608 EAP-SAKE: Use os_memcmp_const() for hash/password comparisons
05c79d6 EAP-SIM/AKA: Use os_memcmp_const() for hash/password comparisons
675ddad EAP-IKEv2: Use os_memcmp_const() for hash/password comparisons
2049a3c TLS: Use os_memcmp_const() for hash/password comparisons
a79aea5 Milenage: Use os_memcmp_const() for hash/password comparisons
05f916e AES-GCM: Use os_memcmp_const() for hash/password comparisons
87a5c93 AES-CCM: Use os_memcmp_const() for hash/password comparisons
7c24f53 EAPOL supplicant: Use os_memcmp_const() for hash/password comparisons
870834a RSN authenticator: Use os_memcmp_const() for hash/password comparisons
0d15b69 RSN supplicant: Use os_memcmp_const() for hash/password comparisons
72619ce MACsec: Use os_memcmp_const() for hash/password comparisons
c237195 RADIUS: Use os_memcmp_const() for hash/password comparisons
ce9c9bc WPS: Use os_memcmp_const() for hash/password comparisons
afc3c8b Add constant time memory comparison function os_memcmp_const
ee352f1 EAP-pwd: Add explicit total length limit
b2b8a4c EAP-SIM/AKA: Pass EAP type as argument to eap_sim_msg_finish()
f107d00 PeerKey: Clean up EAPOL-Key Key Data processing
010fc5f dbus: Clean up array-array-type property getter

Change-Id: I1dbe483be2678a7468e6955d70ea261f8e53b26d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 47cbbee..a2faeb2 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -92,6 +92,15 @@
 }
 
 
+static void eap_sm_free_key(struct eap_sm *sm)
+{
+	if (sm->eapKeyData) {
+		bin_clear_free(sm->eapKeyData, sm->eapKeyDataLen);
+		sm->eapKeyData = NULL;
+	}
+}
+
+
 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
 {
 	ext_password_free(sm->ext_pw_buf);
@@ -159,8 +168,7 @@
 	eapol_set_int(sm, EAPOL_idleWhile, sm->ClientTimeout);
 	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
 	eapol_set_bool(sm, EAPOL_eapFail, FALSE);
-	os_free(sm->eapKeyData);
-	sm->eapKeyData = NULL;
+	eap_sm_free_key(sm);
 	os_free(sm->eapSessionId);
 	sm->eapSessionId = NULL;
 	sm->eapKeyAvailable = FALSE;
@@ -404,7 +412,7 @@
 
 	if (sm->m->isKeyAvailable && sm->m->getKey &&
 	    sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
-		os_free(sm->eapKeyData);
+		eap_sm_free_key(sm);
 		sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
 					       &sm->eapKeyDataLen);
 		os_free(sm->eapSessionId);
@@ -1488,8 +1496,7 @@
 	sm->lastRespData = NULL;
 	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
-	os_free(sm->eapKeyData);
-	sm->eapKeyData = NULL;
+	eap_sm_free_key(sm);
 	os_free(sm->eapSessionId);
 	sm->eapSessionId = NULL;
 
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 3f31866..0662ae7 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -126,6 +126,21 @@
 #endif /* EAP_AKA_PRIME */
 
 
+static void eap_aka_clear_keys(struct eap_aka_data *data, int reauth)
+{
+	if (!reauth) {
+		os_memset(data->mk, 0, EAP_SIM_MK_LEN);
+		os_memset(data->k_aut, 0, EAP_AKA_PRIME_K_AUT_LEN);
+		os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN);
+		os_memset(data->k_re, 0, EAP_AKA_PRIME_K_RE_LEN);
+	}
+	os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN);
+	os_memset(data->emsk, 0, EAP_EMSK_LEN);
+	os_memset(data->autn, 0, EAP_AKA_AUTN_LEN);
+	os_memset(data->auts, 0, EAP_AKA_AUTS_LEN);
+}
+
+
 static void eap_aka_deinit(struct eap_sm *sm, void *priv)
 {
 	struct eap_aka_data *data = priv;
@@ -135,6 +150,7 @@
 		os_free(data->last_eap_identity);
 		wpabuf_free(data->id_msgs);
 		os_free(data->network_name);
+		eap_aka_clear_keys(data, 0);
 		os_free(data);
 	}
 }
@@ -151,7 +167,7 @@
 	pos += os_snprintf(pos, end - pos, ":");
 	pos += wpa_snprintf_hex(pos, end - pos, data->rand, EAP_AKA_RAND_LEN);
 	pos += os_snprintf(pos, end - pos, ":");
-	pos += wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN);
+	wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN);
 
 	eap_sm_request_sim(sm, req);
 	return 1;
@@ -294,7 +310,7 @@
 	{
 		u8 autn[EAP_AKA_AUTN_LEN];
 		os_memset(autn, '1', EAP_AKA_AUTN_LEN);
-		if (os_memcmp(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
+		if (os_memcmp_const(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
 			wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match "
 				   "with expected value");
 			return -1;
@@ -509,7 +525,7 @@
 #endif /* EAP_AKA_PRIME */
 		sha1_vector(1, &addr, &len, hash);
 
-	if (os_memcmp(hash, checkcode, hash_len) != 0) {
+	if (os_memcmp_const(hash, checkcode, hash_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
 		return -1;
 	}
@@ -532,7 +548,7 @@
 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_CLIENT_ERROR);
 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 }
 
 
@@ -549,7 +565,7 @@
 		   "(id=%d)", id);
 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 }
 
 
@@ -568,7 +584,7 @@
 	wpa_printf(MSG_DEBUG, "   AT_AUTS");
 	eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
 			     EAP_AKA_AUTS_LEN);
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 }
 
 
@@ -612,7 +628,7 @@
 				identity, identity_len);
 	}
 
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 }
 
 
@@ -634,7 +650,8 @@
 	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) "", 0);
+	return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, (u8 *) "",
+				  0);
 }
 
 
@@ -676,7 +693,7 @@
 	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, data->k_aut, nonce_s,
+	return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, nonce_s,
 				  EAP_SIM_NONCE_S_LEN);
 }
 
@@ -710,7 +727,7 @@
 		wpa_printf(MSG_DEBUG, "   AT_MAC");
 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
 	}
-	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
+	return eap_sim_msg_finish(msg, data->eap_method, k_aut, (u8 *) "", 0);
 }
 
 
@@ -790,7 +807,7 @@
 			       EAP_AKA_SUBTYPE_CHALLENGE);
 	wpa_printf(MSG_DEBUG, "   AT_KDF");
 	eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 }
 
 
@@ -1372,6 +1389,7 @@
 	data->id_msgs = NULL;
 	data->use_result_ind = 0;
 	data->kdf_negotiation = 0;
+	eap_aka_clear_keys(data, 1);
 }
 
 
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index daa1d32..2591e11 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -157,7 +157,7 @@
 	 *
 	 * If left out, this will be asked through control interface.
 	 */
-	u8 *private_key_passwd;
+	char *private_key_passwd;
 
 	/**
 	 * dh_file - File path to DH/DSA parameters file (in PEM format)
@@ -289,7 +289,7 @@
 	 * This field is like private_key_passwd, but used for phase 2 (inside
 	 * EAP-TTLS/PEAP/FAST tunnel) authentication.
 	 */
-	u8 *private_key2_passwd;
+	char *private_key2_passwd;
 
 	/**
 	 * dh_file2 - File path to DH/DSA parameters file (in PEM format)
diff --git a/src/eap_peer/eap_eke.c b/src/eap_peer/eap_eke.c
index 6818b08..9fec66c 100644
--- a/src/eap_peer/eap_eke.c
+++ b/src/eap_peer/eap_eke.c
@@ -138,7 +138,7 @@
 	os_free(data->serverid);
 	os_free(data->peerid);
 	wpabuf_free(data->msgs);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -566,8 +566,8 @@
 					  EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR);
 	}
 	wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_S", auth_s, data->sess.prf_len);
-	if (os_memcmp(auth_s, pos + data->sess.pnonce_ps_len,
-		      data->sess.prf_len) != 0) {
+	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,
 					  EAP_EKE_FAIL_AUTHENTICATION_FAIL);
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index b3f6a52..0739187 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -250,6 +250,8 @@
 		pac = pac->next;
 		eap_fast_free_pac(prev);
 	}
+	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);
 	os_free(data);
@@ -767,7 +769,7 @@
 		    "MAC calculation", (u8 *) _bind, bind_len);
 	hmac_sha1(cmk, EAP_FAST_CMK_LEN, (u8 *) _bind, bind_len,
 		  _bind->compound_mac);
-	res = os_memcmp(cmac, _bind->compound_mac, sizeof(cmac));
+	res = os_memcmp_const(cmac, _bind->compound_mac, sizeof(cmac));
 	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Received Compound MAC",
 		    cmac, sizeof(cmac));
 	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Calculated Compound MAC",
@@ -1636,6 +1638,8 @@
 		os_free(data);
 		return NULL;
 	}
+	os_memset(data->key_data, 0, EAP_FAST_KEY_LEN);
+	os_memset(data->emsk, 0, EAP_EMSK_LEN);
 	os_free(data->session_id);
 	data->session_id = NULL;
 	if (data->phase2_priv && data->phase2_method &&
diff --git a/src/eap_peer/eap_gpsk.c b/src/eap_peer/eap_gpsk.c
index 3c9cbf4..c54bf11 100644
--- a/src/eap_peer/eap_gpsk.c
+++ b/src/eap_peer/eap_gpsk.c
@@ -134,8 +134,11 @@
 	struct eap_gpsk_data *data = priv;
 	os_free(data->id_server);
 	os_free(data->id_peer);
-	os_free(data->psk);
-	os_free(data);
+	if (data->psk) {
+		os_memset(data->psk, 0, data->psk_len);
+		os_free(data->psk);
+	}
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -565,7 +568,7 @@
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
 		return NULL;
 	}
-	if (os_memcmp(mic, pos, miclen) != 0) {
+	if (os_memcmp_const(mic, pos, miclen) != 0) {
 		wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-3");
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
diff --git a/src/eap_peer/eap_ikev2.c b/src/eap_peer/eap_ikev2.c
index 568a448..c12b519 100644
--- a/src/eap_peer/eap_ikev2.c
+++ b/src/eap_peer/eap_ikev2.c
@@ -113,7 +113,7 @@
 	wpabuf_free(data->in_buf);
 	wpabuf_free(data->out_buf);
 	ikev2_responder_deinit(&data->ikev2);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
diff --git a/src/eap_peer/eap_leap.c b/src/eap_peer/eap_leap.c
index df34013..e0f8bcf 100644
--- a/src/eap_peer/eap_leap.c
+++ b/src/eap_peer/eap_leap.c
@@ -244,7 +244,7 @@
 	ret->methodState = METHOD_DONE;
 	ret->allowNotifications = FALSE;
 
-	if (os_memcmp(pos, expected, LEAP_RESPONSE_LEN) != 0) {
+	if (os_memcmp_const(pos, expected, LEAP_RESPONSE_LEN) != 0) {
 		wpa_printf(MSG_WARNING, "EAP-LEAP: AP sent an invalid "
 			   "response - authentication failed");
 		wpa_hexdump(MSG_DEBUG, "EAP-LEAP: Expected response from AP",
@@ -383,6 +383,9 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: master key", key, LEAP_KEY_LEN);
 	*len = LEAP_KEY_LEN;
 
+	os_memset(pw_hash, 0, sizeof(pw_hash));
+	os_memset(pw_hash_hash, 0, sizeof(pw_hash_hash));
+
 	return key;
 }
 
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index f2fcc37..430c501 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -140,7 +140,7 @@
 	os_free(data->peer_challenge);
 	os_free(data->auth_challenge);
 	wpabuf_free(data->prev_challenge);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -303,7 +303,7 @@
 			WPA_EVENT_PASSWORD_CHANGED
 			"EAP-MSCHAPV2: Password changed successfully");
 		data->prev_error = 0;
-		os_free(config->password);
+		bin_clear_free(config->password, config->password_len);
 		if (config->flags & EAP_CONFIG_FLAGS_EXT_PASSWORD) {
 			/* TODO: update external storage */
 		} else if (config->flags & EAP_CONFIG_FLAGS_PASSWORD_NTHASH) {
@@ -313,11 +313,13 @@
 			    nt_password_hash(config->new_password,
 					     config->new_password_len,
 					     config->password)) {
-				os_free(config->password);
+				bin_clear_free(config->password,
+					       config->password_len);
 				config->password = NULL;
 				config->password_len = 0;
 			}
-			os_free(config->new_password);
+			bin_clear_free(config->new_password,
+				       config->new_password_len);
 		} else {
 			config->password = config->new_password;
 			config->password_len = config->new_password_len;
diff --git a/src/eap_peer/eap_pax.c b/src/eap_peer/eap_pax.c
index 7f87052..1c111c2 100644
--- a/src/eap_peer/eap_pax.c
+++ b/src/eap_peer/eap_pax.c
@@ -86,7 +86,7 @@
 {
 	struct eap_pax_data *data = priv;
 	os_free(data->cid);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -278,7 +278,7 @@
 	eap_pax_mac(data->mac_id, data->ck, EAP_PAX_CK_LEN,
 		    data->rand.r.y, EAP_PAX_RAND_LEN,
 		    (u8 *) data->cid, data->cid_len, NULL, 0, mac);
-	if (os_memcmp(pos, mac, EAP_PAX_MAC_LEN) != 0) {
+	if (os_memcmp_const(pos, mac, EAP_PAX_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(B, CID) "
 			   "received");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: expected MAC_CK(B, CID)",
@@ -415,7 +415,7 @@
 			    wpabuf_head(reqData), mlen, NULL, 0, NULL, 0,
 			    icvbuf);
 	}
-	if (os_memcmp(icv, icvbuf, EAP_PAX_ICV_LEN) != 0) {
+	if (os_memcmp_const(icv, icvbuf, EAP_PAX_ICV_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-PAX: invalid ICV - ignoring the "
 			   "message");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: expected ICV",
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 8634f75..472e861 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -170,6 +170,15 @@
 }
 
 
+static void eap_peap_free_key(struct eap_peap_data *data)
+{
+	if (data->key_data) {
+		bin_clear_free(data->key_data, EAP_TLS_KEY_LEN);
+		data->key_data = NULL;
+	}
+}
+
+
 static void eap_peap_deinit(struct eap_sm *sm, void *priv)
 {
 	struct eap_peap_data *data = priv;
@@ -179,7 +188,7 @@
 		data->phase2_method->deinit(sm, data->phase2_priv);
 	os_free(data->phase2_types);
 	eap_peer_tls_ssl_deinit(sm, &data->ssl);
-	os_free(data->key_data);
+	eap_peap_free_key(data);
 	os_free(data->session_id);
 	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
@@ -423,7 +432,7 @@
 		    buf, sizeof(buf));
 	hmac_sha1(data->cmk, 20, buf, sizeof(buf), mac);
 
-	if (os_memcmp(mac, pos, SHA1_MAC_LEN) != 0) {
+	if (os_memcmp_const(mac, pos, SHA1_MAC_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Invalid Compound_MAC in "
 			   "cryptobinding TLV");
 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Received MAC",
@@ -1005,7 +1014,7 @@
 			char *label;
 			wpa_printf(MSG_DEBUG,
 				   "EAP-PEAP: TLS done, proceed to Phase 2");
-			os_free(data->key_data);
+			eap_peap_free_key(data);
 			/* draft-josefsson-ppext-eap-tls-eap-05.txt
 			 * specifies that PEAPv1 would use "client PEAP
 			 * encryption" as the label. However, most existing
@@ -1115,8 +1124,7 @@
 static void * eap_peap_init_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_peap_data *data = priv;
-	os_free(data->key_data);
-	data->key_data = NULL;
+	eap_peap_free_key(data);
 	os_free(data->session_id);
 	data->session_id = NULL;
 	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
diff --git a/src/eap_peer/eap_psk.c b/src/eap_peer/eap_psk.c
index cd0e3f9..f012663 100644
--- a/src/eap_peer/eap_psk.c
+++ b/src/eap_peer/eap_psk.c
@@ -76,7 +76,7 @@
 	struct eap_psk_data *data = priv;
 	os_free(data->id_s);
 	os_free(data->id_p);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -237,7 +237,7 @@
 		return NULL;
 	}
 	os_free(buf);
-	if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
+	if (os_memcmp_const(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
 		wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third "
 			   "message");
 		ret->methodState = METHOD_DONE;
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 2aa7ba5..bdcca0b 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -157,7 +157,7 @@
 	EC_POINT_free(data->server_element);
 	os_free(data->id_peer);
 	os_free(data->id_server);
-	os_free(data->password);
+	bin_clear_free(data->password, data->password_len);
 	if (data->grp) {
 		EC_GROUP_free(data->grp->group);
 		EC_POINT_free(data->grp->pwe);
@@ -167,7 +167,7 @@
 	}
 	wpabuf_free(data->inbuf);
 	wpabuf_free(data->outbuf);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -782,6 +782,8 @@
 		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;
 		data->inbuf = wpabuf_alloc(tot_len);
 		if (data->inbuf == NULL) {
 			wpa_printf(MSG_INFO, "Out of memory to buffer "
diff --git a/src/eap_peer/eap_sake.c b/src/eap_peer/eap_sake.c
index 431519c..7d14907 100644
--- a/src/eap_peer/eap_sake.c
+++ b/src/eap_peer/eap_sake.c
@@ -108,7 +108,7 @@
 	struct eap_sake_data *data = priv;
 	os_free(data->serverid);
 	os_free(data->peerid);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -315,7 +315,7 @@
 			     data->peerid, data->peerid_len, 0,
 			     wpabuf_head(reqData), wpabuf_len(reqData),
 			     attr.mic_s, mic_s);
-	if (os_memcmp(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) {
+	if (os_memcmp_const(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S");
 		eap_sake_state(data, FAILURE);
 		ret->methodState = METHOD_DONE;
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 63c8939..bd06df7 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -130,6 +130,20 @@
 }
 
 
+static void eap_sim_clear_keys(struct eap_sim_data *data, int reauth)
+{
+	if (!reauth) {
+		os_memset(data->mk, 0, EAP_SIM_MK_LEN);
+		os_memset(data->k_aut, 0, EAP_SIM_K_AUT_LEN);
+		os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN);
+	}
+	os_memset(data->kc, 0, 3 * EAP_SIM_KC_LEN);
+	os_memset(data->sres, 0, 3 * EAP_SIM_SRES_LEN);
+	os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN);
+	os_memset(data->emsk, 0, EAP_EMSK_LEN);
+}
+
+
 static void eap_sim_deinit(struct eap_sm *sm, void *priv)
 {
 	struct eap_sim_data *data = priv;
@@ -138,6 +152,7 @@
 		os_free(data->pseudonym);
 		os_free(data->reauth_id);
 		os_free(data->last_eap_identity);
+		eap_sim_clear_keys(data, 0);
 		os_free(data);
 	}
 }
@@ -449,7 +464,7 @@
 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
 			       EAP_SIM_SUBTYPE_CLIENT_ERROR);
 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0);
 }
 
 
@@ -502,7 +517,7 @@
 				identity, identity_len);
 	}
 
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0);
 }
 
 
@@ -520,7 +535,8 @@
 	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres,
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut,
+				  (u8 *) data->sres,
 				  data->num_chal * EAP_SIM_SRES_LEN);
 }
 
@@ -562,7 +578,7 @@
 	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, data->k_aut, nonce_s,
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, nonce_s,
 				  EAP_SIM_NONCE_S_LEN);
 }
 
@@ -596,7 +612,7 @@
 		wpa_printf(MSG_DEBUG, "   AT_MAC");
 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
 	}
-	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, k_aut, (u8 *) "", 0);
 }
 
 
@@ -1109,6 +1125,7 @@
 	struct eap_sim_data *data = priv;
 	eap_sim_clear_identities(sm, data, CLEAR_EAP_ID);
 	data->use_result_ind = 0;
+	eap_sim_clear_keys(data, 1);
 }
 
 
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index bb9f3f2..5aa3fd5 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -125,13 +125,22 @@
 #endif /* CONFIG_HS20 */
 
 
+static void eap_tls_free_key(struct eap_tls_data *data)
+{
+	if (data->key_data) {
+		bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
+		data->key_data = NULL;
+	}
+}
+
+
 static void eap_tls_deinit(struct eap_sm *sm, void *priv)
 {
 	struct eap_tls_data *data = priv;
 	if (data == NULL)
 		return;
 	eap_peer_tls_ssl_deinit(sm, &data->ssl);
-	os_free(data->key_data);
+	eap_tls_free_key(data);
 	os_free(data->session_id);
 	os_free(data);
 }
@@ -181,7 +190,7 @@
 	ret->methodState = METHOD_DONE;
 	ret->decision = DECISION_UNCOND_SUCC;
 
-	os_free(data->key_data);
+	eap_tls_free_key(data);
 	data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
 						 "client EAP encryption",
 						 EAP_TLS_KEY_LEN +
@@ -267,8 +276,7 @@
 static void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_tls_data *data = priv;
-	os_free(data->key_data);
-	data->key_data = NULL;
+	eap_tls_free_key(data);
 	os_free(data->session_id);
 	data->session_id = NULL;
 	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index 5091bf0..e110236 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -133,6 +133,15 @@
 }
 
 
+static void eap_ttls_free_key(struct eap_ttls_data *data)
+{
+	if (data->key_data) {
+		bin_clear_free(data->key_data, EAP_TLS_KEY_LEN);
+		data->key_data = NULL;
+	}
+}
+
+
 static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
 {
 	struct eap_ttls_data *data = priv;
@@ -141,7 +150,7 @@
 	eap_ttls_phase2_eap_deinit(sm, data);
 	os_free(data->phase2_eap_types);
 	eap_peer_tls_ssl_deinit(sm, &data->ssl);
-	os_free(data->key_data);
+	eap_ttls_free_key(data);
 	os_free(data->session_id);
 	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
@@ -213,7 +222,7 @@
 static int eap_ttls_v0_derive_key(struct eap_sm *sm,
 				  struct eap_ttls_data *data)
 {
-	os_free(data->key_data);
+	eap_ttls_free_key(data);
 	data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
 						 "ttls keying material",
 						 EAP_TLS_KEY_LEN);
@@ -1540,8 +1549,7 @@
 static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_ttls_data *data = priv;
-	os_free(data->key_data);
-	data->key_data = NULL;
+	eap_ttls_free_key(data);
 	os_free(data->session_id);
 	data->session_id = NULL;
 	if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
diff --git a/src/eap_peer/ikev2.c b/src/eap_peer/ikev2.c
index fb2f619..8186afb 100644
--- a/src/eap_peer/ikev2.c
+++ b/src/eap_peer/ikev2.c
@@ -565,7 +565,7 @@
 		return -1;
 
 	if (auth_len != prf->hash_len ||
-	    os_memcmp(auth, auth_data, auth_len) != 0) {
+	    os_memcmp_const(auth, auth_data, auth_len) != 0) {
 		wpa_printf(MSG_INFO, "IKEV2: Invalid Authentication Data");
 		wpa_hexdump(MSG_DEBUG, "IKEV2: Received Authentication Data",
 			    auth, auth_len);
diff --git a/src/eap_peer/mschapv2.c b/src/eap_peer/mschapv2.c
index 37e6735..9bc7370 100644
--- a/src/eap_peer/mschapv2.c
+++ b/src/eap_peer/mschapv2.c
@@ -117,8 +117,8 @@
 	    buf[0] != 'S' || buf[1] != '=' ||
 	    hexstr2bin((char *) (buf + 2), recv_response,
 		       MSCHAPV2_AUTH_RESPONSE_LEN) ||
-	    os_memcmp(auth_response, recv_response,
-		      MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
+	    os_memcmp_const(auth_response, recv_response,
+			    MSCHAPV2_AUTH_RESPONSE_LEN) != 0)
 		return -1;
 	return 0;
 }