Support Gba Api

Added api to support generic authentication architecture.

Bug: 154865133
Test: atest cts/tests/tests/telephony/current/src/android/telephony/gba/cts/
Test: manual by GbaTestApp
Change-Id: I9aea4c8bc2123b6d00c4a8ddf9901c885d2742d2
diff --git a/core/api/current.txt b/core/api/current.txt
index 8b350f5..49d1e75 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -47058,6 +47058,7 @@
     field public static final int APPTYPE_ISIM = 5; // 0x5
     field public static final int APPTYPE_RUIM = 3; // 0x3
     field public static final int APPTYPE_SIM = 1; // 0x1
+    field public static final int APPTYPE_UNKNOWN = 0; // 0x0
     field public static final int APPTYPE_USIM = 2; // 0x2
     field public static final int AUTHTYPE_EAP_AKA = 129; // 0x81
     field public static final int AUTHTYPE_EAP_SIM = 128; // 0x80
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c3bf058..a1d3594 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -36,6 +36,7 @@
     field public static final String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
     field public static final String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
     field public static final String BIND_EXTERNAL_STORAGE_SERVICE = "android.permission.BIND_EXTERNAL_STORAGE_SERVICE";
+    field public static final String BIND_GBA_SERVICE = "android.permission.BIND_GBA_SERVICE";
     field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
     field public static final String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
     field public static final String BIND_MUSIC_RECOGNITION_SERVICE = "android.permission.BIND_MUSIC_RECOGNITION_SERVICE";
@@ -10870,6 +10871,7 @@
   }
 
   public class TelephonyManager {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void bootstrapAuthenticationRequest(int, @NonNull android.net.Uri, @NonNull android.telephony.gba.UaSecurityProtocolIdentifier, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.BootstrapAuthenticationCallback);
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
     method public int checkCarrierPrivilegesForPackage(String);
@@ -11040,6 +11042,12 @@
     field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final int GBA_FAILURE_REASON_FEATURE_NOT_READY = 2; // 0x2
+    field public static final int GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED = 1; // 0x1
+    field public static final int GBA_FAILURE_REASON_INCORRECT_NAF_ID = 4; // 0x4
+    field public static final int GBA_FAILURE_REASON_NETWORK_FAILURE = 3; // 0x3
+    field public static final int GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED = 5; // 0x5
+    field public static final int GBA_FAILURE_REASON_UNKNOWN = 0; // 0x0
     field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
     field public static final int KEY_TYPE_EPDG = 1; // 0x1
     field public static final int KEY_TYPE_WLAN = 2; // 0x2
@@ -11093,6 +11101,12 @@
     field public static final int THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR = 4; // 0x4
   }
 
+  public static class TelephonyManager.BootstrapAuthenticationCallback {
+    ctor public TelephonyManager.BootstrapAuthenticationCallback();
+    method public void onAuthenticationFailure(int);
+    method public void onKeysAvailable(@NonNull byte[], @NonNull String);
+  }
+
   public static interface TelephonyManager.CallForwardingInfoCallback {
     method public void onCallForwardingInfoAvailable(@NonNull android.telephony.CallForwardingInfo);
     method public void onError(int);
@@ -11535,6 +11549,141 @@
 
 }
 
