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/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 86d6d72..8cd4a2f 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -286,7 +286,7 @@
 {
 #ifdef CONFIG_EXT_PASSWORD
 	if (os_strncmp(value, "ext:", 4) == 0) {
-		os_free(ssid->passphrase);
+		str_clear_free(ssid->passphrase);
 		ssid->passphrase = NULL;
 		ssid->psk_set = 0;
 		os_free(ssid->ext_psk);
@@ -322,7 +322,7 @@
 		    os_memcmp(ssid->passphrase, value, len) == 0)
 			return 0;
 		ssid->psk_set = 0;
-		os_free(ssid->passphrase);
+		str_clear_free(ssid->passphrase);
 		ssid->passphrase = dup_binstr(value, len);
 		if (ssid->passphrase == NULL)
 			return -1;
@@ -341,7 +341,7 @@
 		return -1;
 	}
 
-	os_free(ssid->passphrase);
+	str_clear_free(ssid->passphrase);
 	ssid->passphrase = NULL;
 
 	ssid->psk_set = 1;
@@ -435,7 +435,7 @@
 static char * wpa_config_write_proto(const struct parse_data *data,
 				     struct wpa_ssid *ssid)
 {
-	int first = 1, ret;
+	int ret;
 	char *buf, *pos, *end;
 
 	pos = buf = os_zalloc(20);
@@ -444,27 +444,32 @@
 	end = buf + 20;
 
 	if (ssid->proto & WPA_PROTO_WPA) {
-		ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
+		ret = os_snprintf(pos, end - pos, "%sWPA",
+				  pos == buf ? "" : " ");
 		if (ret < 0 || ret >= end - pos)
 			return buf;
 		pos += ret;
-		first = 0;
 	}
 
 	if (ssid->proto & WPA_PROTO_RSN) {
-		ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
+		ret = os_snprintf(pos, end - pos, "%sRSN",
+				  pos == buf ? "" : " ");
 		if (ret < 0 || ret >= end - pos)
 			return buf;
 		pos += ret;
-		first = 0;
 	}
 
 	if (ssid->proto & WPA_PROTO_OSEN) {
-		ret = os_snprintf(pos, end - pos, "%sOSEN", first ? "" : " ");
+		ret = os_snprintf(pos, end - pos, "%sOSEN",
+				  pos == buf ? "" : " ");
 		if (ret < 0 || ret >= end - pos)
 			return buf;
 		pos += ret;
-		first = 0;
+	}
+
+	if (pos == buf) {
+		os_free(buf);
+		buf = NULL;
 	}
 
 	return buf;
@@ -672,6 +677,11 @@
 	}
 #endif /* CONFIG_WPS */
 
+	if (pos == buf) {
+		os_free(buf);
+		buf = NULL;
+	}
+
 	return buf;
 }
 #endif /* NO_CONFIG_WRITE */
@@ -863,6 +873,11 @@
 		pos += ret;
 	}
 
+	if (pos == buf) {
+		os_free(buf);
+		buf = NULL;
+	}
+
 	return buf;
 }
 #endif /* NO_CONFIG_WRITE */
@@ -1115,7 +1130,7 @@
 
 	if (os_strcmp(value, "NULL") == 0) {
 		wpa_printf(MSG_DEBUG, "Unset configuration string 'password'");
-		os_free(ssid->eap.password);
+		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
 		ssid->eap.password = NULL;
 		ssid->eap.password_len = 0;
 		return 0;
@@ -1126,7 +1141,7 @@
 		char *name = os_strdup(value + 4);
 		if (name == NULL)
 			return -1;
-		os_free(ssid->eap.password);
+		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
 		ssid->eap.password = (u8 *) name;
 		ssid->eap.password_len = os_strlen(name);
 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
@@ -1148,7 +1163,7 @@
 		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
 				      (u8 *) tmp, res_len);
 
-		os_free(ssid->eap.password);
+		bin_clear_free(ssid->eap.password, ssid->eap.password_len);
 		ssid->eap.password = (u8 *) tmp;
 		ssid->eap.password_len = res_len;
 		ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
@@ -1177,7 +1192,7 @@
 
 	wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
 
-	os_free(ssid->eap.password);
+	bin_clear_free(ssid->eap.password, ssid->eap.password_len);
 	ssid->eap.password = hash;
 	ssid->eap.password_len = 16;
 	ssid->eap.flags |= EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
@@ -1247,7 +1262,7 @@
 			   line, (unsigned int) *len);
 	}
 	os_memcpy(key, buf, *len);
-	os_free(buf);
+	str_clear_free(buf);
 	res = os_snprintf(title, sizeof(title), "wep_key%d", idx);
 	if (res >= 0 && (size_t) res < sizeof(title))
 		wpa_hexdump_key(MSG_MSGDUMP, title, key, *len);
@@ -1736,6 +1751,9 @@
 #ifdef CONFIG_MACSEC
 	{ INT_RANGE(macsec_policy, 0, 1) },
 #endif /* CONFIG_MACSEC */
+#ifdef CONFIG_HS20
+	{ INT(update_identifier) },
+#endif /* CONFIG_HS20 */
 };
 
 #undef OFFSET
