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/ap/ap_config.c b/src/ap/ap_config.c
index 7535b1b..bc9f6cf 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -379,7 +379,7 @@
 {
 	hostapd_config_free_radius_attr(user->accept_attr);
 	os_free(user->identity);
-	os_free(user->password);
+	bin_clear_free(user->password, user->password_len);
 	os_free(user);
 }
 
@@ -388,7 +388,7 @@
 {
 	int i;
 	for (i = 0; i < NUM_WEP_KEYS; i++) {
-		os_free(keys->key[i]);
+		bin_clear_free(keys->key[i], keys->len[i]);
 		keys->key[i] = NULL;
 	}
 }
@@ -406,10 +406,10 @@
 	while (psk) {
 		prev = psk;
 		psk = psk->next;
-		os_free(prev);
+		bin_clear_free(prev, sizeof(*prev));
 	}
 
-	os_free(conf->ssid.wpa_passphrase);
+	str_clear_free(conf->ssid.wpa_passphrase);
 	os_free(conf->ssid.wpa_psk_file);
 	hostapd_config_free_wep(&conf->ssid.wep);
 #ifdef CONFIG_FULL_DYNAMIC_VLAN
diff --git a/src/ap/eap_user_db.c b/src/ap/eap_user_db.c
index 371a73f..559d77f 100644
--- a/src/ap/eap_user_db.c
+++ b/src/ap/eap_user_db.c
@@ -83,7 +83,7 @@
 
 	for (i = 0; i < argc; i++) {
 		if (os_strcmp(col[i], "password") == 0 && argv[i]) {
-			os_free(user->password);
+			bin_clear_free(user->password, user->password_len);
 			user->password_len = os_strlen(argv[i]);
 			user->password = (u8 *) os_strdup(argv[i]);
 			user->next = (void *) 1;
@@ -118,7 +118,7 @@
 	if (len <= user->identity_len &&
 	    os_memcmp(argv[id], user->identity, len) == 0 &&
 	    (user->password == NULL || len > user->password_len)) {
-		os_free(user->password);
+		bin_clear_free(user->password, user->password_len);
 		user->password_len = os_strlen(argv[id]);
 		user->password = (u8 *) os_strdup(argv[id]);
 		user->next = (void *) 1;
@@ -158,8 +158,10 @@
 		return NULL;
 	}
 
-	os_free(hapd->tmp_eap_user.identity);
-	os_free(hapd->tmp_eap_user.password);
+	bin_clear_free(hapd->tmp_eap_user.identity,
+		       hapd->tmp_eap_user.identity_len);
+	bin_clear_free(hapd->tmp_eap_user.password,
+		       hapd->tmp_eap_user.password_len);
 	os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
 	hapd->tmp_eap_user.phase2 = phase2;
 	hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 55b7ced..26aca2b 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -311,8 +311,10 @@
 #endif /* CONFIG_INTERWORKING */
 
 #ifdef CONFIG_SQLITE
-	os_free(hapd->tmp_eap_user.identity);
-	os_free(hapd->tmp_eap_user.password);
+	bin_clear_free(hapd->tmp_eap_user.identity,
+		       hapd->tmp_eap_user.identity_len);
+	bin_clear_free(hapd->tmp_eap_user.password,
+		       hapd->tmp_eap_user.password_len);
 #endif /* CONFIG_SQLITE */
 }
 
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index ca8db8f..de1ee5e 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -236,7 +236,8 @@
 
 	/* Transaction 3 */
 	if (!iswep || !sta->challenge || !challenge ||
-	    os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {
+	    os_memcmp_const(sta->challenge, challenge,
+			    WLAN_AUTH_CHALLENGE_LEN)) {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_INFO,
 			       "shared key authentication - invalid "
@@ -402,7 +403,7 @@
 		return -1;
 	if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
 			addr, ETH_ALEN, mac) < 0 ||
-	    os_memcmp(token, mac, SHA256_MAC_LEN) != 0)
+	    os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0)
 		return -1;
 
 	return 0;
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index a9cd6f6..2bb8aab 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1490,7 +1490,7 @@
 	os_memset(key->key_mic, 0, 16);
 	if (wpa_eapol_key_mic(PTK->kck, key_info & WPA_KEY_INFO_TYPE_MASK,
 			      data, data_len, key->key_mic) ||
-	    os_memcmp(mic, key->key_mic, 16) != 0)
+	    os_memcmp_const(mic, key->key_mic, 16) != 0)
 		ret = -1;
 	os_memcpy(key->key_mic, mic, 16);
 	return ret;
@@ -1877,8 +1877,8 @@
 		 * Verify that PMKR1Name from EAPOL-Key message 2/4 matches
 		 * with the value we derived.
 		 */
-		if (os_memcmp(sm->sup_pmk_r1_name, sm->pmk_r1_name,
-			      WPA_PMK_NAME_LEN) != 0) {
+		if (os_memcmp_const(sm->sup_pmk_r1_name, sm->pmk_r1_name,
+				    WPA_PMK_NAME_LEN) != 0) {
 			wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
 					"PMKR1Name mismatch in FT 4-way "
 					"handshake");
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index a80bbb7..8a6ca71 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -235,8 +235,8 @@
 	r0 = cache->pmk_r0;
 	while (r0) {
 		if (os_memcmp(r0->spa, spa, ETH_ALEN) == 0 &&
-		    os_memcmp(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN)
-		    == 0) {
+		    os_memcmp_const(r0->pmk_r0_name, pmk_r0_name,
+				    WPA_PMK_NAME_LEN) == 0) {
 			os_memcpy(pmk_r0, r0->pmk_r0, PMK_LEN);
 			if (pairwise)
 				*pairwise = r0->pairwise;
@@ -285,8 +285,8 @@
 	r1 = cache->pmk_r1;
 	while (r1) {
 		if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 &&
-		    os_memcmp(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN)
-		    == 0) {
+		    os_memcmp_const(r1->pmk_r1_name, pmk_r1_name,
+				    WPA_PMK_NAME_LEN) == 0) {
 			os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN);
 			if (pairwise)
 				*pairwise = r1->pairwise;
@@ -310,7 +310,8 @@
 	r0kh = sm->wpa_auth->conf.r0kh_list;
 	while (r0kh) {
 		if (r0kh->id_len == sm->r0kh_id_len &&
-		    os_memcmp(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == 0)
+		    os_memcmp_const(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) ==
+		    0)
 			break;
 		r0kh = r0kh->next;
 	}
@@ -1013,8 +1014,8 @@
 		return WLAN_STATUS_INVALID_PMKID;
 	}
 
-	if (os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
-	{
+	if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)
+	    != 0) {
 		wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match "
 			   "with the PMKR1Name derived from auth request");
 		return WLAN_STATUS_INVALID_PMKID;
@@ -1060,7 +1061,8 @@
 	}
 
 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
-	    os_memcmp(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) {
+	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
+	{
 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
 			   "the current R0KH-ID");
 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
@@ -1075,8 +1077,8 @@
 		return -1;
 	}
 
-	if (os_memcmp(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
-		      FT_R1KH_ID_LEN) != 0) {
+	if (os_memcmp_const(parse.r1kh_id, sm->wpa_auth->conf.r1_key_holder,
+			    FT_R1KH_ID_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
 			   "ReassocReq");
 		wpa_hexdump(MSG_DEBUG, "FT: R1KH-ID in FTIE",
@@ -1087,7 +1089,8 @@
 	}
 
 	if (parse.rsn_pmkid == NULL ||
-	    os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)) {
+	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
+	{
 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
 			   "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
 		return -1;
@@ -1113,7 +1116,7 @@
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 	}
 
-	if (os_memcmp(mic, ftie->mic, 16) != 0) {
+	if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
 		wpa_printf(MSG_DEBUG, "FT: addr=" MACSTR " auth_addr=" MACSTR,
 			   MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr));
@@ -1468,8 +1471,8 @@
 		return -1;
 	}
 
-	if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN)
-	    != 0) {
+	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
+			    FT_R1KH_ID_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: PMK-R1 pull response did not use a "
 			   "matching R1KH-ID");
 		return -1;
@@ -1544,8 +1547,8 @@
 		return -1;
 	}
 
