Cumulative patch from commit 8c43ef8449bd4d2d0983db394770bd73f572b12d

8c43ef8 P2PS: Fix attribute addition in p2p_buf_add_service_instance()
a9ea609 P2PS: Fix p2p_find last parameter handling
6c73149 AP: Increase maximum value accepted for cwmin/cwmax
575e4f5 SAE: Reject FFC commit-element with value p-1
a406244 P2PS: Do not reply to ProbeReq on another channel when starting Listen
0c2b3f6 SAE: Reject commit-scalar value 1
4f39908 Send CTRL-EVENT-NETWORK-NOT-FOUND if no suitable network was found
123df27 D-Bus: Fix typos in debug print
ded14ce Android: Fix nl80211 build if BOARD_*_PRIVATE_LIB is unspecified
a140721 Android: Rename ANDROID_P2P_STUB to ANDROID_LIB_STUB
2ba4de3 D-Bus: Add documentation for wpas_dbus_signal_peer_groups_changed()
e48b5e2 D-Bus: Fix typo in dbus signal function documentation
09d5048 D-Bus: Add function documentation for wpas_dbus_unregister_interface()
adfbbd2 D-Bus: Add function documentation for wpas_dbus_register_interface()
c5967f0 D-Bus: Fix wpas_dbus_signal_p2p_invitation_result() documentation
4457f41 radius: Fix NULL dereference issue on allocation failure
f826fb1 OpenSSL: Handle EC_POINT_is_on_curve() error case
bbb5008 SAE: Use random "password" in extra hunting-and-pecking loops
eb5fee0 SAE: Add side-channel protection to PWE derivation with ECC
16841ab crypto: Add functions for computing the Legendre symbol and EC y^2
c4a13b4 OpenSSL: Add support for Brainpool Elliptic Curves
4584b66 SAE: Increase security parameter k to 40 based on Dragonfly recommendation
fdd731b SAE: Fix PWE generation to use minimum loop count (k) properly
8ec3332 SAE: Merge sae_derive_commit() error case return statements
d93abd4 SAE: Merge sae_get_rand() error case return statements
6a58444 SAE: Verify that own/peer commit-scalar and COMMIT-ELEMENT are different
4e7e688 Add crypto_ec_point_cmp()
8e2a3a4 dbus: Do not initialize variable twice
c1a14ef Do not check unsigned size is less than zero
fdc5608 OpenSSL: Remove SSL_CTX_{get,set}_app_data() compatibility wrapper
ba54933 libtommath: Fix mp_init_multi() stdarg use on error path
f6332b0 wpa_gui: Initialize WpaGuiApp::w in the constructor
f6df3f3 Use os_* wrapper more consistently
91b7a5e Use unsigned/signed printf format more consistently
59bae74 HS 2.0R2: Fix memory leak on error path in hs20-osu-client
c5ca73d P2P: Use offsetof() instead of local implementation
c3c5b5f ERP server: Make erp_send_finish_reauth() easier for static analyzers
6ce1bea bsd: Remove redundant NULL check in bsd_init()
c99df20 Remove redundant NULL check in ieee802_1x_encapsulate_radius()
2eb5967 AP: Add more 2.4 GHz channels for 20/40 MHz HT co-ex scan
5ed6519 hw_features: Merge similar return cases
4e37dd6 SAE: Simplify sae_prepare_commit() error path
04e6c4c Fix SAE group selection in an error case
3dce85c HS 2.0: Add WLAN RADIUS attributes in OSEN case
efd5d26 Remove unnecessary wpa_ie_len check from wpa_parse_wpa_ie_wpa()
ce8963f Remove WEP40/WEP104 cipher suite support for WPA/WPA2
ee140ef FT: Stop association attempt if Auth response processing fails (SME)
1887be4 Make check_20mhz_bss() static

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>

