Cumulative patch from commit 01a025937c67f0eca6021d94b8ec3b144f8b1730

01a0259 WPS: Add support for 60 GHz band
0ef1e29 WPS: Fix shorter authentication timeout during no-SelReg iteration
3465176 nl80211: Verify that cipher suite conversion succeeds
a250722 Try to set PMK only with key mgmt offload support in the driver
4a7ce98 Make IPv6 NA multicast-to-unicast conversion configurable
9f390f4 Interworking: Fix network selection warning without SIM/USIM support
a0ad9e8 Remove WPA per-VLAN groups when no more stations remain
87b5b53 Make VLAN ID available in STA info over control interface
5678a2d P2P: Allow wpa_supplicant to start if social channels are not supported
209214b vlan: Move CONFIG_FULL_DYNAMIC_VLAN includes to proper places
a6da824 Do not use C++ reserved words as variable names
eaa3728 wpa_gui: Themed icon loader
9a3cb41 Fix wpa_priv (CONFIG_PRIVSEP=y) build
8b423ed Declare all read only data structures as const
fd4fb28 OpenSSL: Try to ensure we don't throw away the PIN unnecessarily
fabc6dd mesh: Retransmit the last Commit Message in the Committed state
068669f vlan: Verify RADIUS returned VLAN-ID and dynamic_vlan=required
5add410 WPS: Use shorter authentication timeout during no-SelReg iteration
e7d2034 WPS: Enforce five second minimum time before AP iteration
bd143cc Remove trailing whitespace from Makefile
74802c0 P2P: Do not create a P2P Device interface if P2P is disabled
579674e Document p2p_disabled option in wpa_supplicant.conf
8ea8a89 nl80211: Extend unique MAC address assignment for station iftype

Change-Id: I8bc8a63f37c0892b83376b9d5a5859827ae50554
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c
index 7137c27..1d613c9 100644
--- a/src/crypto/crypto_module_tests.c
+++ b/src/crypto/crypto_module_tests.c
@@ -161,7 +161,7 @@
 	u8 tag[16];
 };
 