-	if (os_memcmp(f.r1kh_id, wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN)
-	    != 0) {
+	if (os_memcmp_const(f.r1kh_id, wpa_auth->conf.r1_key_holder,
+			    FT_R1KH_ID_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: PMK-R1 push did not use a matching "
 			   "R1KH-ID (received " MACSTR " own " MACSTR ")",
 			   MAC2STR(f.r1kh_id),
@@ -1686,6 +1689,11 @@
 		return -1;
 	}
 
+	if (end > pos) {
+		wpa_hexdump(MSG_DEBUG, "FT: Ignore extra data in end",
+			    pos, end - pos);
+	}
+
 	return 0;
 }
 
diff --git a/src/common/sae.c b/src/common/sae.c
index c1b488e..b67623f 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -1051,7 +1051,7 @@
 				   sae->tmp->own_commit_element_ffc,
 				   verifier);
 
-	if (os_memcmp(verifier, data + 2, SHA256_MAC_LEN) != 0) {
+	if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
 		wpa_hexdump(MSG_DEBUG, "SAE: Received confirm",
 			    data + 2, SHA256_MAC_LEN);
diff --git a/src/crypto/aes-ccm.c b/src/crypto/aes-ccm.c
index d14670d..cf22778 100644
--- a/src/crypto/aes-ccm.c
+++ b/src/crypto/aes-ccm.c
@@ -203,7 +203,7 @@
 
 	aes_encrypt_deinit(aes);
 
-	if (os_memcmp(x, t, M) != 0) {
+	if (os_memcmp_const(x, t, M) != 0) {
 		wpa_printf(MSG_EXCESSIVE, "CCM: Auth mismatch");
 		return -1;
 	}
diff --git a/src/crypto/aes-gcm.c b/src/crypto/aes-gcm.c
index 3d91c71..84294d2 100644
--- a/src/crypto/aes-gcm.c
+++ b/src/crypto/aes-gcm.c
@@ -310,7 +310,7 @@
 
 	aes_encrypt_deinit(aes);
 
-	if (os_memcmp(tag, T, 16) != 0) {
+	if (os_memcmp_const(tag, T, 16) != 0) {
 		wpa_printf(MSG_EXCESSIVE, "GCM: Tag mismatch");
 		return -1;
 	}
diff --git a/src/crypto/milenage.c b/src/crypto/milenage.c
index a7f9c6a..6edea57 100644
--- a/src/crypto/milenage.c
+++ b/src/crypto/milenage.c
@@ -217,7 +217,7 @@
 	for (i = 0; i < 6; i++)
 		sqn[i] = auts[i] ^ ak[i];
 	if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
-	    memcmp(mac_s, auts + 6, 8) != 0)
+	    os_memcmp_const(mac_s, auts + 6, 8) != 0)
 		return -1;
 	return 0;
 }
@@ -312,7 +312,7 @@
 
 	wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8);
 
-	if (os_memcmp(mac_a, autn + 8, 8) != 0) {
+	if (os_memcmp_const(mac_a, autn + 8, 8) != 0) {
 		wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch");
 		wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A",
 			    autn + 8, 8);
diff --git a/src/eap_common/eap_eke_common.c b/src/eap_common/eap_eke_common.c
index a62ac8e..4dfdb3f 100644
--- a/src/eap_common/eap_eke_common.c
+++ b/src/eap_common/eap_eke_common.c
@@ -692,7 +692,7 @@
 	if (eap_eke_mac(sess->mac, sess->ki, prot + block_size,
 			prot_len - block_size - icv_len, icv) < 0)
 		return -1;
-	if (os_memcmp(icv, prot + prot_len - icv_len, icv_len) != 0) {
+	if (os_memcmp_const(icv, prot + prot_len - icv_len, icv_len) != 0) {
 		wpa_printf(MSG_INFO, "EAP-EKE: ICV mismatch in Prot() data");
 		return -1;
 	}
diff --git a/src/eap_common/eap_gpsk_common.c b/src/eap_common/eap_gpsk_common.c
index 7a33215..8c7ae27 100644
--- a/src/eap_common/eap_gpsk_common.c
+++ b/src/eap_common/eap_gpsk_common.c
@@ -284,7 +284,6 @@
 			 u8 *pk, size_t *pk_len)
 {
 	u8 *seed, *pos;
-	size_t seed_len;
 	int ret;
 
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving keys (%d:%d)",
@@ -296,8 +295,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len);
 
 	/* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */
-	seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len;
-	seed = os_malloc(seed_len);
+	seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len);
 	if (seed == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
 			   "for key derivation");
@@ -313,17 +311,18 @@
 	pos += EAP_GPSK_RAND_LEN;
 	os_memcpy(pos, id_server, id_server_len);
 	pos += id_server_len;
-	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len);
+	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed);
 
 	switch (specifier) {
 	case EAP_GPSK_CIPHER_AES:
-		ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, seed_len,
+		ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, pos - seed,
 					       msk, emsk, sk, sk_len,
 					       pk, pk_len);
 		break;
 #ifdef EAP_GPSK_SHA256
 	case EAP_GPSK_CIPHER_SHA256:
-		ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, seed_len,
+		ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed,
+						  pos - seed,
 						  msk, emsk, sk, sk_len);
 		break;
 #endif /* EAP_GPSK_SHA256 */
@@ -423,7 +422,6 @@
 {
 	u8 *seed, *pos;
 	u8 kdf_out[16];
-	size_t seed_len;
 	int ret;
 
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving Session ID(%d:%d)",
@@ -441,8 +439,7 @@
 	 * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
 	 *                      CSuite_Sel || inputString)
 	 */
-	seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len;
-	seed = os_malloc(seed_len);
+	seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len);
 	if (seed == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
 			   "for Session-Id derivation");
@@ -458,11 +455,11 @@
 	pos += EAP_GPSK_RAND_LEN;
 	os_memcpy(pos, id_server, id_server_len);
 	pos += id_server_len;
-	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len);
+	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed);
 
 	ret = eap_gpsk_derive_mid_helper(specifier,
 					 kdf_out, sizeof(kdf_out),
-					 psk, seed, seed_len,
+					 psk, seed, pos - seed,
 					 method_type);
 
 	sid[0] = method_type;
diff --git a/src/eap_common/eap_ikev2_common.c b/src/eap_common/eap_ikev2_common.c
index da9f3cc..585c79c 100644
--- a/src/eap_common/eap_ikev2_common.c
+++ b/src/eap_common/eap_ikev2_common.c
@@ -100,7 +100,7 @@
 		return -1;
 	}
 
-	if (os_memcmp(icv, end - icv_len, icv_len) != 0) {
+	if (os_memcmp_const(icv, end - icv_len, icv_len) != 0) {
 		wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV");
 		wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV",
 			    icv, icv_len);
diff --git a/src/eap_common/eap_sim_common.c b/src/eap_common/eap_sim_common.c
index ae02185..2adc3b3 100644
--- a/src/eap_common/eap_sim_common.c
+++ b/src/eap_common/eap_sim_common.c
@@ -198,7 +198,7 @@
 		    hmac, EAP_SIM_MAC_LEN);
 	os_free(tmp);
 
-	return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
+	return (os_memcmp_const(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
 }
 
 
@@ -393,7 +393,7 @@
 		    hmac, EAP_SIM_MAC_LEN);
 	os_free(tmp);
 