Bug: 22062116
Change-Id: Ie1d175f1faab24bf39ce81ead7a078e1e236badd
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index f2d5662..534c4bd 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -614,6 +614,15 @@
 int crypto_bignum_is_one(const struct crypto_bignum *a);
 
 /**
+ * crypto_bignum_legendre - Compute the Legendre symbol (a/p)
+ * @a: Bignum
+ * @p: Bignum
+ * Returns: Legendre symbol -1,0,1 on success; -2 on calculation failure
+ */
+int crypto_bignum_legendre(const struct crypto_bignum *a,
+			   const struct crypto_bignum *p);
+
+/**
  * struct crypto_ec - Elliptic curve context
  *
  * Internal data structure for EC implementation. The contents is specific
@@ -758,6 +767,16 @@
 				  const struct crypto_bignum *x, int y_bit);
 
 /**
+ * crypto_ec_point_compute_y_sqr - Compute y^2 = x^3 + ax + b
+ * @e: EC context from crypto_ec_init()
+ * @x: x coordinate
+ * Returns: y^2 on success, %NULL failure
+ */
+struct crypto_bignum *
+crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
+			      const struct crypto_bignum *x);
+
+/**
  * crypto_ec_point_is_at_infinity - Check whether EC point is neutral element
  * @e: EC context from crypto_ec_init()
  * @p: EC point
@@ -776,4 +795,15 @@
 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
 				const struct crypto_ec_point *p);
 
+/**
+ * crypto_ec_point_cmp - Compare two EC points
+ * @e: EC context from crypto_ec_init()
+ * @a: EC point
+ * @b: EC point
+ * Returns: 0 on equal, non-zero otherwise
+ */
+int crypto_ec_point_cmp(const struct crypto_ec *e,
+			const struct crypto_ec_point *a,
+			const struct crypto_ec_point *b);
+
 #endif /* CRYPTO_H */
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 9834b25..3703b93 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1107,6 +1107,42 @@
 }
 
 
+int crypto_bignum_legendre(const struct crypto_bignum *a,
+			   const struct crypto_bignum *p)
+{
+	BN_CTX *bnctx;
+	BIGNUM *exp = NULL, *tmp = NULL;
+	int res = -2;
+
+	bnctx = BN_CTX_new();
+	if (bnctx == NULL)
+		return -2;
+
+	exp = BN_new();
+	tmp = BN_new();
+	if (!exp || !tmp ||
+	    /* exp = (p-1) / 2 */
+	    !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
+	    !BN_rshift1(exp, exp) ||
+	    !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
+			bnctx))
+		goto fail;
+
+	if (BN_is_word(tmp, 1))
+		res = 1;
+	else if (BN_is_zero(tmp))
+		res = 0;
+	else
+		res = -1;
+
+fail:
+	BN_clear_free(tmp);
+	BN_clear_free(exp);
+	BN_CTX_free(bnctx);
+	return res;
+}
+
+
 #ifdef CONFIG_ECC
 
 struct crypto_ec {
@@ -1114,6 +1150,8 @@
 	BN_CTX *bnctx;
 	BIGNUM *prime;
 	BIGNUM *order;
+	BIGNUM *a;
+	BIGNUM *b;
 };
 
 struct crypto_ec * crypto_ec_init(int group)
@@ -1138,6 +1176,26 @@
 	case 26:
 		nid = NID_secp224r1;
 		break;
+#ifdef NID_brainpoolP224r1
+	case 27:
+		nid = NID_brainpoolP224r1;
+		break;
+#endif /* NID_brainpoolP224r1 */
+#ifdef NID_brainpoolP256r1
+	case 28:
+		nid = NID_brainpoolP256r1;
+		break;
+#endif /* NID_brainpoolP256r1 */
+#ifdef NID_brainpoolP384r1
+	case 29:
+		nid = NID_brainpoolP384r1;
+		break;
+#endif /* NID_brainpoolP384r1 */
+#ifdef NID_brainpoolP512r1
+	case 30:
+		nid = NID_brainpoolP512r1;
+		break;
+#endif /* NID_brainpoolP512r1 */
 	default:
 		return NULL;
 	}
@@ -1150,9 +1208,11 @@
 	e->group = EC_GROUP_new_by_curve_name(nid);
 	e->prime = BN_new();
 	e->order = BN_new();
+	e->a = BN_new();
+	e->b = BN_new();
 	if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
-	    e->order == NULL ||
-	    !EC_GROUP_get_curve_GFp(e->group, e->prime, NULL, NULL, e->bnctx) ||
+	    e->order == NULL || e->a == NULL || e->b == NULL ||
+	    !EC_GROUP_get_curve_GFp(e->group, e->prime, e->a, e->b, e->bnctx) ||
 	    !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
 		crypto_ec_deinit(e);
 		e = NULL;