@@ -1845,14 +1863,14 @@
 static void eap_peer_config_free(struct eap_peer_config *eap)
 {
 	os_free(eap->eap_methods);
-	os_free(eap->identity);
+	bin_clear_free(eap->identity, eap->identity_len);
 	os_free(eap->anonymous_identity);
-	os_free(eap->password);
+	bin_clear_free(eap->password, eap->password_len);
 	os_free(eap->ca_cert);
 	os_free(eap->ca_path);
 	os_free(eap->client_cert);
 	os_free(eap->private_key);
-	os_free(eap->private_key_passwd);
+	str_clear_free(eap->private_key_passwd);
 	os_free(eap->dh_file);
 	os_free(eap->subject_match);
 	os_free(eap->altsubject_match);
@@ -1861,7 +1879,7 @@
 	os_free(eap->ca_path2);
 	os_free(eap->client_cert2);
 	os_free(eap->private_key2);
-	os_free(eap->private_key2_passwd);
+	str_clear_free(eap->private_key2_passwd);
 	os_free(eap->dh_file2);
 	os_free(eap->subject_match2);
 	os_free(eap->altsubject_match2);
@@ -1869,7 +1887,7 @@
 	os_free(eap->phase1);
 	os_free(eap->phase2);
 	os_free(eap->pcsc);
-	os_free(eap->pin);
+	str_clear_free(eap->pin);
 	os_free(eap->engine_id);
 	os_free(eap->key_id);
 	os_free(eap->cert_id);
@@ -1877,13 +1895,13 @@
 	os_free(eap->key2_id);
 	os_free(eap->cert2_id);
 	os_free(eap->ca_cert2_id);
-	os_free(eap->pin2);
+	str_clear_free(eap->pin2);
 	os_free(eap->engine2_id);
 	os_free(eap->otp);
 	os_free(eap->pending_req_otp);
 	os_free(eap->pac_file);
-	os_free(eap->new_password);
-	os_free(eap->external_sim_resp);
+	bin_clear_free(eap->new_password, eap->new_password_len);
+	str_clear_free(eap->external_sim_resp);
 }
 #endif /* IEEE8021X_EAPOL */
 
@@ -1900,7 +1918,8 @@
 	struct psk_list_entry *psk;
 
 	os_free(ssid->ssid);
-	os_free(ssid->passphrase);
+	os_memset(ssid->psk, 0, sizeof(ssid->psk));
+	str_clear_free(ssid->passphrase);
 	os_free(ssid->ext_psk);
 #ifdef IEEE8021X_EAPOL
 	eap_peer_config_free(&ssid->eap);
@@ -1927,14 +1946,14 @@
 	size_t i;
 
 	os_free(cred->realm);
-	os_free(cred->username);
-	os_free(cred->password);
+	str_clear_free(cred->username);
+	str_clear_free(cred->password);
 	os_free(cred->ca_cert);
 	os_free(cred->client_cert);
 	os_free(cred->private_key);
-	os_free(cred->private_key_passwd);
+	str_clear_free(cred->private_key_passwd);
 	os_free(cred->imsi);
-	os_free(cred->milenage);
+	str_clear_free(cred->milenage);
 	for (i = 0; i < cred->num_domain; i++)
 		os_free(cred->domain[i]);
 	os_free(cred->domain);
@@ -2004,7 +2023,7 @@
 	os_free(config->pkcs11_engine_path);
 	os_free(config->pkcs11_module_path);
 	os_free(config->pcsc_reader);
-	os_free(config->pcsc_pin);
+	str_clear_free(config->pcsc_pin);
 	os_free(config->driver_param);
 	os_free(config->device_name);
 	os_free(config->manufacturer);
@@ -2388,7 +2407,7 @@
 					wpa_printf(MSG_DEBUG, "Do not allow "
 						   "key_data field to be "
 						   "exposed");
-					os_free(res);
+					str_clear_free(res);
 					return os_strdup("*");
 				}
 
@@ -2534,7 +2553,7 @@
 
 	if (os_strcmp(var, "password") == 0 &&
 	    os_strncmp(value, "ext:", 4) == 0) {
-		os_free(cred->password);
+		str_clear_free(cred->password);
 		cred->password = os_strdup(value);
 		cred->ext_password = 1;
 		return 0;
@@ -2597,13 +2616,13 @@
 	}
 
 	if (os_strcmp(var, "username") == 0) {
-		os_free(cred->username);
+		str_clear_free(cred->username);
 		cred->username = val;
 		return 0;
 	}
 
 	if (os_strcmp(var, "password") == 0) {
-		os_free(cred->password);
+		str_clear_free(cred->password);
 		cred->password = val;
 		cred->ext_password = 0;
 		return 0;
@@ -2628,7 +2647,7 @@
 	}
 
 	if (os_strcmp(var, "private_key_passwd") == 0) {
-		os_free(cred->private_key_passwd);
+		str_clear_free(cred->private_key_passwd);
 		cred->private_key_passwd = val;
 		return 0;
 	}
@@ -2640,7 +2659,7 @@
 	}
 
 	if (os_strcmp(var, "milenage") == 0) {
-		os_free(cred->milenage);
+		str_clear_free(cred->milenage);
 		cred->milenage = val;
 		return 0;
 	}
@@ -2808,7 +2827,7 @@
 }
 
 
-char * alloc_int_str(int val)
+static char * alloc_int_str(int val)
 {
 	char *buf;
 
@@ -2820,7 +2839,7 @@
 }
 
 
-char * alloc_strdup(const char *str)
+static char * alloc_strdup(const char *str)
 {
 	if (str == NULL)
 		return NULL;
@@ -3192,7 +3211,7 @@
 {
 	if (blob) {
 		os_free(blob->name);
-		os_free(blob->data);
+		bin_clear_free(blob->data, blob->len);
 		os_free(blob);
 	}
 }