-	return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
+	return (os_memcmp_const(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
 }
 
 
@@ -972,7 +972,6 @@
 struct eap_sim_msg {
 	struct wpabuf *buf;
 	size_t mac, iv, encr; /* index from buf */
-	int type;
 };
 
 
@@ -986,7 +985,6 @@
 	if (msg == NULL)
 		return NULL;
 
-	msg->type = type;
 	msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
 	if (msg->buf == NULL) {
 		os_free(msg);
@@ -1006,7 +1004,8 @@
 }
 
 
-struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut,
+struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type,
+				   const u8 *k_aut,
 				   const u8 *extra, size_t extra_len)
 {
 	struct eap_hdr *eap;
@@ -1019,7 +1018,7 @@
 	eap->length = host_to_be16(wpabuf_len(msg->buf));
 
 #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
-	if (k_aut && msg->mac && msg->type == EAP_TYPE_AKA_PRIME) {
+	if (k_aut && msg->mac && type == EAP_TYPE_AKA_PRIME) {
 		eap_sim_add_mac_sha256(k_aut, (u8 *) wpabuf_head(msg->buf),
 				       wpabuf_len(msg->buf),
 				       (u8 *) wpabuf_mhead(msg->buf) +
diff --git a/src/eap_common/eap_sim_common.h b/src/eap_common/eap_sim_common.h
index 6021bd2..daeb0e2 100644
--- a/src/eap_common/eap_sim_common.h
+++ b/src/eap_common/eap_sim_common.h
@@ -211,7 +211,8 @@
 struct eap_sim_msg;
 
 struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype);
-struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut,
+struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type,
+				   const u8 *k_aut,
 				   const u8 *extra, size_t extra_len);
 void eap_sim_msg_free(struct eap_sim_msg *msg);
 u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
diff --git a/src/eap_common/ikev2_common.c b/src/eap_common/ikev2_common.c
index b98a3e8..3d4fb6f 100644
--- a/src/eap_common/ikev2_common.c
+++ b/src/eap_common/ikev2_common.c
@@ -477,7 +477,7 @@
 			   "hash");
 		return NULL;
 	}
-	if (os_memcmp(integ, hash, integ_alg->hash_len) != 0) {
+	if (os_memcmp_const(integ, hash, integ_alg->hash_len) != 0) {
 		wpa_printf(MSG_INFO, "IKEV2: Incorrect Integrity Checksum "
 			   "Data");
 		return NULL;
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;
 }
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index 65d00dd..c1bb6b8 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -168,7 +168,7 @@
 	sm->eap_if.eapSuccess = FALSE;
 	sm->eap_if.eapFail = FALSE;
 	sm->eap_if.eapTimeout = FALSE;
-	os_free(sm->eap_if.eapKeyData);
+	bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
 	sm->eap_if.eapKeyData = NULL;
 	sm->eap_if.eapKeyDataLen = 0;
 	sm->eap_if.eapKeyAvailable = FALSE;
@@ -346,7 +346,7 @@
 	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);
 	if (sm->m->isDone(sm, sm->eap_method_priv)) {
 		eap_sm_Policy_update(sm, NULL, 0);
-		os_free(sm->eap_if.eapKeyData);
+		bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
 		if (sm->m->getKey) {
 			sm->eap_if.eapKeyData = sm->m->getKey(
 				sm, sm->eap_method_priv,
@@ -632,7 +632,7 @@
 	if (sm->eap_if.aaaEapKeyAvailable) {
 		EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData);
 	} else {
-		os_free(sm->eap_if.eapKeyData);
+		bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
 		sm->eap_if.eapKeyData = NULL;
 		sm->eap_if.eapKeyDataLen = 0;
 	}
@@ -1260,7 +1260,7 @@
 {
 	if (user == NULL)
 		return;
-	os_free(user->password);
+	bin_clear_free(user->password, user->password_len);
 	user->password = NULL;
 	os_free(user);
 }
@@ -1352,7 +1352,7 @@
 	if (sm->m && sm->eap_method_priv)
 		sm->m->reset(sm, sm->eap_method_priv);
 	wpabuf_free(sm->eap_if.eapReqData);
-	os_free(sm->eap_if.eapKeyData);
+	bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
 	wpabuf_free(sm->lastReqData);
 	wpabuf_free(sm->eap_if.eapRespData);
 	os_free(sm->identity);
@@ -1361,7 +1361,7 @@
 	os_free(sm->eap_fast_a_id_info);
 	wpabuf_free(sm->eap_if.aaaEapReqData);
 	wpabuf_free(sm->eap_if.aaaEapRespData);
-	os_free(sm->eap_if.aaaEapKeyData);
+	bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen);
 	eap_user_free(sm->user);
 	wpabuf_free(sm->assoc_wps_ie);
 	wpabuf_free(sm->assoc_p2p_ie);
diff --git a/src/eap_server/eap_server_aka.c b/src/eap_server/eap_server_aka.c
index 46fc458..09b976e 100644
--- a/src/eap_server/eap_server_aka.c
+++ b/src/eap_server/eap_server_aka.c
@@ -241,7 +241,7 @@
 	os_free(data->next_reauth_id);
 	wpabuf_free(data->id_msgs);
 	os_free(data->network_name);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -336,7 +336,7 @@
 	else
 		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;
 	}
@@ -377,7 +377,7 @@
 		wpa_printf(MSG_DEBUG, "   AT_PERMANENT_ID_REQ");
 		eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
 	}
-	buf = eap_sim_msg_finish(msg, NULL, NULL, 0);
+	buf = eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
 	if (eap_aka_add_id_msg(data, buf) < 0) {
 		wpabuf_free(buf);
 		return NULL;
@@ -534,7 +534,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, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0);
 }
 
 
@@ -581,7 +581,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, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0);
 }
 
 
@@ -620,7 +620,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, NULL, 0);
+	return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, NULL, 0);
 }
 
 
@@ -963,7 +963,7 @@
 	 */
 	if (attr->res == NULL || attr->res_len < data->res_len ||
 	    attr->res_len_bits != data->res_len * 8 ||
-	    os_memcmp(attr->res, data->res, data->res_len) != 0) {
+	    os_memcmp_const(attr->res, data->res, data->res_len) != 0) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "
 			   "include valid AT_RES (attr len=%lu, res len=%lu "
 			   "bits, expected %lu bits)",
diff --git a/src/eap_server/eap_server_eke.c b/src/eap_server/eap_server_eke.c
index b19a321..966f511 100644
--- a/src/eap_server/eap_server_eke.c
+++ b/src/eap_server/eap_server_eke.c
@@ -104,7 +104,7 @@
 	eap_eke_session_clean(&data->sess);
 	os_free(data->peerid);
 	wpabuf_free(data->msgs);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -635,8 +635,8 @@
 		return;
 	}
 	wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_P", auth_p, data->sess.prf_len);
-	if (os_memcmp(auth_p, payload + data->sess.pnonce_len,
-		      data->sess.prf_len) != 0) {
+	if (os_memcmp_const(auth_p, payload + data->sess.pnonce_len,
+			    data->sess.prf_len) != 0) {
 		wpa_printf(MSG_INFO, "EAP-EKE: Auth_P does not match");
 		eap_eke_fail(data, EAP_EKE_FAIL_AUTHENTICATION_FAIL);
 		return;
diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c
index 44a443a..1024510 100644
--- a/src/eap_server/eap_server_fast.c
+++ b/src/eap_server/eap_server_fast.c
@@ -511,7 +511,7 @@
 	os_free(data->key_block_p);
 	wpabuf_free(data->pending_phase2_resp);
 	os_free(data->identity);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -1198,7 +1198,7 @@
 		return -1;
 	}
 
-	if (os_memcmp(data->crypto_binding_nonce, b->nonce, 31) != 0 ||
+	if (os_memcmp_const(data->crypto_binding_nonce, b->nonce, 31) != 0 ||
 	    (data->crypto_binding_nonce[31] | 1) != b->nonce[31]) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid nonce in "
 			   "Crypto-Binding");
@@ -1212,7 +1212,7 @@
 		    (u8 *) b, bind_len);
 	hmac_sha1(data->cmk, EAP_FAST_CMK_LEN, (u8 *) b, bind_len,
 		  b->compound_mac);