@@ -1166,6 +1226,8 @@
 {
 	if (e == NULL)
 		return;
+	BN_clear_free(e->b);
+	BN_clear_free(e->a);
 	BN_clear_free(e->order);
 	BN_clear_free(e->prime);
 	EC_GROUP_free(e->group);
@@ -1313,6 +1375,33 @@
 }
 
 
+struct crypto_bignum *
+crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
+			      const struct crypto_bignum *x)
+{
+	BIGNUM *tmp, *tmp2, *y_sqr = NULL;
+
+	tmp = BN_new();
+	tmp2 = BN_new();
+
+	/* y^2 = x^3 + ax + b */
+	if (tmp && tmp2 &&
+	    BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
+	    BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
+	    BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
+	    BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
+	    BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
+		y_sqr = tmp2;
+		tmp2 = NULL;
+	}
+
+	BN_clear_free(tmp);
+	BN_clear_free(tmp2);
+
+	return (struct crypto_bignum *) y_sqr;
+}
+
+
 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
 				   const struct crypto_ec_point *p)
 {
@@ -1323,7 +1412,17 @@
 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
 				const struct crypto_ec_point *p)
 {
-	return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p, e->bnctx);
+	return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
+				    e->bnctx) == 1;
+}
+
+
+int crypto_ec_point_cmp(const struct crypto_ec *e,
+			const struct crypto_ec_point *a,
+			const struct crypto_ec_point *b)
+{
+	return EC_POINT_cmp(e->group, (const EC_POINT *) a,
+			    (const EC_POINT *) b, e->bnctx);
 }
 
 #endif /* CONFIG_ECC */
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 37ab000..2250e6e 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -29,10 +29,6 @@
 #include "sha1.h"
 #include "tls.h"
 
-#if defined(SSL_CTX_get_app_data) && defined(SSL_CTX_set_app_data)
-#define OPENSSL_SUPPORTS_CTX_APP_DATA
-#endif
-
 #if OPENSSL_VERSION_NUMBER < 0x10000000L
 /* ERR_remove_thread_state replaces ERR_remove_state and the latter is
  * deprecated. However, OpenSSL 0.9.8 doesn't include
@@ -793,24 +789,17 @@
 		PKCS12_PBE_add();
 #endif  /* PKCS12_FUNCS */
 	} else {
-#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
-		/* Newer OpenSSL can store app-data per-SSL */
 		context = tls_context_new(conf);
 		if (context == NULL)
 			return NULL;
-#else /* OPENSSL_SUPPORTS_CTX_APP_DATA */
-		context = tls_global;
-#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
 	}
 	tls_openssl_ref_count++;
 
 	ssl = SSL_CTX_new(SSLv23_method());
 	if (ssl == NULL) {
 		tls_openssl_ref_count--;
-#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
 		if (context != tls_global)
 			os_free(context);
-#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
 		if (tls_openssl_ref_count == 0) {
 			os_free(tls_global);
 			tls_global = NULL;
@@ -822,9 +811,7 @@
 	SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
 
 	SSL_CTX_set_info_callback(ssl, ssl_info_cb);
-#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
 	SSL_CTX_set_app_data(ssl, context);
-#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
 
 #ifndef OPENSSL_NO_ENGINE
 	wpa_printf(MSG_DEBUG, "ENGINE: Loading dynamic engine");
@@ -862,11 +849,9 @@
 void tls_deinit(void *ssl_ctx)
 {
 	SSL_CTX *ssl = ssl_ctx;
-#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
 	struct tls_context *context = SSL_CTX_get_app_data(ssl);
 	if (context != tls_global)
 		os_free(context);
-#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
 	SSL_CTX_free(ssl);
 
 	tls_openssl_ref_count--;
@@ -1083,11 +1068,7 @@
 	SSL_CTX *ssl = ssl_ctx;
 	struct tls_connection *conn;
 	long options;
-#ifdef OPENSSL_SUPPORTS_CTX_APP_DATA
 	struct tls_context *context = SSL_CTX_get_app_data(ssl);
-#else /* OPENSSL_SUPPORTS_CTX_APP_DATA */
-	struct tls_context *context = tls_global;
-#endif /* OPENSSL_SUPPORTS_CTX_APP_DATA */
 
 	conn = os_zalloc(sizeof(*conn));
 	if (conn == NULL)