Carrier Wi-Fi

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.

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-AKA
    • 1: EAP-SIM
    • 6: EAP-AKA'
  • The NAI realm format is wlan.mncXXX.mccYYY.3gppnetwork.org where XXX is replaced with the SIM card's mobile network code (MNC) and YYY 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-AKA
  • 1: EAP-SIM
  • 6: 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 identity
  • 0: EAP-AKA
  • 1: EAP-SIM
  • 6: 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:

  1. The public key and expiration can be extracted from the certificate.
  2. 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-----"
    } ]
    }