-	if (os_memcmp(cmac, b->compound_mac, sizeof(cmac)) != 0) {
+	if (os_memcmp_const(cmac, b->compound_mac, sizeof(cmac)) != 0) {
 		wpa_hexdump(MSG_MSGDUMP,
 			    "EAP-FAST: Calculated Compound MAC",
 			    b->compound_mac, sizeof(cmac));
diff --git a/src/eap_server/eap_server_gpsk.c b/src/eap_server/eap_server_gpsk.c
index 66f4271..cb369e4 100644
--- a/src/eap_server/eap_server_gpsk.c
+++ b/src/eap_server/eap_server_gpsk.c
@@ -95,7 +95,7 @@
 {
 	struct eap_gpsk_data *data = priv;
 	os_free(data->id_peer);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -433,7 +433,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	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-2");
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
@@ -502,7 +502,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	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-4");
 		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_server/eap_server_gtc.c b/src/eap_server/eap_server_gtc.c
index f423106..98ac3c6 100644
--- a/src/eap_server/eap_server_gtc.c
+++ b/src/eap_server/eap_server_gtc.c
@@ -175,7 +175,7 @@
 	}
 
 	if (rlen != sm->user->password_len ||
-	    os_memcmp(pos, sm->user->password, rlen) != 0) {
+	    os_memcmp_const(pos, sm->user->password, rlen) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
 		data->state = FAILURE;
 	} else {
diff --git a/src/eap_server/eap_server_ikev2.c b/src/eap_server/eap_server_ikev2.c
index 3e32cc9..65b2ef6 100644
--- a/src/eap_server/eap_server_ikev2.c
+++ b/src/eap_server/eap_server_ikev2.c
@@ -127,7 +127,7 @@
 	wpabuf_free(data->in_buf);
 	wpabuf_free(data->out_buf);
 	ikev2_initiator_deinit(&data->ikev2);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
diff --git a/src/eap_server/eap_server_md5.c b/src/eap_server/eap_server_md5.c
index 5a5e290..71e8d59 100644
--- a/src/eap_server/eap_server_md5.c
+++ b/src/eap_server/eap_server_md5.c
@@ -126,7 +126,7 @@
 		return;
 	}
 
-	if (os_memcmp(hash, pos, CHAP_MD5_LEN) == 0) {
+	if (os_memcmp_const(hash, pos, CHAP_MD5_LEN) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
 		data->state = SUCCESS;
 	} else {
diff --git a/src/eap_server/eap_server_mschapv2.c b/src/eap_server/eap_server_mschapv2.c
index 0eb7908..f7a753d 100644
--- a/src/eap_server/eap_server_mschapv2.c
+++ b/src/eap_server/eap_server_mschapv2.c
@@ -91,7 +91,7 @@
 		return;
 
 	os_free(data->peer_challenge);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -393,7 +393,7 @@
 		return;
 	}
 
-	if (os_memcmp(nt_response, expected, 24) == 0) {
+	if (os_memcmp_const(nt_response, expected, 24) == 0) {
 		const u8 *pw_hash;
 		u8 pw_hash_buf[16], pw_hash_hash[16];
 
diff --git a/src/eap_server/eap_server_pax.c b/src/eap_server/eap_server_pax.c
index 35a42ad..c87848c 100644
--- a/src/eap_server/eap_server_pax.c
+++ b/src/eap_server/eap_server_pax.c
@@ -64,7 +64,7 @@
 {
 	struct eap_pax_data *data = priv;
 	os_free(data->cid);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -268,7 +268,7 @@
 			    wpabuf_mhead(respData),
 			    wpabuf_len(respData) - EAP_PAX_ICV_LEN,
 			    NULL, 0, NULL, 0, icvbuf);
-		if (os_memcmp(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
+		if (os_memcmp_const(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
 			wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV");
 			wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
 				    icvbuf, EAP_PAX_ICV_LEN);
@@ -395,7 +395,7 @@
 		    data->rand.r.x, EAP_PAX_RAND_LEN,
 		    data->rand.r.y, EAP_PAX_RAND_LEN,
 		    (u8 *) data->cid, data->cid_len, mac);
-	if (os_memcmp(mac, pos, EAP_PAX_MAC_LEN) != 0) {
+	if (os_memcmp_const(mac, pos, EAP_PAX_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(A, B, CID) in "
 			   "PAX_STD-2");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected MAC_CK(A, B, CID)",
@@ -417,7 +417,7 @@
 		    wpabuf_head(respData),
 		    wpabuf_len(respData) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0,
 		    icvbuf);
-	if (os_memcmp(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
+	if (os_memcmp_const(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV in PAX_STD-2");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
 			    icvbuf, EAP_PAX_ICV_LEN);
diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c
index defcb3c..594e02d 100644
--- a/src/eap_server/eap_server_peap.c
+++ b/src/eap_server/eap_server_peap.c
@@ -172,7 +172,7 @@
 	wpabuf_free(data->pending_phase2_resp);
 	os_free(data->phase2_key);
 	wpabuf_free(data->soh_response);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -593,7 +593,7 @@
 	buf[60] = EAP_TYPE_PEAP;
 	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_key(MSG_DEBUG, "EAP-PEAP: CMK", data->cmk, 20);
diff --git a/src/eap_server/eap_server_psk.c b/src/eap_server/eap_server_psk.c
index 46bedd9..db394e9 100644
--- a/src/eap_server/eap_server_psk.c
+++ b/src/eap_server/eap_server_psk.c
@@ -47,7 +47,7 @@
 {
 	struct eap_psk_data *data = priv;
 	os_free(data->id_p);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -314,7 +314,7 @@
 	}
 	os_free(buf);
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN);
-	if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
+	if (os_memcmp_const(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P",
 			    mac, EAP_PSK_MAC_LEN);
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index ec53481..9154ab1 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -116,7 +116,7 @@
 	data->bnctx = BN_CTX_new();
 	if (data->bnctx == NULL) {
 		wpa_printf(MSG_INFO, "EAP-PWD: bn context allocation fail");
-		os_free(data->password);
+		bin_clear_free(data->password, data->password_len);
 		os_free(data->id_server);
 		os_free(data);
 		return NULL;
@@ -144,7 +144,7 @@
 	EC_POINT_free(data->peer_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);
@@ -154,7 +154,7 @@
 	}
 	wpabuf_free(data->inbuf);
 	wpabuf_free(data->outbuf);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -900,6 +900,8 @@
 		tot_len = WPA_GET_BE16(pos);
 		wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments, total "
 			   "length = %d", tot_len);
+		if (tot_len > 15000)
+			return;
 		data->inbuf = wpabuf_alloc(tot_len);
 		if (data->inbuf == NULL) {
 			wpa_printf(MSG_INFO, "EAP-pwd: Out of memory to "
diff --git a/src/eap_server/eap_server_sake.c b/src/eap_server/eap_server_sake.c
index 68dd76b..1937621 100644
--- a/src/eap_server/eap_server_sake.c
+++ b/src/eap_server/eap_server_sake.c
@@ -83,7 +83,7 @@
 {
 	struct eap_sake_data *data = priv;
 	os_free(data->peerid);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -351,7 +351,7 @@
 			     data->peerid, data->peerid_len, 1,
 			     wpabuf_head(respData), wpabuf_len(respData),
 			     attr.mic_p, mic_p);
-	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
+	if (os_memcmp_const(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
 		eap_sake_state(data, FAILURE);
 		return;
@@ -388,7 +388,7 @@
 			     data->peerid, data->peerid_len, 1,
 			     wpabuf_head(respData), wpabuf_len(respData),
 			     attr.mic_p, mic_p);
-	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
+	if (os_memcmp_const(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
 		eap_sake_state(data, FAILURE);
 	} else
diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c
index b531241..23ee2b6 100644
--- a/src/eap_server/eap_server_sim.c
+++ b/src/eap_server/eap_server_sim.c
@@ -94,7 +94,7 @@
 	struct eap_sim_data *data = priv;
 	os_free(data->next_pseudonym);
 	os_free(data->next_reauth_id);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -140,7 +140,7 @@
 	ver[1] = EAP_SIM_VERSION;
 	eap_sim_msg_add(msg, EAP_SIM_AT_VERSION_LIST, sizeof(ver),
 			ver, sizeof(ver));
-	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, NULL, NULL, 0);
 }
 
 
@@ -240,8 +240,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, data->nonce_mt,
-				  EAP_SIM_NONCE_MT_LEN);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut,
+				  data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
 }
 
 
@@ -278,7 +278,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, NULL, 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0);
 }
 
 
@@ -317,7 +317,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, NULL, 0);
+	return eap_sim_msg_finish(msg, EAP_TYPE_SIM, data->k_aut, NULL, 0);
 }
 
 
diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c
index d09a769..31e3871 100644
--- a/src/eap_server/eap_server_ttls.c
+++ b/src/eap_server/eap_server_ttls.c
@@ -336,7 +336,7 @@
 		data->phase2_method->reset(sm, data->phase2_priv);
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
 	wpabuf_free(data->pending_phase2_eap_resp);
-	os_free(data);
+	bin_clear_free(data, sizeof(*data));
 }
 
 
@@ -509,8 +509,8 @@
 	}
 
 	if (sm->user->password_len != user_password_len ||
-	    os_memcmp(sm->user->password, user_password, user_password_len) !=
-	    0) {
+	    os_memcmp_const(sm->user->password, user_password,
+			    user_password_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
 		eap_ttls_state(data, FAILURE);
 		return;
@@ -558,7 +558,8 @@
 		return;
 	}
 
-	if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN)
+	    != 0 ||
 	    password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
 		os_free(chal);
@@ -571,7 +572,8 @@
 	chap_md5(password[0], sm->user->password, sm->user->password_len,
 		 challenge, challenge_len, hash);
 
-	if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
+	if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
+	    0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
 		eap_ttls_state(data, SUCCESS);
 	} else {
@@ -616,7 +618,8 @@
 		return;
 	}
 
-	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
+	    != 0 ||
 	    response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
 		os_free(chal);
@@ -631,7 +634,7 @@
 		nt_challenge_response(challenge, sm->user->password,
 				      sm->user->password_len, nt_response);
 
-	if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) {
+	if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
 		eap_ttls_state(data, SUCCESS);
 	} else {
@@ -703,7 +706,8 @@
 		return;
 	}
 
-	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN)
+	    != 0 ||
 	    response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
 		os_free(chal);
@@ -736,7 +740,7 @@
 	}
 
 	rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
