Cumulative patch from commit 801e117376e13d5b3c50f1627b93a949529fdf99

801e117 Fix validation of RSN EAPOL-Key version for GCMP with PMF
3d4d234 FT: Fix GTK rekeying after FT protocol
d3d0483 nl80211: Work around error case prints for nl_recvmsgs on Android
8a387a2 P2P NFC: Fix use of freed memory
df48efc Fix external radio work stopping to not read freed memory
13c3303 SAE: Fix memory leak in random number generation
d92bdf9 hostapd: Make sure hapd->drv_priv gets cleared on driver deinit
438e133 hostapd: Use helper function to avoid duplicate deinit calls
ac1a224 hostapd: Clean up if interface setup fails
81c4fca hostapd: Reset hapd->interface_add properly
3fbd036 hostapd: Prevent double interface disabling from segfaulting
ea39367 nl80211: Fix wpa_driver_nl80211_if_add() failure paths
b77aeae Interworking: Re-trigger scan if no connect attempt is done
b523973 RADIUS client: Trigger failover more quickly if socket is not valid
09844c0 RADIUS client: Do not flush pending messages if server did not change
5d67bf1 hostapd: Fix configuration of multiple RADIUS servers with SET
70d4084 RADIUS client: Fix socket close/re-open on server change
d045cc8 RADIUS client: Fix crash issue in radius_client_timer()
c1fb75a RADIUS client: Handle ENETUNREACH similarly to other failure cases
9ed4076 RADIUS client: Do not try to send message without socket
cc0b7cb hostapd_cli: Fix segmentation fault with interface command
114153b P2P: Debug print channel lists for invitation processing
4eb3b76 OpenSSL: Fix OCSP certificate debug print to use wpa_printf
f6fb192 HS 2.0R2: Fix subscr_remediation_method for RADIUS server
74879f3 Remove extra newline from a debug print

