Appropriately fail EAP-SIM/AKA when SIM doesn't generate good response

This change instructs supplicant to terminate the eapol when bad
reponses are obtained from call to getIccSimChallengeResponse; it
ensures that the failed connections terminate early and connection
times are reduced.

Bug: 23703236
Change-Id: I8eb8edde7a8bb310d73d1b3cc8bc060647e2375f
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index d1b009e..7bdd17c 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -876,6 +876,16 @@
         }
     }
 
+    public boolean simAuthFailedResponse(int id) {
+        // should be used with type GSM-AUTH
+        return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-FAIL");
+    }
+
+    public boolean umtsAuthFailedResponse(int id) {
+        // should be used with type UMTS-AUTH
+        return doBooleanCommand("CTRL-RSP-SIM-" + id + ":UMTS-FAIL");
+    }
+
     public boolean simIdentityResponse(int id, String response) {
         synchronized (mLock) {
             return doBooleanCommand("CTRL-RSP-IDENTITY-" + id + ":" + response);
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 29c4492..7773cb9 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -10181,16 +10181,19 @@
                     String kc = makeHex(result, 1+kc_offset, kc_len);
                     sb.append(":" + kc + ":" + sres);
                     logv("kc:" + kc + " sres:" + sres);
+
+                    String response = sb.toString();
+                    logv("Supplicant Response -" + response);
+                    mWifiNative.simAuthResponse(requestData.networkId, "GSM-AUTH", response);
                 } else {
                     loge("bad response - " + tmResponse);
+                    mWifiNative.simAuthFailedResponse(requestData.networkId);
                 }
             }
 
-            String response = sb.toString();
-            logv("Supplicant Response -" + response);
-            mWifiNative.simAuthResponse(requestData.networkId, "GSM-AUTH", response);
         } else {
             loge("could not get telephony manager");
+            mWifiNative.simAuthFailedResponse(requestData.networkId);
         }
     }
 
@@ -10234,6 +10237,7 @@
             }
         }
 
+        boolean good_response = false;
         if (tmResponse != null && tmResponse.length() > 4) {
             byte[] result = android.util.Base64.decode(tmResponse,
                     android.util.Base64.DEFAULT);
@@ -10249,6 +10253,7 @@
                 String ik = makeHex(result, res_len + ck_len + 4, ik_len);
                 sb.append(":" + ik + ":" + ck + ":" + res);
                 logv("ik:" + ik + "ck:" + ck + " res:" + res);
+                good_response = true;
             } else if (tag == (byte) 0xdc) {
                 loge("synchronisation failure");
                 int auts_len = result[1];
@@ -10256,18 +10261,21 @@
                 res_type = "UMTS-AUTS";
                 sb.append(":" + auts);
                 logv("auts:" + auts);
+                good_response = true;
             } else {
                 loge("bad response - unknown tag = " + tag);
-                return;
             }
         } else {
             loge("bad response - " + tmResponse);
-            return;
         }
 
-        String response = sb.toString();
-        logv("Supplicant Response -" + response);
-        mWifiNative.simAuthResponse(requestData.networkId, res_type, response);
+        if (good_response) {
+            String response = sb.toString();
+            if (VDBG) logv("Supplicant Response -" + response);
+            mWifiNative.simAuthResponse(requestData.networkId, res_type, response);
+        } else {
+            mWifiNative.umtsAuthFailedResponse(requestData.networkId);
+        }
     }
 
     /**