-	if (os_memcmp(nt_response, rx_resp, 24) == 0) {
+	if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
 			   "NT-Response");
 		data->mschapv2_resp_ok = 1;
diff --git a/src/eap_server/ikev2.c b/src/eap_server/ikev2.c
index 512ba30..632598f 100644
--- a/src/eap_server/ikev2.c
+++ b/src/eap_server/ikev2.c
@@ -633,7 +633,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/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index e00dea3..cf3506d 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -719,8 +719,8 @@
 	hmac_md5(keydata.sign_key, sign_key_len,
 		 sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length),
 		 key->key_signature);
-	if (os_memcmp(orig_key_sign, key->key_signature,
-		      IEEE8021X_KEY_SIGN_LEN) != 0) {
+	if (os_memcmp_const(orig_key_sign, key->key_signature,
+			    IEEE8021X_KEY_SIGN_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in "
 			   "EAPOL-Key packet");
 		os_memcpy(key->key_signature, orig_key_sign,
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index fb8a8ca..56c195a 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -2942,8 +2942,9 @@
 						 mka_msg_len);
 
 	if (msg_icv) {
-		if (os_memcmp(msg_icv, icv,
-			      mka_alg_tbl[kay->mka_algindex].icv_len) != 0) {
+		if (os_memcmp_const(msg_icv, icv,
+				    mka_alg_tbl[kay->mka_algindex].icv_len) !=
+		    0) {
 			wpa_printf(MSG_ERROR,
 				   "KaY: Computed ICV is not equal to Received ICV");
 		return -1;
diff --git a/src/radius/radius.c b/src/radius/radius.c
index e34d08b..f2d8e96 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -508,7 +508,7 @@
 	addr[3] = secret;
 	len[3] = secret_len;
 	md5_vector(4, addr, len, hash);
-	return os_memcmp(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0;
+	return os_memcmp_const(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0;
 }
 
 
@@ -535,7 +535,7 @@
 	addr[3] = secret;
 	len[3] = secret_len;
 	md5_vector(4, addr, len, hash);
-	if (os_memcmp(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0)
+	if (os_memcmp_const(msg->hdr->authenticator, hash, MD5_MAC_LEN) != 0)
 		return 1;
 
 	for (i = 0; i < msg->attr_used; i++) {
@@ -568,7 +568,7 @@
 	os_memcpy(msg->hdr->authenticator, orig_authenticator,
 		  sizeof(orig_authenticator));
 
-	return os_memcmp(orig, auth, MD5_MAC_LEN) != 0;
+	return os_memcmp_const(orig, auth, MD5_MAC_LEN) != 0;
 }
 
 
@@ -801,7 +801,7 @@
 			  sizeof(orig_authenticator));
 	}
 
-	if (os_memcmp(orig, auth, MD5_MAC_LEN) != 0) {
+	if (os_memcmp_const(orig, auth, MD5_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "Invalid Message-Authenticator!");
 		return 1;
 	}
@@ -838,7 +838,7 @@
 	addr[3] = secret;
 	len[3] = secret_len;
 	md5_vector(4, addr, len, hash);
-	if (os_memcmp(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
+	if (os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "Response Authenticator invalid!");
 		return 1;
 	}
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index c35ba55..24348a3 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -623,7 +623,7 @@
 
 	os_memset(&tmp, 0, sizeof(tmp));
 	res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
-	os_free(tmp.password);
+	bin_clear_free(tmp.password, tmp.password_len);
 
 	if (res != 0) {
 		RADIUS_DEBUG("User-Name not found from user database");
@@ -852,7 +852,7 @@
 					 os_strlen(sess->username), 0, &tmp);
 		if (res || !tmp.macacl || tmp.password == NULL) {
 			RADIUS_DEBUG("No MAC ACL user entry");
-			os_free(tmp.password);
+			bin_clear_free(tmp.password, tmp.password_len);
 			code = RADIUS_CODE_ACCESS_REJECT;
 		} else {
 			u8 buf[128];
@@ -861,10 +861,10 @@
 				(u8 *) client->shared_secret,
 				client->shared_secret_len,
 				buf, sizeof(buf));
-			os_free(tmp.password);
+			bin_clear_free(tmp.password, tmp.password_len);
 
 			if (res < 0 || pw_len != (size_t) res ||
-			    os_memcmp(pw, buf, res) != 0) {
+			    os_memcmp_const(pw, buf, res) != 0) {
 				RADIUS_DEBUG("Incorrect User-Password");
 				code = RADIUS_CODE_ACCESS_REJECT;
 			}
diff --git a/src/rsn_supp/peerkey.c b/src/rsn_supp/peerkey.c
index 88550e4..aab8b7e 100644
--- a/src/rsn_supp/peerkey.c
+++ b/src/rsn_supp/peerkey.c
@@ -653,11 +653,11 @@
 static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm,
 					      struct wpa_peerkey *peerkey,
 					      const struct wpa_eapol_key *key,
-					      u16 ver)
+					      u16 ver, const u8 *key_data,
+					      size_t key_data_len)
 {
 	struct wpa_eapol_ie_parse ie;
-	const u8 *kde;
-	size_t len, kde_buf_len;
+	size_t kde_buf_len;
 	struct wpa_ptk *stk;
 	u8 buf[8], *kde_buf, *pos;
 	be32 lifetime;
@@ -668,14 +668,13 @@
 	os_memset(&ie, 0, sizeof(ie));
 
 	/* RSN: msg 1/4 should contain SMKID for the selected SMK */
-	kde = (const u8 *) (key + 1);
-	len = WPA_GET_BE16(key->key_data_length);
-	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len);
-	if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) {
+	wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", key_data, key_data_len);
+	if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0 ||
+	    ie.pmkid == NULL) {
 		wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4");
 		return;
 	}
-	if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
+	if (os_memcmp_const(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
 		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4",
 			    ie.pmkid, PMKID_LEN);
 		return;
@@ -760,11 +759,10 @@
 static void wpa_supplicant_process_stk_2_of_4(struct wpa_sm *sm,
 					      struct wpa_peerkey *peerkey,
 					      const struct wpa_eapol_key *key,
-					      u16 ver)
+					      u16 ver, const u8 *key_data,
+					      size_t key_data_len)
 {
 	struct wpa_eapol_ie_parse kde;
-	const u8 *keydata;
-	size_t len;
 
 	wpa_printf(MSG_DEBUG, "RSN: RX message 2 of STK 4-Way Handshake from "
 		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);
@@ -773,16 +771,14 @@
 
 	/* RSN: msg 2/4 should contain SMKID for the selected SMK and RSN IE
 	 * from the peer. It may also include Lifetime KDE. */
-	keydata = (const u8 *) (key + 1);
-	len = WPA_GET_BE16(key->key_data_length);
-	wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", keydata, len);
-	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0 ||
+	wpa_hexdump(MSG_DEBUG, "RSN: msg 2/4 key data", key_data, key_data_len);
+	if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0 ||
 	    kde.pmkid == NULL || kde.rsn_ie == NULL) {
 		wpa_printf(MSG_DEBUG, "RSN: No SMKID or RSN IE in STK 2/4");
 		return;
 	}
 
-	if (os_memcmp(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
+	if (os_memcmp_const(kde.pmkid, peerkey->smkid, PMKID_LEN) != 0) {
 		wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 2/4",
 			    kde.pmkid, PMKID_LEN);
 		return;
@@ -809,11 +805,11 @@
 static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
 					      struct wpa_peerkey *peerkey,
 					      const struct wpa_eapol_key *key,
-					      u16 ver)
+					      u16 ver, const u8 *key_data,
+					      size_t key_data_len)
 {
 	struct wpa_eapol_ie_parse kde;
-	const u8 *keydata;
-	size_t len, key_len;
+	size_t key_len;
 	const u8 *_key;
 	u8 key_buf[32], rsc[6];
 
@@ -824,10 +820,8 @@
 
 	/* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
 	 * Lifetime KDE. */
-	keydata = (const u8 *) (key + 1);
-	len = WPA_GET_BE16(key->key_data_length);
-	wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
-	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
+	wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", key_data, key_data_len);
+	if (wpa_supplicant_parse_ies(key_data, key_data_len, &kde) < 0) {
 		wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
 			   "STK 3/4");
 		return;
@@ -935,7 +929,7 @@
 		os_memset(key->key_mic, 0, 16);
 		wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
 				  key->key_mic);
-		if (os_memcmp(mic, key->key_mic, 16) != 0) {
+		if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
 			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
 				   "when using TSTK - ignoring TSTK");
 		} else {
@@ -951,7 +945,7 @@
 		os_memset(key->key_mic, 0, 16);
 		wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
 				  key->key_mic);
-		if (os_memcmp(mic, key->key_mic, 16) != 0) {
+		if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
 			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
 				   "- dropping packet");
 			return -1;
@@ -1117,21 +1111,25 @@
 
 
 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
-			   struct wpa_eapol_key *key, u16 key_info, u16 ver)
+			   struct wpa_eapol_key *key, u16 key_info, u16 ver,
+			   const u8 *key_data, size_t key_data_len)
 {
 	if ((key_info & (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) ==
 	    (WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK)) {
 		/* 3/4 STK 4-Way Handshake */
-		wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver);
+		wpa_supplicant_process_stk_3_of_4(sm, peerkey, key, ver,
+						  key_data, key_data_len);
 	} else if (key_info & WPA_KEY_INFO_ACK) {
 		/* 1/4 STK 4-Way Handshake */
-		wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver);
+		wpa_supplicant_process_stk_1_of_4(sm, peerkey, key, ver,
+						  key_data, key_data_len);
 	} else if (key_info & WPA_KEY_INFO_SECURE) {
 		/* 4/4 STK 4-Way Handshake */
 		wpa_supplicant_process_stk_4_of_4(sm, peerkey, key, ver);
 	} else {
 		/* 2/4 STK 4-Way Handshake */
-		wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver);
+		wpa_supplicant_process_stk_2_of_4(sm, peerkey, key, ver,
+						  key_data, key_data_len);
 	}
 }
 
