Carrier Wi-Fi is an auto-connection feature (using encrypted IMSI) available in Android 9 and higher that allows devices to automatically connect to carrier-implemented Wi-Fi networks. In areas of high congestion or with minimal cell coverage such as a stadium or an underground train station, carrier Wi-Fi can be used to improve users' connectivity experience and to offload traffic.
Devices with the carrier Wi-Fi feature automatically connect to configured carrier Wi-Fi networks (networks with a public key certificate). When a user manually disconnects from a carrier Wi-Fi network, the network is blacklisted for 24 hours (no auto-connection). Users can manually connect to blacklisted networks at any time.
On devices running Android 9 or higher with carrier Wi-Fi implemented, automatic connection through carrier Wi-Fi is off by default. A notification is sent to the user when the device attempts to connect to a carrier Wi-Fi network for the first time.
Implementation
Device manufacturers and carriers must do the following to implement carrier Wi-Fi.
Manufacturers
For devices running Android 11 and higher, use the Wi-Fi suggestion API to add Wi-Fi profiles for each carrier.
For devices running 10 or lower, add Wi-Fi profiles by
configuring the carrier_wifi_string_array
parameter for each carrier in the
carrier config manager.
carrier_wifi_string_array
: A string array where each string entry is a Base64-encoded Wi-Fi SSID and an EAP type separated by a comma, where the EAP type is an integer (refer to Extensible Authentication Protocol (EAP) Registry). For example, the following configuration is for SOME_SSID_NAME using EAP-AKA and Some_Other_SSID using EAP-SIM:config { key: "carrier_wifi_string_array" text_array { item: "U09NRV9TU0lEX05BTUUK,23" item: "U29tZV9PdGhlcl9TU0lECg==,18" } }
In the carrier config manager, configure the following parameters for each carrier:
imsi_key_availability_int
: Identifies whether the key used for IMSI encryption is available for WLAN (bit 1 is set), EPDG (bit 0 is set), or both (both bit 0 and bit 1 are set). For example, the following configuration indicates that IMSI encryption is available for WLAN but not for EPDG:config { key: "imsi_key_availability_int" int_value: 2 }
imsi_key_download_url_string
: URL from which the proto containing the public key of the carrier used for IMSI encryption is downloaded. For example, the following configuration provides a specific URL:config { key: "imsi_key_download_url_string" text_value: "https://www.some_company_name.com:5555/some_directory_name/some_filename.json" }
allow_metered_network_for_cert_download_bool
: A flag indicating whether to allow the downloading of the public key of the carrier over a metered (cellular) network. If this flag isn't set, a new device with no Wi-Fi connectivity won't be able to connect to the Carrier Wi-Fi network because it won't be allowed to download the key.config { key: "allow_metered_network_for_cert_download_bool" bool_value: true }
Carriers
To implement carrier Wi-Fi, the carrier must enable IMSI privacy protection and provide a public key.
IMSI privacy protection
Android protects the confidentiality of a subscriber's permanent identity (IMSI) using public key cryptography. Android implements the Wireless Broadband Alliance (WBA) specification for IMSI Privacy Protection for Wi-Fi. When IMSI privacy protection is enabled for a connection, the permanent subscriber identity isn't transmitted in the clear over the air.
Permanent identity encryption
The format of the encrypted permanent identity is as follows:
- The permanent identity is in the format of
<EAP-Method><IMSI>@<NAI realm>
. - The EAP-Method prefix is a single octet that defines the EAP method that's
used for the authentication:
0
: EAP-AKA1
: EAP-SIM6
: EAP-AKA'
- The NAI realm format is
wlan.mncXXX.mccYYY.3gppnetwork.org
whereXXX
is replaced with the SIM card's mobile network code (MNC) andYYY
is replaced with the mobile country code (MCC). - The permanent identity is encrypted using an RSA public key provided by the carrier. The public key is included in an X.509 certificate.
- The encryption scheme is RSAES-OAEP with SHA-256 as the cryptographic hash function. This encryption scheme guarantees a unique cipher text every time the scheme is used, thus avoiding yet another persistent identity that can be trackable.
- The RSA key length is 2048 bits.
- The encryption buffer is 256 bytes.
- The cipher text is encoded with Base64.
- The output encrypted permanent identity length is 344 bytes.
Encrypted Permanent Identity = Base64(RSAES-OAEP-SHA-256(<EAP-Method><IMSI>@<NAI Realm>))
Key identifier
The key identifier is an optional attribute value pair that the carrier attaches
to a certificate to allow the server to locate the proper private key during
authentication. An example of a key identifier is
CertificateSerialNumber=123456
. If the key identifier is provided, it's sent
in the clear as part of the authentication process.
Modifications to SIM-based EAP authentication methods
When IMSI privacy protection is enabled on a connection, the system doesn't send
the permanent identity upon receipt of EAP-Request/Identity
, instead it
responds with an anonymous login:
SERVER: EAP-Request/Identity
UE: EAP-Response/Identity AT_IDENTITY=<prefix>|anonymous@<NAI Realm>
<prefix>
is optional. If the enable_eap_method_prefix_bool
carrier
configuration is set to true
, the first character of the identity (before
anonymous
) notifies the server about the type of EAP method used before the
EAP exchange begins.
0
: EAP-AKA1
: EAP-SIM6
: EAP-AKA'
If the carrier configuration is set to false
, this prefix isn't included in
the message.
In response, the server sends an EAP-Request/AKA-Identity
message and the
system responds in the following format:
SERVER: EAP-Request/AKA-Identity AT_ANY_ID_REQ
UE: EAP-Response/AKA-Identity AT_IDENTITY=<prefix>|<Encrypted Permanent Identity>|","|"<attribute>=<value>"
The first character of the identity notifies the server either that an encrypted identity is used, or the type of EAP method that is configured:
\0
: Encrypted permanent identity0
: EAP-AKA1
: EAP-SIM6
: EAP-AKA'
The key identifier attribute value pair is optional and isn't appended to the end of the encrypted permanent identity if not in use.
At this point, the server locates the private key from the key identifier (if provided), decrypts the encrypted identity using the carrier private key, and continues the normal EAP flow.
Upon successful authentication, the server can provide a fast re-authentication identity or a temporary identity (pseudonym), which is used in subsequent connections. If no temporary identities are provided by the server, the system sends the encrypted identity in the subsequent connection.
Carrier certificate retrieval, expiration, and revocation
In the case where no certificate is installed in the system, the system uses the
URL provided in the imsi_key_download_url_string
carrier configuration to
download a certificate using the HTTP GET method. The system uses cellular data
only if the allow_metered_network_for_cert_download_bool
carrier
configuration is set to true
. Otherwise, the system downloads the certificate
only when a Wi-Fi connection is available.
Certificate expiration is enforced by the system. The system starts attempting to renew certificates 21 days prior to the certificate expiration date, and uses the same URL to download the new certificate.
In the case the server is unable to decrypt the encrypted identity, the server
sends an EAP-Request/AKA-Notification
message with the AT_NOTIFICATION
code
General Failure
(16384) to terminate the EAP exchange.
In the case where the certificate is revoked or expired, the server sends an
EAP-Request/AKA-Notification
message with the AT_NOTIFICATION
code
Certificate Replacement Required
(16385) to terminate the EAP exchange.
In response, the system applies internal heuristics to determine whether to
remove the certificate and attempt to download a new certificate from the same
URL.
Provide the public key
Provide a public URL to a server, preferably using HTTP over TLS, that hosts the certificate of the carrier where:
- The public key and expiration can be extracted from the certificate.
The information from the server is in JSON format as follows:
Property: key-identifier Type: String Encoding: UTF-8 Description: Specifies an identifier that the carrier would like to attach to the certificate. Optional: Yes Property: certificate Property alternative name: public-key Type: String Encoding: Base64 Description: The content of the carrier's X.509 certificate. Optional: No Property: key-type Type: String Encoding: UTF-8 Description: Specifies the module that will use the key. The value for type must be either WLAN or EPDG. Optional: Yes. If the key-type property isn't included, then its value defaults to WLAN.
The following is an example of a public key.
{ "carrier-keys" : [ { "key-identifier" : "CertificateSerialNumber=5xxe06d4", "public-key" : "-----BEGIN CERTIFICATE-----\r\nTIIDRTCCAi2gAwIBAgIEVR4G1DANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJVUzELMAkGA1UE\r\nCBMCTkExCzAJBgNVBAcTAk5BMQswCQYDVQQKEwJOQTELMAkGA1UECxMCTkExEDAOBgNVBAMTB1Rl\r\nc3RiT6N1/w==\r\n-----END CERTIFICATE-----" } ] }