Android 5.1 introduced a mechanism to grant special privileges for APIs relevant to the owners of universal integrated circuit card (UICC) apps. The Android platform loads certificates stored on a UICC and grants permission to apps signed by these certificates to make calls to a handful of special APIs.
Android 7.0 extended this feature to support other storage sources for UICC carrier privilege rules, dramatically increasing the number of carriers that can use the APIs. For an API reference, see CarrierConfigManager; for instructions, see Carrier Configuration.
Carriers have full control of the UICC, so this mechanism provides a secure and flexible way to manage apps from the mobile network operator (MNO) hosted on generic app distribution channels (such as Google Play) while retaining special privileges on devices and without the need to sign apps with the per-device platform certificate or preinstall as a system app.
Rules on UICC
Storage on the UICC is compatible with the
GlobalPlatform
Secure Element Access Control specification. The app identifier
(AID) on the card is A00000015141434C00
, and the standard
GET DATA
command is used to fetch rules stored on the card. You can update these rules
through card over-the-air (OTA) updates.
Data hierarchy
UICC rules use the following data hierarchy (the two-character letter and
number combination in parentheses is the object tag). Each rule is
REF-AR-DO
(E2
) and consists of a concatenation of
REF-DO
and AR-DO
:
REF-DO
(E1
) containsDeviceAppID-REF-DO
or a concatenation ofDeviceAppID-REF-DO
andPKG-REF-DO
.DeviceAppID-REF-DO
(C1
) stores the SHA-1 (20 bytes) or SHA-256 (32 bytes) signature of the certificate.PKG-REF-DO
(CA
) is the full package name string defined in the manifest, ASCII encoded, max length 127 bytes.
AR-DO
(E3
) is extended to includePERM-AR-DO
(DB
), which is an 8-byte bit mask representing 64 separate permissions.
If PKG-REF-DO
isn't present, any app signed by the certificate
is granted access; otherwise both the certificate and the package name need to
match.
Rule example
The app name is com.google.android.apps.myapp
and the
SHA-1 certificate in hex string is:
AB:CD:92:CB:B1:56:B2:80:FA:4E:14:29:A6:EC:EE:B6:E5:C1:BF:E4
The rule on UICC in hex string is:
E243 <= 43 is value length in hex E135 C114 ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4 CA1D 636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070 E30A DB08 0000000000000001
Access rule file support
Android 7.0 adds support for reading carrier privilege rules from the access rule file (ARF).
The Android platform first attempts to select the access rule application
(ARA) AID A00000015141434C00
. If it doesn't find
the AID on the UICC, it falls back to ARF by selecting PKCS15 AID
A000000063504B43532D3135
. Android then reads the
access control rules file (ACRF) at 0x4300
and looks for entries
with AID FFFFFFFFFFFF
. Entries with different AIDs are ignored, so
rules for other use cases can coexist.
Example ACRF content in hex string:
30 10 A0 08 04 06 FF FF FF FF FF FF 30 04 04 02 43 10
Example access control conditions file (ACCF) content:
30 16 04 14 61 ED 37 7E 85 D3 86 A8 DF EE 6B 86 4B D8 5B 0B FA A5 AF 81
In the example above, 0x4310
is the address for ACCF, which
contains the certificate hash
61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
. Apps
signed by this certificate are granted carrier privileges.
Enabled APIs
Android supports the following APIs.
TelephonyManager
- Method to let the carrier app to ask UICC for a challenge/response:
getIccAuthentication
. - Method to check whether the calling app has been granted carrier
privileges:
hasCarrierPrivileges
. - Methods to override brand and number:
- Methods for direct UICC communication:
- Method to set device mode to global:
setPreferredNetworkTypeToGlobal
. - Methods to get the device or network identities:
- International Mobile Equipment Identity (IMEI):
getImei
- Mobile Equipment Identifier (MEID):
getMeid
- Network Access Identifier (NAI):
getNai
- SIM serial number:
getSimSerialNumber
- International Mobile Equipment Identity (IMEI):
- Method to get the carrier configuration:
getCarrierConfig
- Method to get the network type for data transmission:
getDataNetworkType
- Method to get the network type for voice service:
getVoiceNetworkType
- Methods to get the information about the UICC SIM (USIM) app:
- SIM serial number:
getSimSerialNumber
- Card information:
getUiccCardsInfo
- GID1 (group ID level1):
getGroupIdLevel1
- Phone number string for line 1:
getLine1Number
- Forbidden public land mobile network (PLMN):
getForbiddenPlmns
- Equivalent home PLMN:
getEquivalentHomePlmns
- SIM serial number:
- Methods to get or set voicemail number:
- Method to send special dialer code:
sendDialerSpecialCode
- Method to reset the radio modem:
rebootModem
- Methods to get or set network selection modes:
- Method to request a network scan:
requestNetworkScan
- Methods to get or set the allowed/preferred network types:
- Methods to check if the mobile data or roaming is enabled per user settings:
- Methods to check or set data connection with reason:
- Method to get the emergency number list:
getEmergencyNumberList
- Methods to control the opportunistic networks:
- Methods to set or clear cellular signal strength update request:
TelephonyCallback
TelephonyCallback
has interfaces with a callback method to
notify the calling app when the registered states change:
- The message waiting indicator changed:
onMessageWaitingIndicatorChanged
- The call forwarding indicator changed:
onCallForwardingIndicatorChanged
- The IP multimedia system (IMS) call disconnection cause changed:
onImsCallDisconnectCauseChanged
- The precise data connection state changed:
onPreciseDataConnectionStateChanged
- The current emergency number list changed:
onEmergencyNumberListChanged
- The active data subscription ID changed:
onActiveDataSubscriptionIdChanged
- The carrier network changed:
onCarrierNetworkChange
- The network registration or a location/routing/tracking area update
failed:
onRegistrationFailed
- The barring information change:
onBarringInfoChanged
- The current physical channel configuration changed:
onPhysicalChannelConfigChanged
SubscriptionManager
- Methods to get various subscription information:
- Method to get the number of active subscriptions:
getActiveSubscriptionInfoCount
- Methods to manage subscription groups:
- Methods to get or set the description of the billing relationship plan between a carrier and a specific subscriber:
- Method to temporarily override the billing relationship plan between a
carrier and a specific subscriber to be considered unmetered:
setSubscriptionOverrideUnmetered
- Method to temporarily override the billing relationship plan between a
carrier and a specific subscriber to be considered congested:
setSubscriptionOverrideCongested
- Method to check whether the app with the given context is
authorized to manage the given subscription according to its metadata:
canManageSubscription
SmsManager
- Method to let the caller create new incoming SMS messages:
injectSmsPdu
. - Method to send a text based SMS message without writing into the SMS
provider:
sendTextMessageWithoutPersisting
CarrierConfigManager
- Method to notify configuration changed:
notifyConfigChangedForSubId
. - Method to get carrier configuration for the default subscription:
getConfig
- Method to get carrier configuration for the specified subscription:
getConfigForSubId
For instructions, see Carrier Configuration.
BugreportManager
Method to start a connectivity bug report, which is a specialized version of
the bug report that includes only information for debugging connectivity related
issues:
startConnectivityBugreport
NetworkStatsManager
- Method to query network usage summary:
querySummary
- Method to query network usage history:
queryDetails
- Methods to register or unregister network usage callback:
ImsMmTelManager
- Methods to register or unregister IMS MmTel registration callback:
ImsRcsManager
- Methods to register or unregister IMS RCS registration callback:
- Methods to get IMS registration state or transport type:
ProvisioningManager
- Methods to register and unregister IMS feature provisioning updates callback:
- Methods related to the provisioning status for IMS MmTel or RCS capability:
EuiccManager
Method to switch to (enable) the given subscription:
switchToSubscription
CarrierMessagingService
Service that receives calls from the system when new SMS and MMS are sent or
received. To extend this class, declare the service in your manifest file with
the android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE
permission and include an intent filter with the #SERVICE_INTERFACE
action. Methods include:
- Method to filter inbound SMS messages:
onFilterSms
- Method to intercept text SMS messages sent from the device:
onSendTextSms
- Method to intercept binary SMS messages sent from the device:
onSendDataSms
- Method to intercept long SMS messages sent from the device:
onSendMultipartTextSms
- Method to intercept MMS messages sent from the device:
onSendMms
- Method to download MMS messages received:
onDownloadMms
CarrierService
Service that exposes carrier-specific functionalities to the system. To
extend this class, declare the service in the app manifest file with the
android.Manifest.permission#BIND_CARRIER_SERVICES
permission and
include an intent filter with the CARRIER_SERVICE_INTERFACE
action.
If the service has a long-lived binding, set
android.service.carrier.LONG_LIVED_BINDING
to
true
in the metadata of the service.
The platform binds CarrierService
with special flags to let the
carrier service process run in a special
app standby bucket. This exempts the carrier service app from
app idle restriction and makes it more likely to stay alive when device
memory is low. However, if the carrier service app crashes for any reason,
it loses all above privileges until the app restarts and the binding is
reestablished. So it's critical to keep the carrier service app stable.
Methods in CarrierService
include:
- To override and set the carrier specific configurations:
onLoadConfig
- To inform the system of an intentional upcoming carrier network change by
the carrier app:
notifyCarrierNetworkChange
Telephony provider
Content provider APIs to allow modifications (insert, delete, update, query)
to the telephony database. Values fields are defined at
Telephony.Carriers
; for more details, refer to
the Telephony
class reference
WifiNetworkSuggestion
When building a WifiNetworkSuggestion
object, use the following
methods to set a subscription ID or a subscription group:
- Method to set a subscription ID:
setSubscriptionId
- Metohd to set a subscription group:
setSubscriptionGroup
Android platform
On a detected UICC, the platform constructs internal UICC objects that
include carrier privilege rules as part of the UICC.
UiccCarrierPrivilegeRules.java
loads rules, parses them from the UICC card, and caches them in memory. When
a privilege check is needed, UiccCarrierPrivilegeRules
compares the
caller certificate with its own rules one by one. If the UICC is removed, the
rules are destroyed along with the UICC object.
Validation
To validate the implementation through
Compatibility Test Suite (CTS) using CtsCarrierApiTestCases.apk
,
you must have a developer UICC with the correct UICC rules or ARF support.
Ask the SIM card vendor of your choice to prepare a developer UICC with the
right ARF as described in this section and use that UICC to run the tests. The
UICC doesn't require active cellular service to pass CTS tests.
Prepare the UICC
For Android 11 and lower, CtsCarrierApiTestCases.apk
is
signed by aosp-testkey
, with hash value
61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
.
Starting in Android 12, CtsCarrierApiTestCases.apk
is
signed by
cts-uicc-2021-testkey
, hash value
CE:7B:2B:47:AE:2B:75:52:C8:F9:2C:C2:91:24:27:98:83:04:1F:B6:23:A5:F1:94:A8:2C:9B:F1:5D:49:2A:A0
.
To run CTS carrier API tests in Android 12, the device needs to use a SIM with CTS carrier privileges meeting the requirements specified in the latest version of the third-party GSMA TS.48 Test Profile specification.
The same SIM can also be used for versions prior to Android 12.
Modify the CTS SIM profile
- Add: CTS carrier privileges in
access rule app master (ARA-M) or ARF. Both signatures must be
encoded in the carrier privilege rules:
- Hash1(SHA1):
61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
- Hash2(SHA256):
CE:7B:2B:47:AE:2B:75:52:C8:F9:2C:C2:91:24:27:98:83:04:1F:B6:23:A5:F1:94:A8:2C:9B:F1:5D:49:2A:A0
- Hash1(SHA1):
- Create: ADF USIM elementary files (EFs) not present in
TS.48 and needed for CTS:
- EF_MBDN (6FC7), record size: 28, record number: 4
- Content
- Rec1: 566F696365204D61696CFFFFFFFF06915155555555FF…FF
- Rec2-n: FF…FF
- Content
- EF_EXT6 (6FC8), record size:13, record number: 1
- Content: 00FF…FF
- EF_MBI (6FC9), record size: 4, record number: 1
- Content: Rec1: 01010101
- EF_MWIS (6FCA), record size: 5, record number: 1
- Content: 0000000000
- Content: 00FF…FF
- EF_MBDN (6FC7), record size: 28, record number: 4
- Modify: USIM service table: Enable services n°47, n°48
- EF_UST (6F38)
- Content:
9EFFBF1DFFFE0083410310010400406E01
- Content:
- EF_UST (6F38)
- Modify: DF-5GS and DF-SAIP files
- DF-5GS - EF_5GS3GPPLOCI (USIM/5FC0/4F01)
- Content:
FFFFFFFFFFFFFFFFFFFFFFFFFF42F618FFFFFE01
- Content:
- DF-5GS - EF_5GSN3GPPLOCI (USIM/5FC0/4F02)
- Content:
FFFFFFFFFFFFFFFFFFFFFFFFFF42F618FFFFFE01
- Content:
- DF-5GS - EF SUCI_Calc_Info (USIM/5FC0/4F07)
- Content:
A0020000FF…FF
- Content:
- DF-SAIP - EF SUCI_Calc_Info_USIM (USIM/5FD0/4F01)
- Content:
A0020000FF…FF
- Content:
- DF-5GS - EF_5GS3GPPLOCI (USIM/5FC0/4F01)
- Modify: Use the carrier name string Android CTS
in respective EFs containing this designation:
- EF_SPN (USIM/6F46)
- Content:
01416E64726F696420435453FF..FF
- Content:
- EF_PNN (USIM/6FC5)
- Content:
Rec1 430B83413759FE4E934143EA14FF..FF
- Content:
- EF_SPN (USIM/6F46)
Match the test profile structure
Download and match the latest version of the following generic test profile structures. These profiles won't have the CTS Carrier Privilege rule personalized or other modifications listed above.
Run tests
For convenience, CTS supports a device token that restricts
tests to run only on devices configured with the same token. Carrier API CTS
tests support the device token sim-card-with-certs
. For example,
the following device token restricts carrier API tests to run only on device
abcd1234
:
cts-tradefed run cts --device-token abcd1234:sim-card-with-certs
When running a test without using a device token, the test runs on all devices.
FAQ
How can certificates be updated on the UICC?
A: Use the existing card OTA update mechanism.
Can UICC coexist with other rules?
A: It's fine to have other security rules on the UICC under the same AID; the platform filters them out automatically.
What happens when the UICC is removed for an app that relies on the certificates on it?
A: The app loses its privileges because the rules associated with the UICC are destroyed on UICC removal.
Is there a limit on the number of certificates on the UICC?
A: The platform doesn't limit the number of certificates; but because the check is linear, too many rules may incur a latency for check.
Is there a limit to the number of APIs that we can support with this method?
A: No, but we limit the scope to carrier-related APIs.
Are there some APIs prohibited from using this method? If so, how do you enforce them? (that is, do you have tests to validate which APIs are supported with this method?)
A: See the API Behavioral Compatibility section of the Android Compatibility Definition Document (CDD). We have some CTS tests to make sure that the permission model of the APIs isn't changed.
How does this work with the multi-SIM feature?
A: The default SIM specified by the user is used.
Does this in any way interact or overlap with other SE access technologies, for example, SEEK?
A: As an example, SEEK uses the same AID as on the UICC. So the rules
coexist and are filtered by either SEEK or
UiccCarrierPrivileges
.
When is it a good time to check carrier privileges?
A: After the SIM state loaded broadcast.
Can OEMs disable part of carrier APIs?
A: No. We believe that the current APIs are the minimal set, and we plan to use the bit mask for finer granularity control in the future.
Does setOperatorBrandOverride
override ALL other forms
of operator
name strings? For example, SE13, UICC SPN, or network-based NITZ?
Yes, the operator brand override has the highest priority. When it's set, it overrides ALL other forms of operator name strings.
What does the injectSmsPdu
method call do?
A: This method facilitates SMS backup/restore in the cloud. The
injectSmsPdu
call enables the restore function.
For SMS filtering, is the onFilterSms
call based on
SMS UDH port filtering? Or do carrier apps have access to ALL incoming SMS?
A: Carriers have access to all SMS data.
The extension of DeviceAppID-REF-DO
to support
32 bytes appears to be
incompatible with the current GP spec (which allows 0 or 20 bytes only), so why
are you introducing this change? Isn't SHA-1 sufficient to
avoid collisions? Have you proposed this change to GP already, as this could
be backward incompatible with existing ARA-M/ARF?
A: For providing future-proof security, this extension introduces SHA-256
for DeviceAppID-REF-DO
in addition to SHA-1, which is currently
the only option in the GP SEAC standard. We highly recommend using SHA-256.
If DeviceAppID
is 0 (empty), do you apply the rule to
all device apps not covered by a specific rule?
A: Carrier APIs require DeviceAppID-REF-DO
be populated.
Being empty is intended for test purposes and isn't recommended for operational
deployments.
According to your spec, PKG-REF-DO
used just by
itself, without DeviceAppID-REF-DO
, shouldn't be accepted. But
it's still described in Table 6-4 of the specification as extending the
definition of REF-DO
. Is this on purpose? How does the code
behave when only PKG-REF-DO
is used in REF-DO
?
A: The option of having PKG-REF-DO
as a single value
item in REF-DO
was removed in the latest version.
PKG-REF-DO
should occur only in combination with
DeviceAppID-REF-DO
.
We assume that we can grant access to all carrier-based permissions or have finer-grained control. If so, what defines the mapping between the bit mask and the actual permissions? One permission per class? One permission per method? Are 64 separate permissions enough in the long run?
A: This is reserved for the future, and we welcome suggestions.
Can you further define DeviceAppID
for Android
specifically? This is the SHA-1 (20 bytes) hash value of the Publisher
certificate used to sign the given app, so shouldn't the name reflect that
purpose? (The name could be confusing to many readers as the rule is then
applicable to all apps signed with that same Publisher certificate.)
A: The DeviceAppID
storing certificates is supported by the
existing spec. We tried to minimize spec changes to lower the barrier for
adoption. For details, see Rules on UICC.