diff --git a/src/rsn_supp/peerkey.h b/src/rsn_supp/peerkey.h
index f420691..4c17eae 100644
--- a/src/rsn_supp/peerkey.h
+++ b/src/rsn_supp/peerkey.h
@@ -41,7 +41,8 @@
 				 struct wpa_eapol_key *key, u16 ver,
 				 const u8 *buf, size_t len);
 void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
-			   struct wpa_eapol_key *key, u16 key_info, u16 ver);
+			   struct wpa_eapol_key *key, u16 key_info, u16 ver,
+			   const u8 *key_data, size_t key_data_len);
 void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
 			  struct wpa_eapol_key *key, size_t extra_len,
 			  u16 key_info, u16 ver);
@@ -60,7 +61,8 @@
 
 static inline void
 peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
-		      struct wpa_eapol_key *key, u16 key_info, u16 ver)
+		      struct wpa_eapol_key *key, u16 key_info, u16 ver,
+		      const u8 *key_data, size_t key_data_len)
 {
 }
 
diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c
index 0960815..b5a87fc 100644
--- a/src/rsn_supp/pmksa_cache.c
+++ b/src/rsn_supp/pmksa_cache.c
@@ -152,9 +152,9 @@
 	while (pos) {
 		if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) {
 			if (pos->pmk_len == pmk_len &&
-			    os_memcmp(pos->pmk, pmk, pmk_len) == 0 &&
-			    os_memcmp(pos->pmkid, entry->pmkid, PMKID_LEN) ==
-			    0) {
+			    os_memcmp_const(pos->pmk, pmk, pmk_len) == 0 &&
+			    os_memcmp_const(pos->pmkid, entry->pmkid,
+					    PMKID_LEN) == 0) {
 				wpa_printf(MSG_DEBUG, "WPA: reusing previous "
 					   "PMKSA entry");
 				os_free(entry);
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index cda6957..cd34223 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -564,7 +564,7 @@
 		wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid,
 				  peer->rsnie_p, timeoutie, (u8 *) ftie,
 				  mic);
-		if (os_memcmp(mic, ftie->mic, 16) != 0) {
+		if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
 			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - "
 				   "dropping packet");
 			wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC",
@@ -591,7 +591,7 @@
 	if (peer->tpk_set) {
 		wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode,
 					  dtoken, lnkid, (u8 *) ftie, mic);
-		if (os_memcmp(mic, ftie->mic, 16) != 0) {
+		if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
 			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - "
 				   "dropping packet");
 			return -1;
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 40fb92a..9471071 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -162,7 +162,7 @@
 	}
 
 	if (pmkid && sm->cur_pmksa &&
-	    os_memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
+	    os_memcmp_const(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
 		wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
 		wpa_sm_set_pmk_from_pmksa(sm);
 		wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
@@ -906,7 +906,8 @@
 		return -1;
 	}
 
-	if (os_memcmp(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) {
+	if (os_memcmp_const(rsn.pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0)
+	{
 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
 			"FT: PMKR1Name mismatch in "
 			"FT 4-way handshake message 3/4");
@@ -1418,7 +1419,7 @@
 		os_memset(key->key_mic, 0, 16);
 		wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len,
 				  key->key_mic);
-		if (os_memcmp(mic, key->key_mic, 16) != 0) {
+		if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
 			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
 				"WPA: Invalid EAPOL-Key MIC "
 				"when using TPTK - ignoring TPTK");
@@ -1435,7 +1436,7 @@
 		os_memset(key->key_mic, 0, 16);
 		wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len,
 				  key->key_mic);
-		if (os_memcmp(mic, key->key_mic, 16) != 0) {
+		if (os_memcmp_const(mic, key->key_mic, 16) != 0) {
 			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
 				"WPA: Invalid EAPOL-Key MIC - "
 				"dropping packet");
@@ -1833,7 +1834,8 @@
 		}
 		if (peerkey) {
 			/* PeerKey 4-Way Handshake */
-			peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver);
+			peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
+					      key_data, key_data_len);
 		} else if (key_info & WPA_KEY_INFO_MIC) {
 			/* 3/4 4-Way Handshake */
 			wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index c8d8cfc..4a75b92 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -442,7 +442,8 @@
 	}
 
 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
-	    os_memcmp(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) {
+	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
+	{
 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
 			   "the current R0KH-ID");
 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
@@ -458,7 +459,8 @@
 	}
 
 	if (parse.rsn_pmkid == NULL ||
-	    os_memcmp(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN)) {
+	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r0_name, WPA_PMK_NAME_LEN))
+	{
 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in "
 			   "RSNIE");
 		return -1;