+package android.telephony.gba {
+
+  public class GbaService extends android.app.Service {
+    ctor public GbaService();
+    method public void onAuthenticationRequest(int, int, int, @NonNull android.net.Uri, @NonNull byte[], boolean);
+    method public final void reportAuthenticationFailure(int, int) throws java.lang.RuntimeException;
+    method public final void reportKeysAvailable(int, @NonNull byte[], @NonNull String) throws java.lang.RuntimeException;
+    field public static final String SERVICE_INTERFACE = "android.telephony.gba.GbaService";
+  }
+
+  public class TlsParams {
+    method public static boolean isTlsCipherSuiteSupported(int);
+    field public static final int GROUP_SECP256R1 = 23; // 0x17
+    field public static final int GROUP_SECP384R1 = 24; // 0x18
+    field public static final int GROUP_X25519 = 29; // 0x1d
+    field public static final int GROUP_X448 = 30; // 0x1e
+    field public static final int PROTOCOL_VERSION_TLS_1_2 = 771; // 0x303
+    field public static final int PROTOCOL_VERSION_TLS_1_3 = 772; // 0x304
+    field public static final int SIG_ECDSA_BRAINPOOLP256R1TLS13_SHA256 = 2074; // 0x81a
+    field public static final int SIG_ECDSA_BRAINPOOLP384R1TLS13_SHA384 = 2075; // 0x81b
+    field public static final int SIG_ECDSA_BRAINPOOLP512R1TLS13_SHA512 = 2076; // 0x81c
+    field public static final int SIG_ECDSA_SECP256R1_SHA256 = 1027; // 0x403
+    field public static final int SIG_ECDSA_SECP384R1_SHA384 = 1283; // 0x503
+    field public static final int SIG_ECDSA_SECP521R1_SHA512 = 1539; // 0x603
+    field public static final int SIG_ECDSA_SHA1 = 515; // 0x203
+    field public static final int SIG_RSA_PKCS1_SHA1 = 513; // 0x201
+    field public static final int SIG_RSA_PKCS1_SHA256 = 1025; // 0x401
+    field public static final int SIG_RSA_PKCS1_SHA256_LEGACY = 1056; // 0x420
+    field public static final int SIG_RSA_PKCS1_SHA384 = 1281; // 0x501
+    field public static final int SIG_RSA_PKCS1_SHA384_LEGACY = 1312; // 0x520
+    field public static final int SIG_RSA_PKCS1_SHA512 = 1537; // 0x601
+    field public static final int SIG_RSA_PKCS1_SHA512_LEGACY = 1568; // 0x620
+    field public static final int SIG_RSA_PSS_RSAE_SHA256 = 2052; // 0x804
+    field public static final int SIG_RSA_PSS_RSAE_SHA384 = 2053; // 0x805
+    field public static final int SIG_RSA_PSS_RSAE_SHA512 = 2054; // 0x806
+    field public static final int TLS_AES_128_CCM_SHA256 = 4868; // 0x1304
+    field public static final int TLS_AES_128_GCM_SHA256 = 4865; // 0x1301
+    field public static final int TLS_AES_256_GCM_SHA384 = 4866; // 0x1302
+    field public static final int TLS_CHACHA20_POLY1305_SHA256 = 4867; // 0x1303
+    field public static final int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 19; // 0x13
+    field public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 50; // 0x32
+    field public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 64; // 0x40
+    field public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 56; // 0x38
+    field public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 106; // 0x6a
+    field public static final int TLS_DHE_PSK_WITH_AES_128_CCM = 49318; // 0xc0a6
+    field public static final int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 170; // 0xaa
+    field public static final int TLS_DHE_PSK_WITH_AES_256_CCM = 49319; // 0xc0a7
+    field public static final int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 171; // 0xab
+    field public static final int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 52397; // 0xccad
+    field public static final int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 22; // 0x16
+    field public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 51; // 0x33
+    field public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 103; // 0x67
+    field public static final int TLS_DHE_RSA_WITH_AES_128_CCM = 49310; // 0xc09e
+    field public static final int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 158; // 0x9e
+    field public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 57; // 0x39
+    field public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 107; // 0x6b
+    field public static final int TLS_DHE_RSA_WITH_AES_256_CCM = 49311; // 0xc09f
+    field public static final int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 159; // 0x9f
+    field public static final int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 52394; // 0xccaa
+    field public static final int TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 27; // 0x1b
+    field public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA = 52; // 0x34
+    field public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 108; // 0x6c
+    field public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA = 58; // 0x3a
+    field public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 109; // 0x6d
+    field public static final int TLS_DH_ANON_WITH_RC4_128_MD5 = 24; // 0x18
+    field public static final int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 13; // 0xd
+    field public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 48; // 0x30
+    field public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 62; // 0x3e
+    field public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 54; // 0x36
+    field public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 104; // 0x68
+    field public static final int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 16; // 0x10
+    field public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 49; // 0x31
+    field public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 63; // 0x3f
+    field public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 55; // 0x37
+    field public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 105; // 0x69
+    field public static final int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 49195; // 0xc02b
+    field public static final int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 49196; // 0xc02c
+    field public static final int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 52393; // 0xcca9
+    field public static final int TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 53253; // 0xd005
+    field public static final int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 53249; // 0xd001
+    field public static final int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 53250; // 0xd002
+    field public static final int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 52396; // 0xccac
+    field public static final int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 49199; // 0xc02f
+    field public static final int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 49200; // 0xc030
+    field public static final int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 52392; // 0xcca8
+    field public static final int TLS_NULL_WITH_NULL_NULL = 0; // 0x0
+    field public static final int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 10; // 0xa
+    field public static final int TLS_RSA_WITH_AES_128_CBC_SHA = 47; // 0x2f
+    field public static final int TLS_RSA_WITH_AES_128_CBC_SHA256 = 60; // 0x3c
+    field public static final int TLS_RSA_WITH_AES_256_CBC_SHA = 53; // 0x35
+    field public static final int TLS_RSA_WITH_AES_256_CBC_SHA256 = 61; // 0x3d
+    field public static final int TLS_RSA_WITH_NULL_MD5 = 1; // 0x1
+    field public static final int TLS_RSA_WITH_NULL_SHA = 2; // 0x2
+    field public static final int TLS_RSA_WITH_NULL_SHA256 = 59; // 0x3b
+    field public static final int TLS_RSA_WITH_RC4_128_MD5 = 4; // 0x4
+    field public static final int TLS_RSA_WITH_RC4_128_SHA = 5; // 0x5
+  }
+
+  public final class UaSecurityProtocolIdentifier implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getOrg();
+    method public int getProtocol();
+    method public int getTlsCipherSuite();
+    method @NonNull public byte[] toByteArray();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.gba.UaSecurityProtocolIdentifier> CREATOR;
+    field public static final int ORG_3GPP = 1; // 0x1
+    field public static final int ORG_3GPP2 = 2; // 0x2
+    field public static final int ORG_GSMA = 4; // 0x4
+    field public static final int ORG_LOCAL = 255; // 0xff
+    field public static final int ORG_NONE = 0; // 0x0
+    field public static final int ORG_OMA = 3; // 0x3
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI = 256; // 0x100
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER = 5; // 0x5
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS = 3; // 0x3
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION = 2; // 0x2
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE = 6; // 0x6
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_MBMS = 1; // 0x1
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS = 4; // 0x4
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE = 0; // 0x0
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER = 131072; // 0x20000
+    field public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT = 65536; // 0x10000
+  }
+
+  public static final class UaSecurityProtocolIdentifier.Builder {
+    ctor public UaSecurityProtocolIdentifier.Builder();
+    ctor public UaSecurityProtocolIdentifier.Builder(@NonNull android.telephony.gba.UaSecurityProtocolIdentifier);
+    method @NonNull public android.telephony.gba.UaSecurityProtocolIdentifier build();
+    method @NonNull public android.telephony.gba.UaSecurityProtocolIdentifier.Builder setOrg(int);
+    method @NonNull public android.telephony.gba.UaSecurityProtocolIdentifier.Builder setProtocol(int);
+    method @NonNull public android.telephony.gba.UaSecurityProtocolIdentifier.Builder setTlsCipherSuite(int);
+  }
+
+}
+
 package android.telephony.ims {
 
   public final class AudioCodecAttributes implements android.os.Parcelable {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1250eb7..618eff0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2379,6 +2379,15 @@
     <permission android:name="android.permission.READ_CARRIER_APP_INFO"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an GbaService to ensure that only the
+         system can bind to it.
+         <p>Protection level: signature
+         @SystemApi
+         @hide
+    -->
+    <permission android:name="android.permission.BIND_GBA_SERVICE"
+        android:protectionLevel="signature" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index f900c38..99f2e5e 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -624,6 +624,20 @@
     public @interface UiccAppType{}
 
     /**
+     * UICC SIM Application Types including UNKNOWN
+     */
+    @IntDef(prefix = { "APPTYPE_" }, value = {
+            TelephonyManager.APPTYPE_UNKNOWN,
+            TelephonyManager.APPTYPE_SIM,
+            TelephonyManager.APPTYPE_USIM,
+            TelephonyManager.APPTYPE_RUIM,
+            TelephonyManager.APPTYPE_CSIM,
+            TelephonyManager.APPTYPE_ISIM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UiccAppTypeExt{}
+
+    /**
      * Override network type
      */
     @Retention(RetentionPolicy.SOURCE)
diff --git a/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl b/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl
new file mode 100644
index 0000000..d39ad0e
--- /dev/null
+++ b/telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+/**
+ * Callback to handle the response of bootstrapAuthenticationRequest
+ * @hide
+ */
+oneway interface IBootstrapAuthenticationCallback
+{
+    void onKeysAvailable(int token, in byte[] gbaKey, String btId);
+    void onAuthenticationFailure(int token, int reason);
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 239329c..8c655ad 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -80,12 +80,14 @@
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.ThermalMitigationResult;
 import android.telephony.Annotation.UiccAppType;
+import android.telephony.Annotation.UiccAppTypeExt;
 import android.telephony.CallForwardingInfo.CallForwardingReason;
 import android.telephony.VisualVoicemailService.VisualVoicemailTask;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.MvnoType;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsRegistration;
@@ -7204,6 +7206,8 @@
         }
     }
 
+    /** UICC application type is unknown or not specified */
+    public static final int APPTYPE_UNKNOWN = PhoneConstants.APPTYPE_UNKNOWN;
     /** UICC application type is SIM */
     public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM;
     /** UICC application type is USIM */
@@ -14415,4 +14419,173 @@
             throw new IllegalStateException("telephony service is null.");
         }
     }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"GBA_FAILURE_REASON_"}, value = {
+            GBA_FAILURE_REASON_UNKNOWN,
+            GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED,
+            GBA_FAILURE_REASON_FEATURE_NOT_READY,
+            GBA_FAILURE_REASON_NETWORK_FAILURE,
+            GBA_FAILURE_REASON_INCORRECT_NAF_ID,
+            GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED})
+    public @interface AuthenticationFailureReason {}
+
+    /**
+     * GBA Authentication has failed for an unknown reason.
+     *
+     * <p>The caller should retry a message that failed with this response.
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_UNKNOWN = 0;
+
+    /**
+     * GBA Authentication is not supported by the carrier, SIM or android.
+     *
+     * <p>Application should use other authentication mechanisms if possible.
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED = 1;
+
+    /**
+     * GBA Authentication service is not ready for use.
+     *
+     * <p>Application could try again at a later time.
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_FEATURE_NOT_READY = 2;
+
+    /**
+     * GBA Authentication has been failed by the network.
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_NETWORK_FAILURE = 3;
+
+    /**
+     * GBA Authentication has failed due to incorrect NAF URL.
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_INCORRECT_NAF_ID = 4;
+
+    /**
+     * GBA Authentication has failed due to unsupported security protocol
+     * @hide
+     */
+    @SystemApi
+    public static final int GBA_FAILURE_REASON_SECURITY_PROTOCOL_NOT_SUPPORTED = 5;
+
+    /**
+     * The callback associated with a {@link #bootstrapAuthenticationRequest()}.
+     * @hide
+     */
+    @SystemApi
+    public static class BootstrapAuthenticationCallback {
+
+        /**
+         * Invoked when the previously requested GBA keys are available (@see
+         * bootstrapAuthenticationRequest()).
+         * @param gbaKey Ks_NAF/Ks_ext_NAF Response
+         * @param transactionId Bootstrapping Transaction Identifier
+         */
+        public void onKeysAvailable(@NonNull byte[] gbaKey, @NonNull String transactionId) {}
+
+        /**
+         * @param reason The reason for the authentication failure.
+         */
+        public void onAuthenticationFailure(@AuthenticationFailureReason int reason) {}
+    }
+
+    /**
+     * Used to get the Generic Bootstrapping Architecture authentication keys
+     * KsNAF/Ks_ext_NAF for a particular NAF as defined in 3GPP spec TS 33.220 for
+     * the specified sub id.
+     *
+     * <p>Application must be prepared to wait for receiving the Gba keys through the
+     * registered callback and not invoke the API on the main application thread.
+     * Application also must call the api to get the fresh key every time instead
+     * of caching the key.
+     *
+     * Following steps may be invoked on the API call depending on the state of the
+     * underlying GBA implementation:
+     * <ol>
+     *     <li>Resolve and bind to a Gba implementation.</li>
+     *     <li>Run bootstrapping if no valid keys are available or bootstrapping is forced.</li>
+     *     <li>Generate the ks_NAF/ ks_Ext_NAF to be returned via the callback.</li>
+     * </ol>
+     *
+     * <p> Requires Permission: MODIFY_PHONE_STATE or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}).
+     * @param appType icc application type, like {@link #APPTYPE_USIM} or {@link
+     * #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN}
+     * @param nafId Network Application Function(NAF) fully qualified domain name and
+     * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first
+     * part is the constant string "3GPP-bootstrapping" (GBA_ME),
+     * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest),
+     * and the latter part shall be the FQDN of the NAF (e.g.
+     * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com",
+     * or "3GPP-bootstrapping-digest@naf1.operator.com").
+     * @param securityProtocol Security protocol identifier between UE and NAF.  See
+     * 3GPP TS 33.220 Annex H. Application can use
+     * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId},
+     * {@link UaSecurityProtocolIdentifier#create3GppUaSpId},
+     * to create the ua security protocol identifier as needed
+     * @param forceBootStrapping true=force bootstrapping, false=do not force
+     * bootstrapping. Bootstrapping shouldn't be forced unless the application sees
+     * authentication errors from the server.
+     * @param e The {@link Executor} that will be used to call the Gba callback.
+     * @param callback A callback called on the supplied {@link Executor} that will
+     * contain the GBA Ks_NAF/Ks_ext_NAF when available. If the NAF keys are
+     * available and valid at the time of call and bootstrapping is not requested,
+     * then the callback shall be invoked with the available keys.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void bootstrapAuthenticationRequest(
+            @UiccAppTypeExt int appType, @NonNull Uri nafId,
+            @NonNull UaSecurityProtocolIdentifier securityProtocol,
+            boolean forceBootStrapping, @NonNull Executor e,
+            @NonNull BootstrapAuthenticationCallback callback) {
+        try {
+            ITelephony service = getITelephony();
+            if (service == null) {
+                e.execute(() -> callback.onAuthenticationFailure(
+                        GBA_FAILURE_REASON_FEATURE_NOT_READY));
+                return;
+            }
+            service.bootstrapAuthenticationRequest(
+                    getSubId(), appType, nafId, securityProtocol, forceBootStrapping,
+                    new IBootstrapAuthenticationCallback.Stub() {
+                        @Override
+                        public void onKeysAvailable(int token, byte[] gbaKey,
+                                String transactionId) {
+                            final long identity = Binder.clearCallingIdentity();
+                            try {
+                                e.execute(() -> callback.onKeysAvailable(gbaKey, transactionId));
+                            } finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                        }
+
+                        @Override
+                        public void onAuthenticationFailure(int token, int reason) {
+                            final long identity = Binder.clearCallingIdentity();
+                            try {
+                                e.execute(() -> callback.onAuthenticationFailure(reason));
+                            } finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                        }
+                    });
+        } catch (RemoteException exception) {
+            Log.e(TAG, "Error calling ITelephony#bootstrapAuthenticationRequest", exception);
+            e.execute(() -> callback.onAuthenticationFailure(GBA_FAILURE_REASON_FEATURE_NOT_READY));
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/gba/GbaAuthRequest.aidl b/telephony/java/android/telephony/gba/GbaAuthRequest.aidl
new file mode 100644
index 0000000..ba243a2
--- /dev/null
+++ b/telephony/java/android/telephony/gba/GbaAuthRequest.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.gba;
+
+parcelable GbaAuthRequest;
diff --git a/telephony/java/android/telephony/gba/GbaAuthRequest.java b/telephony/java/android/telephony/gba/GbaAuthRequest.java
new file mode 100644
index 0000000..5366e9a
--- /dev/null
+++ b/telephony/java/android/telephony/gba/GbaAuthRequest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.gba;
+
+import android.annotation.NonNull;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.IBootstrapAuthenticationCallback;
+
+import com.android.internal.telephony.uicc.IccUtils;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * GBA authentication request
+ * {@hide}
+ */
+public final class GbaAuthRequest implements Parcelable {
+    private int mToken;
+    private int mSubId;
+    private int mAppType;
+    private Uri mNafUrl;
+    private byte[] mSecurityProtocol;
+    private boolean mForceBootStrapping;
+    private IBootstrapAuthenticationCallback mCallback;
+
+    private static AtomicInteger sUniqueToken = new AtomicInteger(0);
+
+    public GbaAuthRequest(int subId, int appType, Uri nafUrl, byte[] securityProtocol,
+            boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
+        this(nextUniqueToken(), subId, appType, nafUrl,
+                securityProtocol, forceBootStrapping, callback);
+    }
+
+    public GbaAuthRequest(GbaAuthRequest request) {
+        this(request.mToken, request.mSubId, request.mAppType, request.mNafUrl,
+                request.mSecurityProtocol, request.mForceBootStrapping, request.mCallback);
+    }
+
+    public GbaAuthRequest(int token, int subId, int appType, Uri nafUrl, byte[] securityProtocol,
+            boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
+        mToken = token;
+        mSubId = subId;
+        mAppType = appType;
+        mNafUrl = nafUrl;
+        mSecurityProtocol = securityProtocol;
+        mCallback = callback;
+        mForceBootStrapping = forceBootStrapping;
+    }
+
+    public int getToken() {
+        return mToken;
+    }
+
+    public int getSubId() {
+        return mSubId;
+    }
+
+    public int getAppType() {
+        return mAppType;
+    }
+
+    public Uri getNafUrl() {
+        return mNafUrl;
+    }
+
+    public byte[] getSecurityProtocol() {
+        return mSecurityProtocol;
+    }
+
+    public boolean isForceBootStrapping() {
+        return mForceBootStrapping;
+    }
+
+    public void setCallback(IBootstrapAuthenticationCallback cb) {
+        mCallback = cb;
+    }
+
+    public IBootstrapAuthenticationCallback getCallback() {
+        return mCallback;
+    }
+
+    /**
+     * {@link Parcelable#writeToParcel}
+     */
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mToken);
+        out.writeInt(mSubId);
+        out.writeInt(mAppType);
+        out.writeParcelable(mNafUrl, 0);
+        out.writeInt(mSecurityProtocol.length);
+        out.writeByteArray(mSecurityProtocol);
+        out.writeBoolean(mForceBootStrapping);
+        out.writeStrongInterface(mCallback);
+    }
+
+    /**
+     * {@link Parcelable.Creator}
+     *
+     */
+    public static final @android.annotation.NonNull Parcelable.Creator<
+            GbaAuthRequest> CREATOR = new Creator<GbaAuthRequest>() {
+                @Override
+                public GbaAuthRequest createFromParcel(Parcel in) {
+                    int token = in.readInt();
+                    int subId = in.readInt();
+                    int appType = in.readInt();
+                    Uri nafUrl = in.readParcelable(GbaAuthRequest.class.getClassLoader());
+                    int len = in.readInt();
+                    byte[] protocol = new byte[len];
+                    in.readByteArray(protocol);
+                    boolean forceBootStrapping = in.readBoolean();
+                    IBootstrapAuthenticationCallback callback =
+                            IBootstrapAuthenticationCallback.Stub
+                            .asInterface(in.readStrongBinder());
+                    return new GbaAuthRequest(token, subId, appType, nafUrl, protocol,
+                            forceBootStrapping, callback);
+                }
+
+                @Override
+                public GbaAuthRequest[] newArray(int size) {
+                    return new GbaAuthRequest[size];
+                }
+            };
+
+    /**
+     * {@link Parcelable#describeContents}
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    private static int nextUniqueToken() {
+        return sUniqueToken.getAndIncrement() << 16 | (0xFFFF & (int) System.currentTimeMillis());
+    }
+
+    @Override
+    public String toString() {
+        String str = "Token: " +  mToken + "SubId:" + mSubId + ", AppType:"
+                + mAppType + ", NafUrl:" + mNafUrl + ", SecurityProtocol:"
+                + IccUtils.bytesToHexString(mSecurityProtocol)
+                + ", ForceBootStrapping:" + mForceBootStrapping
+                + ", CallBack:" + mCallback;
+        return str;
+    }
+}
diff --git a/telephony/java/android/telephony/gba/GbaService.java b/telephony/java/android/telephony/gba/GbaService.java
new file mode 100644
index 0000000..3962aff
--- /dev/null
+++ b/telephony/java/android/telephony/gba/GbaService.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.gba;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telephony.Annotation.UiccAppTypeExt;
+import android.telephony.IBootstrapAuthenticationCallback;
+import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.AuthenticationFailureReason;
+import android.util.Log;
+import android.util.SparseArray;
+
+/**
+  * Base class for GBA Service. Any implementation which wants to provide
+  * GBA service must extend this class.
+  *
+  * <p>Note that the application to implement the service must declare to use
+  * the permission {@link android.Manifest.permission#BIND_GBA_SERVICE},
+  * and filter the intent of {@link #SERVICE_INTERFACE}.
+  * The manifest of the service must follow the format below:
+  *
+  * <p>...
+  * <service
+  *     android:name=".EgGbaService"
+  *     android:directBootAware="true"
+  *     android:permission="android.permission.BIND_GBA_SERVICE" >
+  *     ...
+  *     <intent-filter>
+  *         <action android:name="android.telephony.gba.GbaService"/>
+  *     </intent-filter>
+  * </service>
+  * ...
+  *
+  * <p>The service should also be file-based encryption (FBE) aware.
+  * {@hide}
+  */
+@SystemApi
+public class GbaService extends Service  {
+    private static final boolean DBG = Build.IS_DEBUGGABLE;
+    private static final String TAG = "GbaService";
+
+    /**
+    * The intent must be defined as an intent-filter in the
+    * AndroidManifest of the GbaService.
+    */
+    public static final String SERVICE_INTERFACE = "android.telephony.gba.GbaService";
+
+    private static final int EVENT_GBA_AUTH_REQUEST = 1;
+
+    private final HandlerThread mHandlerThread;
+    private final GbaServiceHandler mHandler;
+
+    private final SparseArray<IBootstrapAuthenticationCallback> mCallbacks = new SparseArray<>();
+    private final IGbaServiceWrapper mBinder = new IGbaServiceWrapper();
+
+    /**
+     * Default constructor.
+     */
+    public GbaService() {
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+
+        mHandler = new GbaServiceHandler(mHandlerThread.getLooper());
+        Log.d(TAG, "GBA service created");
+    }
+
+    private class GbaServiceHandler extends Handler {
+
+        GbaServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_GBA_AUTH_REQUEST:
+                    GbaAuthRequest req = (GbaAuthRequest) msg.obj;
+                    synchronized (mCallbacks) {
+                        mCallbacks.put(req.getToken(), req.getCallback());
+                    }
+                    onAuthenticationRequest(req.getSubId(), req.getToken(), req.getAppType(),
+                            req.getNafUrl(), req.getSecurityProtocol(), req.isForceBootStrapping());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Called by the platform when a GBA authentication request is received from
+     * {@link TelephonyManager#bootstrapAuthenticationRequest} to get the KsNAF for
+     * a particular NAF.
+     *
+     * @param subscriptionId the ICC card to be used for the bootstrapping authentication.
+     * @param token the identification of the authentication request.
+     * @param appType icc application type, like {@link #APPTYPE_USIM} or {@link
+     * #APPTYPE_ISIM} or {@link#APPTYPE_UNKNOWN}
+     * @param nafUrl Network Application Function(NAF) fully qualified domain name and
+     * the selected GBA mode. It shall contain two parts delimited by "@" sign. The first
+     * part is the constant string "3GPP-bootstrapping" (GBA_ME),
+     * "3GPP-bootstrapping-uicc" (GBA_ U), or "3GPP-bootstrapping-digest" (GBA_Digest),
+     * and the latter part shall be the FQDN of the NAF (e.g.
+     * "3GPP-bootstrapping@naf1.operator.com" or "3GPP-bootstrapping-uicc@naf1.operator.com",
+     * or "3GPP-bootstrapping-digest@naf1.operator.com").
+     * @param securityProtocol Security protocol identifier between UE and NAF.  See
+     * 3GPP TS 33.220 Annex H. Application can use
+     * {@link UaSecurityProtocolIdentifier#createDefaultUaSpId},
+     * {@link UaSecurityProtocolIdentifier#create3GppUaSpId},
+     * to create the ua security protocol identifier as needed
+     * @param forceBootStrapping true=force bootstrapping, false=do not force
+     * bootstrapping. Bootstrapping shouldn't be forced unless the application sees
+     * authentication errors from the server.
+     * Response is returned via {@link TelephonyManager#BootstrapAuthenticationCallback}
+     * along with the token to identify the request.
+     *
+     * <p>Note that this is not called in the main thread.
+     */
+    public void onAuthenticationRequest(int subscriptionId, int token, @UiccAppTypeExt int appType,
+            @NonNull Uri nafUrl, @NonNull byte[] securityProtocol, boolean forceBootStrapping) {
+        //Default implementation should be overridden by vendor Gba Service. Vendor Gba Service
+        //should handle the gba bootstrap authentication request, and call reportKeysAvailable or
+        //reportAuthenticationFailure to notify the caller accordingly.
+        reportAuthenticationFailure(
+                token, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
+    }
+
+    /**
+     * Called by {@link GbaService} when the previously requested GBA keys are available
+     * (@see onAuthenticationRequest())
+     *
+     * @param token unique identifier of the request.
+     * @param gbaKey KsNaf Response.
+     * @param transactionId Bootstrapping Transaction ID.
+     * @throws RuntimeException when there is remote failure of callback.
+     */
+    public final void reportKeysAvailable(int token, @NonNull byte[] gbaKey,
+            @NonNull String transactionId) throws RuntimeException {
+        IBootstrapAuthenticationCallback cb = null;
+        synchronized (mCallbacks) {
+            cb = mCallbacks.get(token);
+            mCallbacks.remove(token);
+        }
+        if (cb != null) {
+            try {
+                cb.onKeysAvailable(token, gbaKey, transactionId);
+            } catch (RemoteException exception) {
+                throw exception.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Invoked when the previously requested GBA key authentication failed
+     * (@see onAuthenticationRequest())
+     *
+     * @param token unique identifier of the request.
+     * @param reason The reason for the authentication failure.
+     * @throws RuntimeException when there is remote failure of callback.
+     */
+    public final void reportAuthenticationFailure(int token,
+            @AuthenticationFailureReason int reason) throws RuntimeException {
+        IBootstrapAuthenticationCallback cb = null;
+        synchronized (mCallbacks) {
+            cb = mCallbacks.get(token);
+            mCallbacks.remove(token);
+        }
+        if (cb != null) {
+            try {
+                cb.onAuthenticationFailure(token, reason);
+            } catch (RemoteException exception) {
+                throw exception.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            Log.d(TAG, "GbaService Bound.");
+            return mBinder;
+        }
+        return null;
+    }
+
+    /** @hide */
+    @Override
+    public void onDestroy() {
+        mHandlerThread.quit();
+        super.onDestroy();
+    }
+
+    private class IGbaServiceWrapper extends IGbaService.Stub {
+        @Override
+        public void authenticationRequest(GbaAuthRequest request) {
+            if (DBG) Log.d(TAG, "receive request: " + request);
+            mHandler.obtainMessage(EVENT_GBA_AUTH_REQUEST, request).sendToTarget();
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/gba/IGbaService.aidl b/telephony/java/android/telephony/gba/IGbaService.aidl
new file mode 100644
index 0000000..b7ba5a4
--- /dev/null
+++ b/telephony/java/android/telephony/gba/IGbaService.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.gba;
+
+import android.net.Uri;
+import android.telephony.gba.GbaAuthRequest;
+
+/**
+ * @hide
+ */
+interface IGbaService
+{
+    oneway void authenticationRequest(in GbaAuthRequest request);
+}
diff --git a/telephony/java/android/telephony/gba/TlsParams.java b/telephony/java/android/telephony/gba/TlsParams.java
new file mode 100644
index 0000000..922f4bb
--- /dev/null
+++ b/telephony/java/android/telephony/gba/TlsParams.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.gba;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
+/**
+ * Defines the TLS parameters for GBA as per IANA and TS 33.210, which are used
+ * by some UA security protocol identifiers defined in 3GPP TS 33.220 Annex H,
+ * and 3GPP TS 33.222.
+ *
+ * @hide
+ */
+@SystemApi
+public class TlsParams {
+
+    private TlsParams() {}
+
+    /**
+     * TLS protocol version supported by GBA
+     */
+    public static final int PROTOCOL_VERSION_TLS_1_2 = 0x0303;
+    public static final int PROTOCOL_VERSION_TLS_1_3 = 0x0304;
+
+    /**
+     * TLS cipher suites are used to create {@link UaSecurityProtocolIdentifier}
+     * by {@link UaSecurityProtocolIdentifier#create3GppUaSpId}
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+        prefix = {"TLS_"},
+        value = {
+            TLS_NULL_WITH_NULL_NULL,
+            TLS_RSA_WITH_NULL_MD5,
+            TLS_RSA_WITH_NULL_SHA,
+            TLS_RSA_WITH_RC4_128_MD5,
+            TLS_RSA_WITH_RC4_128_SHA,
+            TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+            TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
+            TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+            TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+            TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+            TLS_DH_ANON_WITH_RC4_128_MD5,
+            TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA,
+            TLS_RSA_WITH_AES_128_CBC_SHA,
+            TLS_DH_DSS_WITH_AES_128_CBC_SHA,
+            TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+            TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+            TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+            TLS_DH_ANON_WITH_AES_128_CBC_SHA,
+            TLS_RSA_WITH_AES_256_CBC_SHA,
+            TLS_DH_DSS_WITH_AES_256_CBC_SHA,
+            TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+            TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+            TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+            TLS_DH_ANON_WITH_AES_256_CBC_SHA,
+            TLS_RSA_WITH_NULL_SHA256,
+            TLS_RSA_WITH_AES_128_CBC_SHA256,
+            TLS_RSA_WITH_AES_256_CBC_SHA256,
+            TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
+            TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
+            TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+            TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+            TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
+            TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
+            TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+            TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+            TLS_DH_ANON_WITH_AES_128_CBC_SHA256,
+            TLS_DH_ANON_WITH_AES_256_CBC_SHA256,
+            TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+            TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+            TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+            TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+            TLS_AES_128_GCM_SHA256,
+            TLS_AES_256_GCM_SHA384,
+            TLS_CHACHA20_POLY1305_SHA256,
+            TLS_AES_128_CCM_SHA256,
+            TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+            TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+            TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+            TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+            TLS_DHE_RSA_WITH_AES_128_CCM,
+            TLS_DHE_RSA_WITH_AES_256_CCM,
+            TLS_DHE_PSK_WITH_AES_128_CCM,
+            TLS_DHE_PSK_WITH_AES_256_CCM,
+            TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+            TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+            TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+            TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+            TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+            TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
+            TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
+            TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256
+        })
+    public @interface TlsCipherSuite {}
+
+    // Cipher suites for TLS v1.2 per RFC5246
+    public static final int TLS_NULL_WITH_NULL_NULL = 0x0000;
+    public static final int TLS_RSA_WITH_NULL_MD5 = 0x0001;
+    public static final int TLS_RSA_WITH_NULL_SHA = 0x0002;
+    public static final int TLS_RSA_WITH_RC4_128_MD5 = 0x0004;
+    public static final int TLS_RSA_WITH_RC4_128_SHA = 0x0005;
+    public static final int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
+    public static final int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D;
+    public static final int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010;
+    public static final int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013;
+    public static final int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016;
+    public static final int TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018;
+    public static final int TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B;
+    public static final int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F;
+    public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030;
+    public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031;
+    public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032;
+    public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033;
+    public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034;
+    public static final int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035;
+    public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036;
+    public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037;
+    public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038;
+    public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039;
+    public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A;
+    public static final int TLS_RSA_WITH_NULL_SHA256 = 0x003B;
+    public static final int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C;
+    public static final int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D;
+    public static final int TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E;
+    public static final int TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F;
+    public static final int TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040;
+    public static final int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067;
+    public static final int TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068;
+    public static final int TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069;
+    public static final int TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A;
+    public static final int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B;
+    public static final int TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C;
+    public static final int TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D;
+
+    // Cipher suites for TLS v1.3 per RFC8446 and recommended by IANA
+    public static final int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E;
+    public static final int TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F;
+    public static final int TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA;
+    public static final int TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB;
+    public static final int TLS_AES_128_GCM_SHA256 = 0x1301;
+    public static final int TLS_AES_256_GCM_SHA384 = 0x1302;
+    public static final int TLS_CHACHA20_POLY1305_SHA256 = 0x1303;
+    public static final int TLS_AES_128_CCM_SHA256 = 0x1304;
+    public static final int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B;
+    public static final int TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C;
+    public static final int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F;
+    public static final int TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030;
+    public static final int TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E;
+    public static final int TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F;
+    public static final int TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6;
+    public static final int TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7;
+    public static final int TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
+    public static final int TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
+    public static final int TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA;
+    public static final int TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
+    public static final int TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD;
+    public static final int TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 = 0xD001;
+    public static final int TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 = 0xD002;
+    public static final int TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 = 0xD005;
+
+    private static final int[] CS_EXPECTED = {
+        TLS_NULL_WITH_NULL_NULL,
+        TLS_RSA_WITH_NULL_MD5,
+        TLS_RSA_WITH_NULL_SHA,
+        TLS_RSA_WITH_RC4_128_MD5,
+        TLS_RSA_WITH_RC4_128_SHA,
+        TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+        TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
+        TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+        TLS_DH_ANON_WITH_RC4_128_MD5,
+        TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA,
+        TLS_RSA_WITH_AES_128_CBC_SHA,
+        TLS_DH_DSS_WITH_AES_128_CBC_SHA,
+        TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+        TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+        TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+        TLS_DH_ANON_WITH_AES_128_CBC_SHA,
+        TLS_RSA_WITH_AES_256_CBC_SHA,
+        TLS_DH_DSS_WITH_AES_256_CBC_SHA,
+        TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+        TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+        TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+        TLS_DH_ANON_WITH_AES_256_CBC_SHA,
+        TLS_RSA_WITH_NULL_SHA256,
+        TLS_RSA_WITH_AES_128_CBC_SHA256,
+        TLS_RSA_WITH_AES_256_CBC_SHA256,
+        TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
+        TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
+        TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+        TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+        TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
+        TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
+        TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+        TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+        TLS_DH_ANON_WITH_AES_128_CBC_SHA256,
+        TLS_DH_ANON_WITH_AES_256_CBC_SHA256,
+        TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+        TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+        TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+        TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+        TLS_AES_128_GCM_SHA256,
+        TLS_AES_256_GCM_SHA384,
+        TLS_CHACHA20_POLY1305_SHA256,
+        TLS_AES_128_CCM_SHA256,
+        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+        TLS_DHE_RSA_WITH_AES_128_CCM,
+        TLS_DHE_RSA_WITH_AES_256_CCM,
+        TLS_DHE_PSK_WITH_AES_128_CCM,
+        TLS_DHE_PSK_WITH_AES_256_CCM,
+        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+        TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+        TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+        TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+        TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
+        TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384,
+        TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256
+    };
+
+    /**
+     * TLS supported groups required by TS 33.210
+     */
+    public static final int GROUP_SECP256R1 = 23;
+    public static final int GROUP_SECP384R1 = 24;
+    public static final int GROUP_X25519 = 29;
+    public static final int GROUP_X448 = 30;
+
+    /**
+     * Signature algorithms shall be supported as per TS 33.210
+     */
+    public static final int SIG_RSA_PKCS1_SHA1 = 0X0201;
+    public static final int SIG_ECDSA_SHA1 = 0X0203;
+    public static final int SIG_RSA_PKCS1_SHA256 = 0X0401;
+    public static final int SIG_ECDSA_SECP256R1_SHA256 = 0X0403;
+    public static final int SIG_RSA_PKCS1_SHA256_LEGACY = 0X0420;
+    public static final int SIG_RSA_PKCS1_SHA384 = 0X0501;
+    public static final int SIG_ECDSA_SECP384R1_SHA384 = 0X0503;
+    public static final int SIG_RSA_PKCS1_SHA384_LEGACY = 0X0520;
+    public static final int SIG_RSA_PKCS1_SHA512 = 0X0601;
+    public static final int SIG_ECDSA_SECP521R1_SHA512 = 0X0603;
+    public static final int SIG_RSA_PKCS1_SHA512_LEGACY = 0X0620;
+    public static final int SIG_RSA_PSS_RSAE_SHA256 = 0X0804;
+    public static final int SIG_RSA_PSS_RSAE_SHA384 = 0X0805;
+    public static final int SIG_RSA_PSS_RSAE_SHA512 = 0X0806;
+    public static final int SIG_ECDSA_BRAINPOOLP256R1TLS13_SHA256 = 0X081A;
+    public static final int SIG_ECDSA_BRAINPOOLP384R1TLS13_SHA384 = 0X081B;
+    public static final int SIG_ECDSA_BRAINPOOLP512R1TLS13_SHA512 = 0X081C;
+
+    /**
+     * Returns whether the TLS cipher suite id is supported
+     */
+    public static boolean isTlsCipherSuiteSupported(int csId) {
+        return Arrays.binarySearch(CS_EXPECTED, csId) >= 0;
+    }
+}
diff --git a/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl
new file mode 100644
index 0000000..a71e860
--- /dev/null
+++ b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.gba;
+
+parcelable UaSecurityProtocolIdentifier;
diff --git a/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java
new file mode 100644
index 0000000..c141875
--- /dev/null
+++ b/telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.gba;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.gba.TlsParams.TlsCipherSuite;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * Description of ua security protocol identifier defined in 3GPP TS 33.220 H.2
+ * @hide
+ */
+@SystemApi
+public final class UaSecurityProtocolIdentifier implements Parcelable {
+
+    /**
+     * Organization code defined in 3GPP TS 33.220 H.3
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"ORG_"}, value = {
+        ORG_NONE,
+        ORG_3GPP,
+        ORG_3GPP2,
+        ORG_OMA,
+        ORG_GSMA,
+        ORG_LOCAL})
+    public @interface OrganizationCode {}
+
+    /**
+     * Organization octet value for default ua security protocol
+     */
+    public static final int ORG_NONE  = 0;
+    /**
+     * Organization octet value for 3GPP ua security protocol
+     */
+    public static final int ORG_3GPP  = 0x01;
+    /**
+     * Organization octet value for 3GPP2 ua security protocol
+     */
+    public static final int ORG_3GPP2 = 0x02;
+    /**
+     * Organization octet value for OMA ua security protocol
+     */
+    public static final int ORG_OMA   = 0x03;
+    /**
+     * Organization octet value for GSMA ua security protocol
+     */
+    public static final int ORG_GSMA  = 0x04;
+    /**
+     * Internal organization octet value for local/experimental protocols
+     */
+    public static final int ORG_LOCAL = 0xFF;
+
+    /**
+     * 3GPP UA Security Protocol ID defined in 3GPP TS 33.220 H.3
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"UA_SECURITY_PROTOCOL_3GPP_"}, value = {
+        UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE,
+        UA_SECURITY_PROTOCOL_3GPP_MBMS,
+        UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION,
+        UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS,
+        UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS,
+        UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER,
+        UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE,
+        UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI,
+        UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT,
+        UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER})
+    public @interface UaSecurityProtocol3gpp {}
+
+    /**
+     * Security protocol param according to TS 33.221 as described in TS
+     * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x00".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE = 0;
+
+    /**
+     * Security protocol param according to TS 33.246 for Multimedia
+     * broadcast/Multimedia services (MBMS) as described in TS
+     * 33.220 Annex H. Mapped to byte stream "0x01,0x00,0x00,0x00,0x01".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_MBMS = 1;
+
+    /**
+     * Security protocol param based on HTTP digest authentication
+     * according to TS 24.109 as described in TS 33.220 Annex H. Mapped to
+     * byte stream "0x01,0x00,0x00,0x00,0x02".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION = 2;
+
+    /**
+     * Security protocol param used with HTTP-based security procedures for
+     * Multimedia broadcast/Multimedia services (MBMS) user services
+     * according to TS 26.237 as described in TS 33.220 Annex H.
+     * Mapped to byte stream "0x01,0x00,0x00,0x00,0x03".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS = 3;
+
+    /**
+     * Security protocol param used with SIP-based security procedures for
+     * Multimedia broadcast/Multimedia services (MBMS) user services
+     * according to TS 26.237 as described in TS 33.220 Annex H.
+     * Mapped to byte stream "0x01,0x00,0x00,0x00,0x04".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS = 4;
+
+    /**
+     * Security protocol param used with Generic Push Layer according to TS
+     * 33.224  as described in TS 33.220 Annex H. Mapped to byte stream
+     * "0x01,0x00,0x00,0x00,0x05".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER = 5;
+
+    /**
+     * Security protocol param used for IMS UE to KMS http based message
+     * exchanges according to "IMS media plane security", TS 33.328   as
+     * described in TS 33.220 Annex H. Mapped to byte stream
+     * "0x01,0x00,0x00,0x00,0x06".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE = 6;
+
+    /**
+     * Security protocol param used for Generation of Temporary IP
+     * Multimedia Private Identity (TMPI) according to TS 33.220 Annex B.4
+     * Mapped to byte stream "0x01,0x00,0x00,0x01,0x00".
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI = 0x0100;
+
+    /**
+     * Security protocol param used for Shared key-based UE authentication with
+     * certificate-based NAF authentication, according to TS 33.222 section 5.3,
+     * or Shared key-based mutual authentication between UE and NAF, according to
+     * TS 33.222 section 5.4. Mapped to byte stream "0x01,0x00,0x01,yy,zz".
+     * "yy, zz" is the TLS CipherSuite code.
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT = 0x010000;
+
+    /**
+     * Security protocol param used for Shared key-based UE authentication with
+     * certificate-based NAF authentication, according to TS 33.222 Annex D.
+     * Mapped to byte stream "0x01,0x00,0x02,yy,zz".
+     * "yy, zz" is the TLS CipherSuite code.
+     */
+    public static final int UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER = 0x020000;
+
+    private static final int PROTOCOL_SIZE = 5;
+    private static final int[] sUaSp3gppIds = new int[] {
+            UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE,
+            UA_SECURITY_PROTOCOL_3GPP_MBMS,
+            UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION,
+            UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS,
+            UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS,
+            UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER,
+            UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE,
+            UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI,
+            UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT,
+            UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER};
+
+    private int mOrg;
+    private int mProtocol;
+    private int mTlsCipherSuite;
+
+    private UaSecurityProtocolIdentifier() {}
+
+    private UaSecurityProtocolIdentifier(UaSecurityProtocolIdentifier sp) {
+        mOrg = sp.mOrg;
+        mProtocol = sp.mProtocol;
+        mTlsCipherSuite = sp.mTlsCipherSuite;
+    }
+
+    /**
+     * Returns the byte array representing the ua security protocol
+     */
+    @NonNull
+    public byte[] toByteArray() {
+        byte[] data = new byte[PROTOCOL_SIZE];
+        ByteBuffer buf = ByteBuffer.wrap(data);
+        buf.put((byte) mOrg);
+        buf.putInt(mProtocol | mTlsCipherSuite);
+        return data;
+    }
+
+    /**
+     * Returns the organization code
+     */
+    public @OrganizationCode int getOrg() {
+        return mOrg;
+    }
+
+    /**
+     * Returns the security procotol id
+     *
+     * <p>Note that only 3GPP UA Security Protocols are supported for now
+     */
+    public @UaSecurityProtocol3gpp int getProtocol() {
+        return mProtocol;
+    }
+
+    /**
+     * Returns the TLS cipher suite
+     */
+    public @TlsCipherSuite int getTlsCipherSuite() {
+        return mTlsCipherSuite;
+    }
+
+    /**
+     * {@link Parcelable#writeToParcel}
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mOrg);
+        out.writeInt(mProtocol);
+        out.writeInt(mTlsCipherSuite);
+    }
+
+    /**
+     * {@link Parcelable.Creator}
+     *
+     */
+    public static final @NonNull Parcelable.Creator<
+            UaSecurityProtocolIdentifier> CREATOR = new Creator<UaSecurityProtocolIdentifier>() {
+                @Nullable
+                @Override
+                public UaSecurityProtocolIdentifier createFromParcel(Parcel in) {
+                    int org = in.readInt();
+                    int protocol = in.readInt();
+                    int cs = in.readInt();
+                    if (org < 0 || protocol < 0 || cs < 0) {
+                        return null;
+                    }
+                    Builder builder = new Builder();
+                    try {
+                        if (org > 0) {
+                            builder.setOrg(org);
+                        }
+                        if (protocol > 0) {
+                            builder.setProtocol(protocol);
+                        }
+                        if (cs > 0) {
+                            builder.setTlsCipherSuite(cs);
+                        }
+                    } catch (IllegalArgumentException e) {
+                        return null;
+                    }
+                    return builder.build();
+                }
+
+                @NonNull
+                @Override
+                public UaSecurityProtocolIdentifier[] newArray(int size) {
+                    return new UaSecurityProtocolIdentifier[size];
+                }
+            };
+
+    /**
+     * {@link Parcelable#describeContents}
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "UaSecurityProtocolIdentifier[" + mOrg + " , " + (mProtocol | mTlsCipherSuite) + "]";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof UaSecurityProtocolIdentifier)) {
+            return false;
+        }
+
+        UaSecurityProtocolIdentifier other = (UaSecurityProtocolIdentifier) obj;
+
+        return mOrg == other.mOrg && mProtocol == other.mProtocol
+                && mTlsCipherSuite == other.mTlsCipherSuite;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mOrg, mProtocol, mTlsCipherSuite);
+    }
+
+    private boolean isTlsSupported() {
+        //TODO May update to support non 3gpp protocol in the future
+        if (mOrg == ORG_3GPP && (mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT
+                    || mProtocol == UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Builder class for UaSecurityProtocolIdentifier
+     */
+    public static final class Builder {
+        private final UaSecurityProtocolIdentifier mSp;
+
+        /**
+         * Creates a Builder with default UaSecurityProtocolIdentifier, a.k.a 0x00 00 00 00 00
+         */
+        public Builder() {
+            mSp = new UaSecurityProtocolIdentifier();
+        }
+
+        /**
+         * Creates a Builder from a UaSecurityProtocolIdentifier
+         */
+        public Builder(@NonNull final UaSecurityProtocolIdentifier sp) {
+            Objects.requireNonNull(sp);
+            mSp = new UaSecurityProtocolIdentifier(sp);
+        }
+
+        /**
+         * Sets the organization code
+         *
+         * @param orgCode the organization code with the following value
+         * <ol>
+         * <li>{@link #ORG_NONE} </li>
+         * <li>{@link #ORG_3GPP} </li>
+         * <li>{@link #ORG_3GPP2} </li>
+         * <li>{@link #ORG_OMA} </li>
+         * <li>{@link #ORG_GSMA} </li>
+         * <li>{@link #ORG_LOCAL} </li>
+         * </ol>
+         * @throws IllegalArgumentException if it is not one of the value above.
+         *
+         * <p>Note that this method will reset the security protocol and TLS cipher suite
+         * if they have been set.
+         */
+        @NonNull
+        public Builder setOrg(@OrganizationCode int orgCode) {
+            if (orgCode < ORG_NONE || orgCode > ORG_LOCAL) {
+                throw new IllegalArgumentException("illegal organization code");
+            }
+            mSp.mOrg = orgCode;
+            mSp.mProtocol = 0;
+            mSp.mTlsCipherSuite = 0;
+            return this;
+        }
+
+        /**
+         * Sets the UA security protocol for 3GPP
+         *
+         * @param protocol only 3GPP ua security protocol ID is supported for now, which
+         * is one of the following value
+         * <ol>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_MBMS} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_DIGEST_AUTHENTICATION} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_HTTP_BASED_MBMS} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_SIP_BASED_MBMS} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERIC_PUSH_LAYER} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT} </li>
+         * <li>{@link #UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER} </li>
+         * </ol>
+         * @throws IllegalArgumentException if the protocol is not one of the value above.
+         *
+         * <p>Note that this method will reset TLS cipher suite if it has been set.
+         */
+        @NonNull
+        public Builder setProtocol(@UaSecurityProtocol3gpp int protocol) {
+            //TODO May update to support non 3gpp protocol in the future
+            if (protocol < UA_SECURITY_PROTOCOL_3GPP_SUBSCRIBER_CERTIFICATE
+                    || (protocol > UA_SECURITY_PROTOCOL_3GPP_IMS_MEDIA_PLANE
+                    && protocol != UA_SECURITY_PROTOCOL_3GPP_GENERATION_TMPI
+                    && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_DEFAULT
+                    && protocol != UA_SECURITY_PROTOCOL_3GPP_TLS_BROWSER)
+                    || mSp.mOrg != ORG_3GPP) {
+                throw new IllegalArgumentException("illegal protocol code");
+            }
+            mSp.mProtocol = protocol;
+            mSp.mTlsCipherSuite = 0;
+            return this;
+        }
+
+        /**
+         * Sets the UA security protocol for 3GPP
+         *
+         * @param cs TLS cipher suite value defined by {@link TlsParams#TlsCipherSuite}
+         * @throws IllegalArgumentException if it is not a 3GPP ua security protocol,
+         * the protocol does not support TLS, or does not support the cipher suite.
+         */
+        @NonNull
+        public Builder setTlsCipherSuite(@TlsCipherSuite int cs) {
+            if (!mSp.isTlsSupported()) {
+                throw new IllegalArgumentException("The protocol does not support TLS");
+            }
+            if (!TlsParams.isTlsCipherSuiteSupported(cs)) {
+                throw new IllegalArgumentException("TLS cipher suite is not supported");
+            }
+            mSp.mTlsCipherSuite = cs;
+            return this;
+        }
+
+        /**
+         * Builds the instance of UaSecurityProtocolIdentifier
+         *
+         * @return the built instance of UaSecurityProtocolIdentifier
+         */
+        @NonNull
+        public UaSecurityProtocolIdentifier build() {
+            return new UaSecurityProtocolIdentifier(mSp);
+        }
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 5d4fdd0..66311ad 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -37,6 +37,8 @@
 import android.telephony.CellInfo;
 import android.telephony.ClientRequestStats;
 import android.telephony.ThermalMitigationRequest;
+import android.telephony.gba.UaSecurityProtocolIdentifier;
+import android.telephony.IBootstrapAuthenticationCallback;
 import android.telephony.IccOpenLogicalChannelResponse;
 import android.telephony.ICellInfoCallback;
 import android.telephony.ModemActivityInfo;
@@ -2273,4 +2275,31 @@
      */
     int sendThermalMitigationRequest(int subId,
             in ThermalMitigationRequest thermalMitigationRequest);
+
+    /**
+     * get the Generic Bootstrapping Architecture authentication keys
+     */
+    void bootstrapAuthenticationRequest(int subId, int appType, in Uri nafUrl,
+            in UaSecurityProtocolIdentifier securityProtocol,
+            boolean forceBootStrapping, IBootstrapAuthenticationCallback callback);
+
+    /**
+     * Set the GbaService Package Name that Telephony will bind to.
+     */
+    boolean setBoundGbaServiceOverride(int subId, String packageName);
+
+    /**
+     * Return the package name of the currently bound GbaService.
+     */
+    String getBoundGbaService(int subId);
+
+    /**
+     * Set the release time for telephony to unbind GbaService.
+     */
+    boolean setGbaReleaseTimeOverride(int subId, int interval);
+
+    /**
+     * Return the release time for telephony to unbind GbaService.
+     */
+    int getGbaReleaseTime(int subId);
 }