Update to new version 0.8.16 from BRCM

Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91
Author: Neeraj Kumar Garg <neerajkg@broadcom.com>
Date:   Tue Dec 27 23:21:45 2011 +0200
    P2P: Reject p2p_group_add if forced frequency is not acceptable

Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/tls/tlsv1_server.c b/src/tls/tlsv1_server.c
index 6a61235..96e160c 100644
--- a/src/tls/tlsv1_server.c
+++ b/src/tls/tlsv1_server.c
@@ -1,6 +1,6 @@
 /*
- * TLSv1 server (RFC 2246)
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
+ * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -49,7 +49,8 @@
 		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
 		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
 			  TLS_RANDOM_LEN);
-		if (tls_prf(pre_master_secret, pre_master_secret_len,
+		if (tls_prf(conn->rl.tls_version,
+			    pre_master_secret, pre_master_secret_len,
 			    "master secret", seed, 2 * TLS_RANDOM_LEN,
 			    conn->master_secret, TLS_MASTER_SECRET_LEN)) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
@@ -64,7 +65,8 @@
 	os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
 	key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
 			     conn->rl.iv_size);
-	if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
+	if (tls_prf(conn->rl.tls_version,
+		    conn->master_secret, TLS_MASTER_SECRET_LEN,
 		    "key expansion", seed, 2 * TLS_RANDOM_LEN,
 		    key_block, key_block_len)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
@@ -115,6 +117,7 @@
 	const u8 *pos, *end;
 	u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
 	size_t in_msg_len;
+	int used;
 
 	if (in_data == NULL || in_len == 0) {
 		wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
@@ -130,13 +133,21 @@
 	/* Each received packet may include multiple records */
 	while (pos < end) {
 		in_msg_len = in_len;
-		if (tlsv1_record_receive(&conn->rl, pos, end - pos,
-					 in_msg, &in_msg_len, &alert)) {
+		used = tlsv1_record_receive(&conn->rl, pos, end - pos,
+					    in_msg, &in_msg_len, &alert);
+		if (used < 0) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
 				   "record failed");
 			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
 			goto failed;
 		}
+		if (used == 0) {
+			/* need more data */
+			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
+				   "yet supported");
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
+			goto failed;
+		}
 		ct = pos[0];
 
 		in_pos = in_msg;
@@ -152,7 +163,7 @@
 			in_pos += in_msg_len;
 		}
 
-		pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
+		pos += used;
 	}
 
 	os_free(in_msg);
@@ -201,10 +212,8 @@
 	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
 			in_data, in_len);
 
-	os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
-
 	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
-			      out_data, out_len, in_len, &rlen) < 0) {
+			      out_data, out_len, in_data, in_len, &rlen) < 0) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
 				   TLS_ALERT_INTERNAL_ERROR);
@@ -232,8 +241,8 @@
 			 u8 *out_data, size_t out_len)
 {
 	const u8 *in_end, *pos;
-	int res;
-	u8 alert, *out_end, *out_pos;
+	int used;
+	u8 alert, *out_end, *out_pos, ct;
 	size_t olen;
 
 	pos = in_data;
@@ -242,7 +251,46 @@
 	out_end = out_data + out_len;
 
 	while (pos < in_end) {
-		if (pos[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
+		ct = pos[0];
+		olen = out_end - out_pos;
+		used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
+					    out_pos, &olen, &alert);
+		if (used < 0) {
+			wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
+				   "failed");
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
+			return -1;
+		}
+		if (used == 0) {
+			/* need more data */
+			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
+				   "yet supported");
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
+			return -1;
+		}
+
+		if (ct == TLS_CONTENT_TYPE_ALERT) {
+			if (olen < 2) {
+				wpa_printf(MSG_DEBUG, "TLSv1: Alert "
+					   "underflow");
+				tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
+						   TLS_ALERT_DECODE_ERROR);
+				return -1;
+			}
+			wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
+				   out_pos[0], out_pos[1]);
+			if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
+				/* Continue processing */
+				pos += used;
+				continue;
+			}
+
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
+					   out_pos[1]);
+			return -1;
+		}
+
+		if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "
 				   "0x%x", pos[0]);
 			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
@@ -250,15 +298,6 @@
 			return -1;
 		}
 
-		olen = out_end - out_pos;
-		res = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
-					   out_pos, &olen, &alert);
-		if (res < 0) {
-			wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
-				   "failed");
-			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
-			return -1;
-		}
 		out_pos += olen;
 		if (out_pos > out_end) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
@@ -268,7 +307,7 @@
 			return -1;
 		}
 
-		pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
+		pos += used;
 	}
 
 	return out_pos - out_data;
@@ -412,7 +451,8 @@
 			  TLS_RANDOM_LEN);
 	}
 
-	return tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
+	return tls_prf(conn->rl.tls_version,
+		       conn->master_secret, TLS_MASTER_SECRET_LEN,
 		       label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
 }