@@ -727,7 +729,8 @@
 	}
 
 	if (parse.r0kh_id_len != sm->r0kh_id_len ||
-	    os_memcmp(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0) {
+	    os_memcmp_const(parse.r0kh_id, sm->r0kh_id, parse.r0kh_id_len) != 0)
+	{
 		wpa_printf(MSG_DEBUG, "FT: R0KH-ID in FTIE did not match with "
 			   "the current R0KH-ID");
 		wpa_hexdump(MSG_DEBUG, "FT: R0KH-ID in FTIE",
@@ -742,14 +745,15 @@
 		return -1;
 	}
 
-	if (os_memcmp(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) {
+	if (os_memcmp_const(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in "
 			   "ReassocResp");
 		return -1;
 	}
 
 	if (parse.rsn_pmkid == NULL ||
-	    os_memcmp(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN)) {
+	    os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN))
+	{
 		wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in "
 			   "RSNIE (pmkid=%d)", !!parse.rsn_pmkid);
 		return -1;
@@ -775,7 +779,7 @@
 		return -1;
 	}
 
-	if (os_memcmp(mic, ftie->mic, 16) != 0) {
+	if (os_memcmp_const(mic, ftie->mic, 16) != 0) {
 		wpa_printf(MSG_DEBUG, "FT: Invalid MIC in FTIE");
 		wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", ftie->mic, 16);
 		wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, 16);
diff --git a/src/tls/pkcs1.c b/src/tls/pkcs1.c
index 381b7a0..141ac50 100644
--- a/src/tls/pkcs1.c
+++ b/src/tls/pkcs1.c
@@ -298,7 +298,7 @@
 		    hdr.payload, hdr.length);
 
 	if (hdr.length != hash_len ||
-	    os_memcmp(hdr.payload, hash, hdr.length) != 0) {
+	    os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
 		wpa_printf(MSG_INFO, "PKCS #1: Digest value does not match calculated hash");
 		os_free(decrypted);
 		return -1;
diff --git a/src/tls/tlsv1_client_read.c b/src/tls/tlsv1_client_read.c
index f78921d..4f08e0f 100644
--- a/src/tls/tlsv1_client_read.c
+++ b/src/tls/tlsv1_client_read.c
@@ -962,7 +962,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
 			verify_data, TLS_VERIFY_DATA_LEN);
 
-	if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
+	if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
 		wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
 			  TLS_ALERT_DECRYPT_ERROR);
diff --git a/src/tls/tlsv1_common.c b/src/tls/tlsv1_common.c
index 8a4645b..ced28cf 100644
--- a/src/tls/tlsv1_common.c
+++ b/src/tls/tlsv1_common.c
@@ -481,7 +481,8 @@
 	}
 #endif /* CONFIG_TLSV12 */
 
-	if (buflen != data_len || os_memcmp(decrypted, data, data_len) != 0) {
+	if (buflen != data_len ||
+	    os_memcmp_const(decrypted, data, data_len) != 0) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in CertificateVerify - did not match calculated hash");
 		os_free(buf);
 		*alert = TLS_ALERT_DECRYPT_ERROR;
diff --git a/src/tls/tlsv1_record.c b/src/tls/tlsv1_record.c
index 3bec3be..0c6897a 100644
--- a/src/tls/tlsv1_record.c
+++ b/src/tls/tlsv1_record.c
@@ -456,7 +456,7 @@
 			return -1;
 		}
 		if (hlen != rl->hash_size ||
-		    os_memcmp(hash, out_data + plen, hlen) != 0 ||
+		    os_memcmp_const(hash, out_data + plen, hlen) != 0 ||
 		    force_mac_error) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
 				   "received message (force_mac_error=%d)",
diff --git a/src/tls/tlsv1_server_read.c b/src/tls/tlsv1_server_read.c
index c34545e..728e137 100644
--- a/src/tls/tlsv1_server_read.c
+++ b/src/tls/tlsv1_server_read.c
@@ -1135,7 +1135,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
 			verify_data, TLS_VERIFY_DATA_LEN);
 
-	if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
+	if (os_memcmp_const(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
 		tlsv1_server_log(conn, "Mismatch in verify_data");
 		return -1;
 	}
diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c
index 751a268..e1e4df8 100644
--- a/src/tls/x509v3.c
+++ b/src/tls/x509v3.c
@@ -1776,7 +1776,7 @@
 	}
 
 	if (hdr.length != hash_len ||
-	    os_memcmp(hdr.payload, hash, hdr.length) != 0) {
+	    os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
 		wpa_printf(MSG_INFO, "X509: Certificate Digest does not match "
 			   "with calculated tbsCertificate hash");
 		os_free(data);
diff --git a/src/utils/common.c b/src/utils/common.c
index 7dc4797..5b017e5 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -827,3 +827,22 @@
 
 	*res = n;
 }
+
+
+void str_clear_free(char *str)
+{
+	if (str) {
+		size_t len = os_strlen(str);
+		os_memset(str, 0, len);
+		os_free(str);
+	}
+}
+
+
+void bin_clear_free(void *bin, size_t len)
+{
+	if (bin) {
+		os_memset(bin, 0, len);
+		os_free(bin);
+	}
+}
diff --git a/src/utils/common.h b/src/utils/common.h
index a85cc15..2bc8fe1 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -535,6 +535,10 @@
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 
+void str_clear_free(char *str);
+void bin_clear_free(void *bin, size_t len);
+
+
 /*
  * gcc 4.4 ends up generating strict-aliasing warnings about some very common
  * networking socket uses that do not really result in a real problem and
diff --git a/src/utils/ext_password_test.c b/src/utils/ext_password_test.c
index 3801bb8..b3a4552 100644
--- a/src/utils/ext_password_test.c
+++ b/src/utils/ext_password_test.c
@@ -36,7 +36,7 @@
 {
 	struct ext_password_test_data *data = ctx;
 
-	os_free(data->params);
+	str_clear_free(data->params);
 	os_free(data);
 }
 
diff --git a/src/utils/http_curl.c b/src/utils/http_curl.c
index 07d9af0..eb79b86 100644
--- a/src/utils/http_curl.c
+++ b/src/utils/http_curl.c
@@ -1368,8 +1368,8 @@
 			       client_cert, client_key);
 	os_free(address);
 	os_free(ca_fname);
-	os_free(username);
-	os_free(password);
+	str_clear_free(username);
+	str_clear_free(password);
 	os_free(client_cert);
 	os_free(client_key);
 	return ret;
@@ -1487,8 +1487,8 @@
 
 	os_free(ctx->svc_address);
 	os_free(ctx->svc_ca_fname);
-	os_free(ctx->svc_username);
-	os_free(ctx->svc_password);
+	str_clear_free(ctx->svc_username);
+	str_clear_free(ctx->svc_password);
 	os_free(ctx->svc_client_cert);
 	os_free(ctx->svc_client_key);
 
diff --git a/src/utils/os.h b/src/utils/os.h
index f019e26..f196209 100644
--- a/src/utils/os.h
+++ b/src/utils/os.h
@@ -584,6 +584,23 @@
  */
 size_t os_strlcpy(char *dest, const char *src, size_t siz);
 
+/**
+ * os_memcmp_const - Constant time memory comparison
+ * @a: First buffer to compare
+ * @b: Second buffer to compare
+ * @len: Number of octets to compare
+ * Returns: 0 if buffers are equal, non-zero if not
+ *
+ * This function is meant for comparing passwords or hash values where
+ * difference in execution time could provide external observer information
+ * about the location of the difference in the memory buffers. The return value
+ * does not behave like os_memcmp(), i.e., os_memcmp_const() cannot be used to
+ * sort items into a defined order. Unlike os_memcmp(), execution time of
+ * os_memcmp_const() does not depend on the contents of the compared memory
+ * buffers, but only on the total compared length.
+ */
+int os_memcmp_const(const void *a, const void *b, size_t len);
+
 
 #ifdef OS_REJECT_C_LIB_FUNCTIONS
 #define malloc OS_DO_NOT_USE_malloc
diff --git a/src/utils/os_internal.c b/src/utils/os_internal.c
index 2cb0d12..90b6688 100644
--- a/src/utils/os_internal.c
+++ b/src/utils/os_internal.c
@@ -463,6 +463,20 @@
 }
 
 
+int os_memcmp_const(const void *a, const void *b, size_t len)
+{
+	const u8 *aa = a;
+	const u8 *bb = b;
+	size_t i;
+	u8 res;
+
+	for (res = 0, i = 0; i < len; i++)
+		res |= aa[i] ^ bb[i];
+
+	return res;
+}
+
+
 char * os_strstr(const char *haystack, const char *needle)
 {
 	size_t len = os_strlen(needle);
diff --git a/src/utils/os_none.c b/src/utils/os_none.c
index 228c472..2649111 100644
--- a/src/utils/os_none.c
+++ b/src/utils/os_none.c
@@ -218,6 +218,11 @@
 }
 
 
