Cumulative patch from commit 681278246232029c334117bd6dc7e74c6b179f96

6812782 hlr_auc_gw: Allow Milenage RES length to be reduced
4839f7c wpa_cli: Fix a typo in usage text
a20a361 wpa_supplicant: Clear blacklist on connect
0144ecb Android: wpa_ctrl missing include for sys/stat.h
0bb20ef HS 2.0R2: Allow user to specify spp.xsd file location
97c9991 HS 2.0R2: Add more debugging messages to hs20-osu-client
93c2e60 HS 2.0R2 CA: Improve setup.sh and .conf for more flexibility
02e122a Reschedule scan from wpas_stop_pno if it was postponed
80fd9c3 EAP-PEAP server: Add support for negotiating vendor for Phase 2
a867082 EAP peer: Use 32-bit EAP method type for Phase 2 processing
56dfc49 Fix a typo in configuration parameter documentation
c4b45c6 TLS: Fix memory leaks on tls_connection_set_params() error paths
af85191 Make tls_connection_get_keyblock_size() internal to tls_*.c
94f1fe6 Remove master key extraction from tls_connection_get_keys()
fa0e715 Use tls_connection_prf() for all EAP TLS-based key derivation
df8191d Rename HT 20/40 coex variable to be more descriptive
1d0f42a EAP server: Add debug prints to help asleap testing
2c1cf90 Add wpa_snprintf_hex_sep()
5955cfa ms_funcs: Make challenge_hash() non-static

Change-Id: I0f3e5e5170a61e458949a675641946d95598dc5d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c
index 0c955da..afd4695 100644
--- a/src/crypto/tls_internal.c
+++ b/src/crypto/tls_internal.c
@@ -192,26 +192,31 @@
 
 	if (params->subject_match) {
 		wpa_printf(MSG_INFO, "TLS: subject_match not supported");
+		tlsv1_cred_free(cred);
 		return -1;
 	}
 
 	if (params->altsubject_match) {
 		wpa_printf(MSG_INFO, "TLS: altsubject_match not supported");
+		tlsv1_cred_free(cred);
 		return -1;
 	}
 
 	if (params->suffix_match) {
 		wpa_printf(MSG_INFO, "TLS: suffix_match not supported");
+		tlsv1_cred_free(cred);
 		return -1;
 	}
 
 	if (params->domain_match) {
 		wpa_printf(MSG_INFO, "TLS: domain_match not supported");
+		tlsv1_cred_free(cred);
 		return -1;
 	}
 
 	if (params->openssl_ciphers) {
-		wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported");
+		wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported");
+		tlsv1_cred_free(cred);
 		return -1;
 	}
 
@@ -348,25 +353,57 @@
 }
 
 
-int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
-		       const char *label, int server_random_first,
-		       u8 *out, size_t out_len)
+static int tls_get_keyblock_size(struct tls_connection *conn)
 {
 #ifdef CONFIG_TLS_INTERNAL_CLIENT
+	if (conn->client)
+		return tlsv1_client_get_keyblock_size(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+	if (conn->server)
+		return tlsv1_server_get_keyblock_size(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+	return -1;
+}
+
+
+int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
+		       const char *label, int server_random_first,
+		       int skip_keyblock, u8 *out, size_t out_len)
+{
+	int ret = -1, skip = 0;
+	u8 *tmp_out = NULL;
+	u8 *_out = out;
+
+	if (skip_keyblock) {
+		skip = tls_get_keyblock_size(conn);
+		if (skip < 0)
+			return -1;
+		tmp_out = os_malloc(skip + out_len);
+		if (!tmp_out)
+			return -1;
+		_out = tmp_out;
+	}
+
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
 	if (conn->client) {
-		return tlsv1_client_prf(conn->client, label,
-					server_random_first,
-					out, out_len);
+		ret = tlsv1_client_prf(conn->client, label,
+				       server_random_first,
+				       _out, out_len);
 	}
 #endif /* CONFIG_TLS_INTERNAL_CLIENT */
 #ifdef CONFIG_TLS_INTERNAL_SERVER
 	if (conn->server) {
-		return tlsv1_server_prf(conn->server, label,
-					server_random_first,
-					out, out_len);
+		ret = tlsv1_server_prf(conn->server, label,
+				       server_random_first,
+				       _out, out_len);
 	}
 #endif /* CONFIG_TLS_INTERNAL_SERVER */
-	return -1;
+	if (ret == 0 && skip_keyblock)
+		os_memcpy(out, _out + skip, out_len);
+	bin_clear_free(tmp_out, skip);
+
+	return ret;
 }
 
 
@@ -637,21 +674,6 @@
 }
 
 
-int tls_connection_get_keyblock_size(void *tls_ctx,
-				     struct tls_connection *conn)
-{
-#ifdef CONFIG_TLS_INTERNAL_CLIENT
-	if (conn->client)
-		return tlsv1_client_get_keyblock_size(conn->client);
-#endif /* CONFIG_TLS_INTERNAL_CLIENT */
-#ifdef CONFIG_TLS_INTERNAL_SERVER
-	if (conn->server)
-		return tlsv1_server_get_keyblock_size(conn->server);
-#endif /* CONFIG_TLS_INTERNAL_SERVER */
-	return -1;
-}
-
-
 unsigned int tls_capabilities(void *tls_ctx)
 {
 	return 0;