Change-Id: I82d4f00501fabb8b325e4461178b45e7b2c0178e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
new file mode 100644
index 0000000..56b1122
--- /dev/null
+++ b/src/common/common_module_tests.c
@@ -0,0 +1,172 @@
+/*
+ * common module tests
+ * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "ieee802_11_common.h"
+#include "wpa_common.h"
+
+
+struct ieee802_11_parse_test_data {
+	u8 *data;
+	size_t len;
+	ParseRes result;
+	int count;
+};
+
+static const struct ieee802_11_parse_test_data parse_tests[] = {
+	{ (u8 *) "", 0, ParseOK, 0 },
+	{ (u8 *) " ", 1, ParseFailed, 0 },
+	{ (u8 *) "\xff\x00", 2, ParseUnknown, 1 },
+	{ (u8 *) "\xff\x01", 2, ParseFailed, 0 },
+	{ (u8 *) "\xdd\x03\x01\x02\x03", 5, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x04\x01\x02\x03\x04", 6, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x04\x00\x50\xf2\x02", 6, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\x02", 7, ParseOK, 1 },
+	{ (u8 *) "\xdd\x05\x00\x50\xf2\x02\xff", 7, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x04\x00\x50\xf2\xff", 6, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x04\x50\x6f\x9a\xff", 6, ParseUnknown, 1 },
+	{ (u8 *) "\xdd\x04\x00\x90\x4c\x33", 6, ParseOK, 1 },
+	{ (u8 *) "\xdd\x04\x00\x90\x4c\xff\xdd\x04\x00\x90\x4c\x33", 12,
+	  ParseUnknown, 2 },
+	{ (u8 *) "\x10\x01\x00\x21\x00", 5, ParseOK, 2 },
+	{ (u8 *) "\x24\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\x38\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\x54\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\x5a\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\x65\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\x65\x12\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11",
+	  20, ParseOK, 1 },
+	{ (u8 *) "\x6e\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\xc7\x00", 2, ParseOK, 1 },
+	{ (u8 *) "\xc7\x01\x00", 3, ParseOK, 1 },
+	{ NULL, 0, ParseOK, 0 }
+};
+
+static int ieee802_11_parse_tests(void)
+{
+	int i, ret = 0;
+
+	wpa_printf(MSG_INFO, "ieee802_11_parse tests");
+
+	for (i = 0; parse_tests[i].data; i++) {
+		const struct ieee802_11_parse_test_data *test;
+		struct ieee802_11_elems elems;
+		ParseRes res;
+
+		test = &parse_tests[i];
+		res = ieee802_11_parse_elems(test->data, test->len, &elems, 1);
+		if (res != test->result ||
+		    ieee802_11_ie_count(test->data, test->len) != test->count) {
+			wpa_printf(MSG_ERROR, "ieee802_11_parse test %d failed",
+				   i);
+			ret = -1;
+		}
+	}
+
+	if (ieee802_11_vendor_ie_concat((const u8 *) "\x00\x01", 2, 0) != NULL)
+	{
+		wpa_printf(MSG_ERROR,
+			   "ieee802_11_vendor_ie_concat test failed");
+		ret = -1;
+	}
+
+	return ret;
+}
+
+
+struct rsn_ie_parse_test_data {
+	u8 *data;
+	size_t len;
+	int result;
+};
+
+static const struct rsn_ie_parse_test_data rsn_parse_tests[] = {
+	{ (u8 *) "", 0, -1 },
+	{ (u8 *) "\x30\x00", 2, -1 },
+	{ (u8 *) "\x30\x02\x01\x00", 4, 0 },
+	{ (u8 *) "\x30\x02\x00\x00", 4, -2 },
+	{ (u8 *) "\x30\x02\x02\x00", 4, -2 },
+	{ (u8 *) "\x30\x02\x00\x01", 4, -2 },
+	{ (u8 *) "\x30\x02\x00\x00\x00", 5, -2 },
+	{ (u8 *) "\x30\x03\x01\x00\x00", 5, -3 },
+	{ (u8 *) "\x30\x06\x01\x00\x00\x00\x00\x00", 8, -1 },
+	{ (u8 *) "\x30\x06\x01\x00\x00\x0f\xac\x04", 8, 0 },
+	{ (u8 *) "\x30\x07\x01\x00\x00\x0f\xac\x04\x00", 9, -5 },
+	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x00", 10, -4 },
+	{ (u8 *) "\x30\x08\x01\x00\x00\x0f\xac\x04\x00\x01", 10, -4 },
+	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
+	  14, 0 },
+	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x00\x01\x00\x0f\xac\x04",
+	  14, -4 },
+	{ (u8 *) "\x30\x0c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x06",
+	  14, -1 },
+	{ (u8 *) "\x30\x10\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x04\x00\x0f\xac\x08",
+	  18, 0 },
+	{ (u8 *) "\x30\x0d\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00",
+	  15, -7 },
+	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x00",
+	  16, -6 },
+	{ (u8 *) "\x30\x0e\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x00\x01",
+	  16, -6 },
+	{ (u8 *) "\x30\x12\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01",
+	  20, 0 },
+	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x02\x00\x00\x0f\xac\x01\x00\x0f\xac\x02",
+	  24, 0 },
+	{ (u8 *) "\x30\x13\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00",
+	  21, 0 },
+	{ (u8 *) "\x30\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00",
+	  22, 0 },
+	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00",
+	  24, 0 },
+	{ (u8 *) "\x30\x16\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x01",
+	  24, -9 },
+	{ (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x00\x00\x00",
+	  28, -10 },
+	{ (u8 *) "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06",
+	  28, 0 },
+	{ (u8 *) "\x30\x1c\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x00\x00\x00\x0f\xac\x06\x01\x02",
+	  30, 0 },
+	{ NULL, 0, 0 }
+};
+
+static int rsn_ie_parse_tests(void)
+{
+	int i, ret = 0;
+
+	wpa_printf(MSG_INFO, "rsn_ie_parse tests");
+
+	for (i = 0; rsn_parse_tests[i].data; i++) {
+		const struct rsn_ie_parse_test_data *test;
+		struct wpa_ie_data data;
+
+		test = &rsn_parse_tests[i];
+		if (wpa_parse_wpa_ie_rsn(test->data, test->len, &data) !=
+		    test->result) {
+			wpa_printf(MSG_ERROR, "rsn_ie_parse test %d failed", i);
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+
+int common_module_tests(void)
+{
+	int ret = 0;
+
+	wpa_printf(MSG_INFO, "common module tests");
+
+	if (ieee802_11_parse_tests() < 0 ||
+	    rsn_ie_parse_tests() < 0)
+		ret = -1;
+
+	return ret;
+}
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index cdee6bc..faa6a39 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -116,7 +116,7 @@
 		default:
 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
 				   "information element ignored "
-				   "(type=%d len=%lu)\n",
+				   "(type=%d len=%lu)",
 				   pos[3], (unsigned long) elen);
 			return -1;
 		}
diff --git a/src/common/sae.c b/src/common/sae.c
index 674cb65..c1b488e 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -134,8 +134,10 @@
 			return NULL;
 		if (crypto_bignum_is_zero(bn) ||
 		    crypto_bignum_is_one(bn) ||
-		    crypto_bignum_cmp(bn, sae->tmp->order) >= 0)
+		    crypto_bignum_cmp(bn, sae->tmp->order) >= 0) {
+			crypto_bignum_deinit(bn, 0);
 			continue;
+		}
 		break;
 	}