+int os_memcmp_const(const void *a, const void *b, size_t len)
+{
+	return 0;
+}
+
 char * os_strstr(const char *haystack, const char *needle)
 {
 	return NULL;
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index 008ec6b..d3860ae 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -450,6 +450,20 @@
 }
 
 
+int os_memcmp_const(const void *a, const void *b, size_t len)
+{
+	const u8 *aa = a;
+	const u8 *bb = b;
+	size_t i;
+	u8 res;
+
+	for (res = 0, i = 0; i < len; i++)
+		res |= aa[i] ^ bb[i];
+
+	return res;
+}
+
+
 #ifdef WPA_TRACE
 
 void * os_malloc(size_t size)
diff --git a/src/utils/os_win32.c b/src/utils/os_win32.c
index 1cfa7a5..55937de 100644
--- a/src/utils/os_win32.c
+++ b/src/utils/os_win32.c
@@ -244,3 +244,17 @@
 
 	return s - src - 1;
 }
+
+
+int os_memcmp_const(const void *a, const void *b, size_t len)
+{
+	const u8 *aa = a;
+	const u8 *bb = b;
+	size_t i;
+	u8 res;
+
+	for (res = 0, i = 0; i < len; i++)
+		res |= aa[i] ^ bb[i];
+
+	return res;
+}
diff --git a/src/utils/pcsc_funcs.c b/src/utils/pcsc_funcs.c
index ec06556..d955dc4 100644
--- a/src/utils/pcsc_funcs.c
+++ b/src/utils/pcsc_funcs.c
@@ -1406,6 +1406,12 @@
 		pos += IK_LEN;
 		wpa_hexdump(MSG_DEBUG, "SCARD: IK", ik, IK_LEN);
 
+		if (end > pos) {
+			wpa_hexdump(MSG_DEBUG,
+				    "SCARD: Ignore extra data in end",
+				    pos, end - pos);
+		}
+
 		return 0;
 	}
 
diff --git a/src/wps/wps.c b/src/wps/wps.c
index 648cfd1..b0f6887 100644
--- a/src/wps/wps.c
+++ b/src/wps/wps.c
@@ -89,7 +89,7 @@
 	if (cfg->pbc) {
 		/* Use special PIN '00000000' for PBC */
 		data->dev_pw_id = DEV_PW_PUSHBUTTON;
-		os_free(data->dev_password);
+		bin_clear_free(data->dev_password, data->dev_password_len);
 		data->dev_password = (u8 *) os_strdup("00000000");
 		if (data->dev_password == NULL) {
 			os_free(data);
@@ -122,7 +122,8 @@
 		data->new_ap_settings =
 			os_malloc(sizeof(*data->new_ap_settings));
 		if (data->new_ap_settings == NULL) {
-			os_free(data->dev_password);
+			bin_clear_free(data->dev_password,
+				       data->dev_password_len);
 			os_free(data);
 			return NULL;
 		}
@@ -173,11 +174,11 @@
 	wpabuf_free(data->dh_pubkey_e);
 	wpabuf_free(data->dh_pubkey_r);
 	wpabuf_free(data->last_msg);
-	os_free(data->dev_password);
-	os_free(data->alt_dev_password);
-	os_free(data->new_psk);
+	bin_clear_free(data->dev_password, data->dev_password_len);
+	bin_clear_free(data->alt_dev_password, data->alt_dev_password_len);
+	bin_clear_free(data->new_psk, data->new_psk_len);
 	wps_device_data_free(&data->peer_dev);
-	os_free(data->new_ap_settings);
+	bin_clear_free(data->new_ap_settings, sizeof(*data->new_ap_settings));
 	dh5_free(data->dh_ctx);
 	os_free(data);
 }
diff --git a/src/wps/wps_attr_process.c b/src/wps/wps_attr_process.c
index 5266620..eadb22f 100644
--- a/src/wps/wps_attr_process.c
+++ b/src/wps/wps_attr_process.c
@@ -41,7 +41,7 @@
 	len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
 
-	if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
+	if (os_memcmp_const(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
 		return -1;
 	}
@@ -71,7 +71,7 @@
 	}
 
 	hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
-	if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
+	if (os_memcmp_const(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
 		return -1;
 	}
diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c
index d072582..f7d41b4 100644
--- a/src/wps/wps_enrollee.c
+++ b/src/wps/wps_enrollee.c
@@ -525,8 +525,8 @@
 	if (wps->peer_pubkey_hash_set) {
 		u8 hash[WPS_HASH_LEN];
 		sha256_vector(1, &pk, &pk_len, hash);
-		if (os_memcmp(hash, wps->peer_pubkey_hash,
-			      WPS_OOB_PUBKEY_HASH_LEN) != 0) {
+		if (os_memcmp_const(hash, wps->peer_pubkey_hash,
+				    WPS_OOB_PUBKEY_HASH_LEN) != 0) {
 			wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
 			wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
 				    pk, pk_len);
@@ -605,7 +605,7 @@
 	len[3] = wpabuf_len(wps->dh_pubkey_r);
 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
 
-	if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
+	if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
 			   "not match with the pre-committed value");
 		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
@@ -645,7 +645,7 @@
 	len[3] = wpabuf_len(wps->dh_pubkey_r);
 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
 
-	if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
+	if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
 			   "not match with the pre-committed value");
 		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
@@ -892,7 +892,7 @@
 
 	if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
 		wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
-		os_free(wps->dev_password);
+		bin_clear_free(wps->dev_password, wps->dev_password_len);
 		wps->dev_pw_id = wps->alt_dev_pw_id;
 		wps->dev_password = wps->alt_dev_password;
 		wps->dev_password_len = wps->alt_dev_password_len;
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index b917e6b..00c8299 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -42,7 +42,7 @@
 static void wps_remove_nfc_pw_token(struct wps_nfc_pw_token *token)
 {
 	dl_list_del(&token->list);
-	os_free(token);
+	bin_clear_free(token, sizeof(*token));
 }
 
 
@@ -91,7 +91,7 @@
 
 static void wps_free_pin(struct wps_uuid_pin *pin)
 {
-	os_free(pin->pin);
+	bin_clear_free(pin->pin, pin->pin_len);
 	os_free(pin);
 }
 
@@ -826,7 +826,7 @@
 	{
 		if (dev_pw && pin->pin &&
 		    (dev_pw_len != pin->pin_len ||
-		     os_memcmp(dev_pw, pin->pin, dev_pw_len) != 0))
+		     os_memcmp_const(dev_pw, pin->pin, dev_pw_len) != 0))
 			continue; /* different PIN */
 		if (pin->wildcard_uuid) {
 			wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
@@ -1343,7 +1343,7 @@
 	const u8 *pin;
 	size_t pin_len = 0;
 
-	os_free(wps->dev_password);
+	bin_clear_free(wps->dev_password, wps->dev_password_len);
 	wps->dev_password = NULL;
 
 	if (wps->pbc) {
@@ -2211,7 +2211,7 @@
 	len[3] = wpabuf_len(wps->dh_pubkey_r);
 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
 
-	if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
+	if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
 			   "not match with the pre-committed value");
 		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
@@ -2251,7 +2251,7 @@
 	len[3] = wpabuf_len(wps->dh_pubkey_r);
 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
 
-	if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
+	if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
 			   "not match with the pre-committed value");
 		wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
@@ -2591,8 +2591,9 @@
 
 			addr[0] = attr->public_key;
 			sha256_vector(1, addr, &attr->public_key_len, hash);
-			if (os_memcmp(hash, wps->nfc_pw_token->pubkey_hash,
-				      WPS_OOB_PUBKEY_HASH_LEN) != 0) {
+			if (os_memcmp_const(hash,
+					    wps->nfc_pw_token->pubkey_hash,
+					    WPS_OOB_PUBKEY_HASH_LEN) != 0) {
 				wpa_printf(MSG_ERROR, "WPS: Public Key hash "
 					   "mismatch");
 				wps->state = SEND_M2D;