summaryrefslogtreecommitdiff
path: root/telephony/java
diff options
context:
space:
mode:
authorHui Wang <huiwang@google.com>2020-12-10 22:40:07 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-12-10 22:40:07 +0000
commit4c9e7a8d0c031cdbfd88394a073e957be9049ad0 (patch)
treee8b3e82deef37eeba696410115d234e7b44f6a6e /telephony/java
parentbeb163c65574f9c950b7009eefb15cbd00d3e483 (diff)
parentbfc6cd7483d998701d7dbe5b160cc8ef7e6ff586 (diff)
Merge "Support Gba Api"
Diffstat (limited to 'telephony/java')
-rw-r--r--telephony/java/android/telephony/Annotation.java14
-rw-r--r--telephony/java/android/telephony/IBootstrapAuthenticationCallback.aidl27
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java173
-rw-r--r--telephony/java/android/telephony/gba/GbaAuthRequest.aidl18
-rw-r--r--telephony/java/android/telephony/gba/GbaAuthRequest.java161
-rw-r--r--telephony/java/android/telephony/gba/GbaService.java226
-rw-r--r--telephony/java/android/telephony/gba/IGbaService.aidl27
-rw-r--r--telephony/java/android/telephony/gba/TlsParams.java281
-rw-r--r--telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.aidl18
-rw-r--r--telephony/java/android/telephony/gba/UaSecurityProtocolIdentifier.java436
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl29
11 files changed, 1410 insertions, 0 deletions
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index f900c387f060..99f2e5ee0755 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -624,6 +624,20 @@ public class Annotation {
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 000000000000..d39ad0e9a2ef
--- /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 b20ad293bd68..8368e3a72734 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -78,12 +78,14 @@ import android.telephony.Annotation.RadioPowerState;
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;
@@ -7163,6 +7165,8 @@ public class TelephonyManager {
}
}
+ /** 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 */
@@ -14281,4 +14285,173 @@ public class TelephonyManager {
}
return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
}
+
+ /** @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 000000000000..ba243a27b4be
--- /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 000000000000..5366e9af3147
--- /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 000000000000..cb82e916e80c
--- /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 (Generic Bootstrapping Architecture) 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 000000000000..b7ba5a4441ec
--- /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 000000000000..922f4bbb4dbf
--- /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 000000000000..a71e860fd54c
--- /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 000000000000..c1418758f64f
--- /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 c448fa39e006..205a425a5161 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.CellIdentity;
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;
@@ -2274,4 +2276,31 @@ interface ITelephony {
*/
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);
}