-static struct omac1_test_vector omac1_test_vectors[] =
+static const struct omac1_test_vector omac1_test_vectors[] =
 {
 	{
 		{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
@@ -210,7 +210,8 @@
 };
 
 
-static int test_omac1_vector(struct omac1_test_vector *tv, unsigned int i)
+static int test_omac1_vector(const struct omac1_test_vector *tv,
+			     unsigned int i)
 {
 	u8 key[] = {
 		0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
@@ -983,14 +984,14 @@
 }
 
 
-static u8 key0[] =
+static const u8 key0[] =
 {
 	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
 	0x0b, 0x0b, 0x0b, 0x0b
 };
-static u8 data0[] = "Hi There";
-static u8 prf0[] =
+static const u8 data0[] = "Hi There";
+static const u8 prf0[] =
 {
 	0xbc, 0xd4, 0xc6, 0x50, 0xb3, 0x0b, 0x96, 0x84,
 	0x95, 0x18, 0x29, 0xe0, 0xd7, 0x5f, 0x9d, 0x54,
@@ -1002,9 +1003,9 @@
 	0xdb, 0x83, 0x73, 0x69, 0x83, 0x56, 0xcf, 0x5a
 };
 
-static u8 key1[] = "Jefe";
-static u8 data1[] = "what do ya want for nothing?";
-static u8 prf1[] =
+static const u8 key1[] = "Jefe";
+static const u8 data1[] = "what do ya want for nothing?";
+static const u8 prf1[] =
 {
 	0x51, 0xf4, 0xde, 0x5b, 0x33, 0xf2, 0x49, 0xad,
 	0xf8, 0x1a, 0xeb, 0x71, 0x3a, 0x3c, 0x20, 0xf4,
@@ -1017,13 +1018,13 @@
 };
 
 
-static u8 key2[] =
+static const u8 key2[] =
 {
 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
 	0xaa, 0xaa, 0xaa, 0xaa
 };
-static u8 data2[] =
+static const u8 data2[] =
 {
 	0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
 	0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
@@ -1033,7 +1034,7 @@
 	0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
 	0xdd, 0xdd
 };
-static u8 prf2[] =
+static const u8 prf2[] =
 {
 	0xe1, 0xac, 0x54, 0x6e, 0xc4, 0xcb, 0x63, 0x6f,
 	0x99, 0x76, 0x48, 0x7b, 0xe5, 0xc8, 0x6b, 0xe1,
@@ -1052,7 +1053,7 @@
 	char psk[32];
 };
 
-static struct passphrase_test passphrase_tests[] =
+static const struct passphrase_test passphrase_tests[] =
 {
 	{
 		"password",
@@ -1097,7 +1098,7 @@
 	size_t dk_len;
 };
 
-static struct rfc6070_test rfc6070_tests[] =
+static const struct rfc6070_test rfc6070_tests[] =
 {
 	{
 		"password",
@@ -1214,7 +1215,7 @@
 	wpa_printf(MSG_INFO, "PBKDF2-SHA1 Passphrase test cases:");
 	for (i = 0; i < NUM_PASSPHRASE_TESTS; i++) {
 		u8 psk[32];
-		struct passphrase_test *test = &passphrase_tests[i];
+		const struct passphrase_test *test = &passphrase_tests[i];
 
 		if (pbkdf2_sha1(test->passphrase,
 				(const u8 *) test->ssid, strlen(test->ssid),
@@ -1230,7 +1231,7 @@
 	wpa_printf(MSG_INFO, "PBKDF2-SHA1 test cases (RFC 6070):");
 	for (i = 0; i < NUM_RFC6070_TESTS; i++) {
 		u8 dk[25];
-		struct rfc6070_test *test = &rfc6070_tests[i];
+		const struct rfc6070_test *test = &rfc6070_tests[i];
 
 		if (pbkdf2_sha1(test->p, (const u8 *) test->s, strlen(test->s),
 				test->c, dk, test->dk_len) == 0 &&
@@ -1248,7 +1249,7 @@
 }
 
 
-struct {
+const struct {
 	char *data;
 	u8 hash[32];
 } tests[] = {
@@ -1272,7 +1273,7 @@
 	}
 };
 
-struct hmac_test {
+const struct hmac_test {
 	u8 key[80];
 	size_t key_len;
 	u8 data[128];
@@ -1513,7 +1514,7 @@
 	}
 
 	for (i = 0; i < ARRAY_SIZE(hmac_tests); i++) {
-		struct hmac_test *t = &hmac_tests[i];
+		const struct hmac_test *t = &hmac_tests[i];
 
 		wpa_printf(MSG_INFO, "HMAC-SHA256 test case %d:", i + 1);
 
diff --git a/src/crypto/dh_groups.c b/src/crypto/dh_groups.c
index d3b2631..3aeb2bb 100644
--- a/src/crypto/dh_groups.c
+++ b/src/crypto/dh_groups.c
@@ -1153,7 +1153,7 @@
 dh_group ## id ## _order, sizeof(dh_group ## id ## _order), safe }
 		
 
-static struct dh_group dh_groups[] = {
+static const struct dh_group dh_groups[] = {
 	DH_GROUP(5, 1),
 #ifdef ALL_DH_GROUPS
 	DH_GROUP(1, 1),
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index f9e2e10..d13657e 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -253,6 +253,7 @@
 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn);
 
 enum {
+	TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN = -4,
 	TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3,
 	TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2
 };
@@ -263,10 +264,12 @@
  * @conn: Connection context data from tls_connection_init()
  * @params: Connection parameters
  * Returns: 0 on success, -1 on failure,
- * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on possible PIN error causing
- * PKCS#11 engine failure, or
+ * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
+ * failure, or
  * TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
- * PKCS#11 engine private key.
+ * PKCS#11 engine private key, or
+ * TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
+ * failure.
  */
 int __must_check
 tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
@@ -277,10 +280,12 @@
  * @tls_ctx: TLS context data from tls_init()
  * @params: Global TLS parameters
  * Returns: 0 on success, -1 on failure,
- * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on possible PIN error causing
- * PKCS#11 engine failure, or
+ * TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
+ * failure, or
  * TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
- * PKCS#11 engine private key.
+ * PKCS#11 engine private key, or
+ * TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
+ * failure.
  */
 int __must_check tls_global_set_params(
 	void *tls_ctx, const struct tls_connection_params *params);
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index cbd35c4..ffcf83a 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -890,6 +890,27 @@
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id);
 #endif
 
+#ifndef OPENSSL_NO_ENGINE
+
+/* Cryptoki return values */
+#define CKR_PIN_INCORRECT 0x000000a0
+#define CKR_PIN_INVALID 0x000000a1
+#define CKR_PIN_LEN_RANGE 0x000000a2
+
+/* libp11 */
+#define ERR_LIB_PKCS11	ERR_LIB_USER
+
+static int tls_is_pin_error(unsigned int err)
+{
+	return ERR_GET_LIB(err) == ERR_LIB_PKCS11 &&
+		(ERR_GET_REASON(err) == CKR_PIN_INCORRECT ||
+		 ERR_GET_REASON(err) == CKR_PIN_INVALID ||
+		 ERR_GET_REASON(err) == CKR_PIN_LEN_RANGE);
+}
+
+#endif /* OPENSSL_NO_ENGINE */
+
+
 static int tls_engine_init(struct tls_connection *conn, const char *engine_id,
 			   const char *pin, const char *key_id,
 			   const char *cert_id, const char *ca_cert_id)
@@ -957,11 +978,16 @@
 							    key_id, NULL,
 							    &key_cb);
 		if (!conn->private_key) {
+			unsigned long err = ERR_get_error();
+
 			wpa_printf(MSG_ERROR,
 				   "ENGINE: cannot load private key with id '%s' [%s]",
 				   key_id,
-				   ERR_error_string(ERR_get_error(), NULL));
-			ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
+				   ERR_error_string(err, NULL));
+			if (tls_is_pin_error(err))
+				ret = TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
+			else
+				ret = TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
 			goto err;
 		}
 	}
@@ -2207,9 +2233,13 @@
 
 	if (!ENGINE_ctrl_cmd(conn->engine, "LOAD_CERT_CTRL",
 			     0, &params, NULL, 1)) {
+		unsigned long err = ERR_get_error();
+
 		wpa_printf(MSG_ERROR, "ENGINE: cannot load client cert with id"
 			   " '%s' [%s]", cert_id,
-			   ERR_error_string(ERR_get_error(), NULL));
+			   ERR_error_string(err, NULL));
+		if (tls_is_pin_error(err))
+			return TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN;
 		return TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED;
 	}
 	if (!params.cert) {