In the Depths of iCloud Keychain

 iCloud 101

In fact, the iCloud is not a single service but general marketing name for a number of cloud-based services from Apple. These include the syncing of settings, documents and photos, Find My Phone to locate lost or stolen devices, iCloud Backup to backup your data to the cloud, and now it’s also iCloud Keychain for secure syncing of passwords and credit card numbers between iOS- and OS X-based devices.

Each iCloud service is hosted at its own third level domain, such as pXX-keyvalueservice.icloud.com, where XX is the number of the server group responsible for processing the requests of the current user; for various Apple IDs, this number can be different; typically, the newer is account, the greater is the number in this counter.

iCloud Security Code

Before diving into analysis of iCloud Keychain, we will pay more attention to the configuration of the service. When enabling iCloud Keychain, the user is asked to think up and enter his/her iCloud Security Code (iCSC). By default, the input form allows you to use a four-digit numeric code, but by clicking the “Advanced Options”, you can use a more complex code or even allow your device to generate a strong random code for you.

Now we know that, in iCloud Keychain, the data is protected by iCSC. Let’s try to understand how exactly this protection is implemented.

By default, iOS prompts you to use a four-digit security code

By default, iOS prompts you to use a four-digit security code

 

Traffic Interception or a Man-in-the-Middle

When you analyze the network services, the first step often includes gaining access to the network traffic between the client and the server. In case of iCloud, we have two pieces of news for you: bad and good. The bad news is that all traffic (or at least the overwhelming part of it) is protected by TLS / SSL, that is, it is encrypted and a conventional passive attack would not allow to “read” it. The good news is that Apple made a gift to all those who want to further study iCloud because it does not use the certificate pinning and, therefore, allows you to rather easily organize a man-in-the-middle attack and decrypt the intercepted traffic. All you need to do is this:

  1. Place the iOS device that you want to use in the experiment into the same Wi-Fi network as the intercepting computer.
  2. Install the intercepting proxy server (such as Burp, Charles Proxy or any similar server) on the computer.
  3. Import the TLS / SSL certificate of installed proxy server (see details in the Help for specific proxy server) to iOS device.
  4. In the Wi-Fi network settings on iOS device (Settings → Wi-Fi → Network Name → HTTP Proxy), specify the IP-address of intercepting computer in Wi-Fi network and the listening port of the proxy server.

If done correctly, this will allow you to get the full view of traffic between the device and iCloud. The interception of this traffic will clearly show that iCloud Keychain is based on two iCloud services: ‘com.apple.Dataclass.KeyValue’ and ‘com.apple.Dataclass.KeychainSync’ — and, when initially and subsequently enabled on other iOS devices, it communicates with these services.

The first service is not new and was among the first features of iCloud; it is widely used by applications to sync settings. The second service is new and, probably, was developed specifically for iCloud Keychain (although, theoretically, its functionality allows to use it also for other purposes). Let’s have a closer look at these services.

com.apple.Dataclass.KeyValue

As I already mentioned above, this is one of services used by iCloud Keychain. Many existing applications use it to synchronize some small amounts of data (settings, bookmarks, etc.). Each record stored by the service is associated with the Bundle ID and the store name. Accordingly, to obtain the stored data, you will also need to provide these identifiers. In iCloud Keychain, this service is used to synchronize Keychain records in the encrypted form. A detailed description of this process is provided in sections on Keychain Syncing and How Keychain Syncing Works in the document “iOS Security”.

Keychain Syncing

When the user enables iCloud Keychain for the first time, the device creates a circle of trust and syncing identity which includes a public and private key for the current device. The public key of this pair is placed in the circle of trust and the circle is signed twice: first, by the private key of syncing identity and next by an asymmetric key (based on Elliptic Curve Cryptography) generated from the user password in iCloud. Also, the circle stores the parameters for calculating the key from the password, such as salt and the number of iterations.

The signed circle is saved in Key/Value store. It cannot be read without knowing the user password in iCloud and cannot be changed without knowing the private key of one of the devices added to the circle.
When a user enables iCloud Keychain on another device, this device communicates with Key/Value store in iCloud and determines that the user already has a circle of trust where the new device is not included. The device generates synchronization keys and a receipt for requesting the membership in the circle. The receipt contains the public key for syncing the device and is signed by a key generated from the iCloud user password by using the key generation parameters retrieved from Key/Value store. Next, the signed receipt is placed in the Key/Value store.

The first device can see the new receipt and displays a message for the user that prompts him/her to add a new device to his/her circle of trust. The user enters his/her iCloud password, and the receipt signature is checked for validity. This proves that the user who generated a request to add the device has entered the correct password when creating the receipt.

Once the user confirms the addition of device to the circle, the first device adds a public key for syncing the new device to the circle and, again, signs it twice by using its private synchronization key and the key generated from the iCloud user password. The new circle is stored in iCloud, and the new device similarly signs it.

How Keychain Syncing Works

Now, there are two devices in the circle of trust, and each of them knows the public keys for syncing the other devices. They begin to share Keychain records via Key/Value store in iCloud. If the same record is present in both devices, the priority will be given to the one with later modification time. If the record modification time in iCloud and on the device is the same, the record is not synced. Each synced record is encrypted specifically for the target device; it cannot be decrypted by other devices or Apple. Furthermore, the record is not permanently stored in iCloud — it is overwritten by the new synced records.

This process is repeated for each new device added to the circle of trust. For example, if a third device is added to the circle, the confirmation request will be displayed on other two devices. The user can confirm the addition on any of them. As you add more devices, each device of the circle is synced with the new one to make sure that the set of records is the same on all devices.

It should be noted that not the entire Keychain is synced. Some records are tied to a device (e.g., VPN accounts), and should not leave the device. Only the records with the attribute ‘kSecAttrSynchronizable’ are synced. Apple has set this attribute for Safari user data (including user names, passwords and credit card numbers) and for Wi-Fi passwords.

In addition, the records of third-party applications are not synced by default. To allow their syncing, the developers must explicitly set the attribute ‘kSecAttrSynchronizable’ when adding the record to Keychain.
iCloud Keychain operates two stores:

  • com.apple.security.cloudkeychainproxy3
    • Bundle ID: com.apple.security.cloudkeychainproxy3;
  • com.apple.sbd3
    • Bundle ID: com.apple.sbd (SBD stands for “Secure Backup Daemon”).

The first store is apparently used to maintain a list of trusted devices (devices in the circle of trust that are allowed for password syncing), to add new devices to the list and to sync the records between devices (in accordance with the mechanism described above).

The second store is designed to backup and restore Keychain records on new devices (for example, when the circle of trust has no other devices) and contains encrypted Keychain records and related information.

Entries in the store 'com.apple.sbd3'

Entries in the store ‘com.apple.sbd3’

 

Therefore, the Keychain records are stored in a regular Key/Value store (‘com.apple.securebackup.record’). These records are encrypted by using a set of keys stored in the same place (BackupKeybag). But this set of keys is protected by a password. Where does this password come from? What is the Apple password escrow service? Let’s try to figure it out.

apple.Dataclass.KeychainSync

This is a new service, which appeared relatively recently: for the first time, it was supported in beta versions of iOS 7, then it disappeared in iOS 7.0-7.0.2 only to be re-added to iOS 7.0.3, which was released simultaneously with OS X Mavericks. This is the password escrow service that I mentioned earlier (the service is hosted at pXX-escrowproxy.icloud.com).

This service is designed to safely store the user secrets and allows the user to recover these secrets after successful authentication. Such successful authentication requires the following:

  • iCloud authentication token obtained in exchange for Apple ID and password during the initial authentication in the iCloud (this is a standard authentication method for most iCloud services);
  • iCloud Security Code (iCSC);
  • Six-digit numeric code communicated by the Apple servers to mobile telephone number associated with the user.

In theory, everything looks good, but to determine whether the theory matches the practice, we will need to audit the client of escrow service. In iOS and OS X, this program is called ‘com.apple.lakitu’. The description of its reverse engineering and audit is beyond the scope of this article, so, let’s go directly to the results.

Available Commands

The audit of ‘com.apple.lakitu’ allows you to identify a list of commands used by the escrow service. On the relevant screenshot, you can see the commands and their descriptions. I would particularly like to draw your attention to the last command. It allows you to change the phone number associated with the current account. This command makes significantly less reliable the multi-factor authentication that is used when recovering iCloud Keychain (Apple ID password + iCSC + device), as it allows to exclude one of the factors. It is also interesting to note that the user interface in iOS does not allow you to run this command — it simply does not have that option (at least, I couldn’t find it).

A feature of this command, that distinguishes it from all others, is that it requires the authentication with the Apple ID password and will not work in case of authentication with iCloud token (other commands work with the authentication token). This provides additional protection for this command and shows that the system designers have taken some steps to improve its security. However, it is not clear why this command is available in the system at all.

Commands supported by 'com.apple.Dataclass.KeychainSync' service

Commands supported by ‘com.apple.Dataclass.KeychainSync’ service

 

Restoring Escrowed Data

The following protocol is followed to obtain the escrowed data:

  1. The client requests the list of escrowed records (‘/get_records’).
  2. The client requests the associated phone number where the server will send a confirmation code (‘/get_sms_targets ‘).
  3. The client initiates the generation and delivery of confirmation code (‘/generate_sms_challenge’).
  4. Once the user has entered iCSC and the confirmation code received from SMS, the client initiates the authentication attempt by using SRP-6a (‘/srp_init’).
  5. After receiving a response from the server, the client makes the calculations prescribed by SRP-6a and requests the escrowed data (‘/recover’).
  6. If the client has successfully passed the authentication, the server returns the escrowed data after encrypting it with the key generated in the process of running SRP-6a (if this protocol has run successfully, then both the server and the client have calculated this shared key).

It is important to note that the phone number obtained in step 2 is used exclusively for the needs of the user interface, that is, to show the user the number where the confirmation code will be sent and, in step 3, the client does not communicate to the server the number for sending the confirmation code.

Recovering the escrowed record

Recovering the escrowed record

 

Secure Remote Password

In step 4, the client initiates SRP-6a protocol. SRP (Secure Remote Password) is a password authentication protocol protected against eavesdropping and man-in-the-middle attacks. For example, when this protocol is used, it is impossible to intercept the password hash and then attempt to restore it, simply because no hash is communicated.

Apple uses SRP-6a, which is the most advanced version of this protocol. This version instructs to disconnect in case of failed authentication. In addition, Apple allows only 10 authentication failures for this service and blocks all subsequent attempts.
A detailed description of SRP and its mathematical foundations is beyond the scope of this article. However, for completeness of presentation, here is an example used by ‘com.apple.Dataclass.KeychainSync’ service.

Example of SRP-6a used by 'com.apple.Dataclass.KeychainSync'

Example of SRP-6a used by ‘com.apple.Dataclass.KeychainSync’

 

As the hash function ‘H’, it uses ‘ SHA-256’ and, as a group (‘N’, ‘g’), it uses a 2048-bit group from ‘RFC 5054’ “Using the Secure Remote Password (SRP) Protocol for TLS Authentication”. The protocol is run as follows:

  1. The device generates a random value ‘a’, calculates ‘A=g^a mod N’, where ‘N’ and ‘g’ are the parameters of 2048-bit group from ‘RFC 5054’, and sends to the server the message that contains the user ‘ID’, computed value ‘A’ and confirmation code from SMS. ‘DsID’ value, a unique numeric user ID, is used as the user identifier.
  2. After receiving the message, the server generates a random ‘b’ value and computes ‘B=k*v + g^b mod N’, where ‘k’ is a multiplier specified in ‘SRP-6a’ as ‘k=H(N, g)’, ‘v=g^H(Salt, iCSC) mod N’ is the password verifier stored on a server (similar to the password hash), the ‘Salt ‘ is a random salt generated when creating the account. The server sends a message to the client containing ‘B’ and ‘Salt’.
  3. The client and the server compute their shared session key ‘K’ through simple mathematical transformations. After this, the first part of the protocol—key generation—is completed, and now the client and the server must make sure that they have the same ‘K’ value.
  4. The client computes ‘M=H(H(N) XOR H(g) | H(ID) | Salt | A | B | K)’ to prove that it knows ‘K’ and sends to the server the ‘M’ value and verification code received from SMS. The server also computes ‘M’ and compares the value received from the client with the computed value; if they do not match, the server terminates the protocol and disconnects.
  5. The server proves to the client that it knows ‘K’ by computing and sending ‘H(A, M, K)’. Now, both participants in the protocol not only generated a shared key but also made sure that both of them have the same key. In case of the escrow service, the server also returns a random initialization vector ‘ IV ‘ and the escrowed record encrypted with the shared key ‘K’ by using ‘AES’ algorithm in ‘CBC’ mode.

In my opinion, the use of SRP for additional protection of user data substantially improves the system security against external attacks, if only because it allows to effectively resist the attempted brute force attacks against iCSC: during one connection to the service, you can try just one password. After several failed attempts, the account (as part of working with the escrow service) is switched to soft lock state and temporarily blocked and, after ten failed attempts, the account will be blocked permanently and any further work with the escrow service can be allowed only after resetting iCSC for the account.
At the same time, the use of SRP does not, in any way, protect against internal threats. The escrowed password is stored on the Apple servers and, therefore, we can assume that Apple can gain access to it when needed. In this case, if the password has not been protected (for example, encrypted) before escrow, this may lead to completely compromising Keychain records stored in iCloud, since the escrowed password will allow to decrypt the encryption keys and they, in turn, will allow to decrypt Keychain records (pay attention to ‘com.apple.Dataclass.KeyValue’).

However, in its “iOS Security” document, Apple claims that it uses specialized Hardware Security Modules (HSM) to store the escrowed records and that the access to escrowed data is impossible.

Escrow Security

iCloud provides a secure infrastructure for the escrow of Keychain which ensures the recovery of Keychain only by authorized users and devices. HSM clusters protect the escrowed records. Each cluster has its own encryption key that is used to protect the records.

To recover its Keychain, the user should pass the authentication by using his/her user name and iCloud password, and reply to received SMS. When this is done, the user must enter his/her iCloud Security Code (iCSC). HSM cluster checks whether the iCSC is correct by using SRP protocol; and, in this case, iCSC is not communicated to Apple servers. Each cluster node, regardless of the others, checks whether the user exceeded the maximum number of attempts to retrieve data. If in most of the nodes the verification is completed successfully, the cluster will decrypt the escrowed record and return it to the user.
Next, the device uses iCSC to decrypt the escrowed record and get the password used to encrypt Keychain records. With this password, the Keychain retrieved from Key/Value store is decrypted and recovered to the device. The system allows only 10 attempts to pass the authentication and retrieve the escrowed data. After several failed attempts, the record is locked and the user must contact the customer support to unlock it. After the tenth failed attempt, HSM cluster will destroy the escrowed record. This provides protection against brute force attacks aimed at retrieving the record.

Unfortunately, we couldn’t check whether HSM is really used. If it is really so and HSM does not allow to read their stored data, one can argue that the iCloud Keychain data is also protected from internal threats. But let me repeat that, unfortunately, we cannot prove or refute the use of HSM and the impossibility to read their stored data.

Still, there is one more way to protect your data from internal threats — by protecting the escrowed data on your device before sending it to Apple servers. As it follows from the description provided by Apple (and the reverse engineering confirms that), such protection is really used and the escrowed password is encrypted by using the iCSC before sending it to Apple servers. Obviously, in this case, the level of security (against internal threats) directly depends on the complexity of iCSC and a four-character iCSC used by default does not provide sufficient protection.

Now that we found out how individual elements of the system operate, it is time to look at the system as a whole.

Putting it all Together

The diagram shows the escrow process and recovery of Keychain records in iCloud Keychain. The system works as follows:

  1. The device generates a set of random keys (‘keybag’ in Apple terminology) to encrypt the Keychain records.
  2. The device encrypts the Keychain records (which have the enabled attribute ‘kSecAttrSynchronizable’) with a set of keys generated in the previous step and stores the encrypted records in Key/Value store ‘com. apple. sbd3’ (key ‘com. apple. securebackup. record’).
  3. The device generates a random password, which consists of six groups of four characters (the entropy of such a password is about 124 bit), encrypts the set of keys generated in step 1 by using this password and saves the encrypted set of keys in Key/Value store ‘com. apple.sbd3’ (key ‘BackupKeybag’).
  4. The device encrypts a random password generated in the previous step by using the key obtained from the iCloud security code of the user and escrows the encrypted password to the service ‘com.apple.Dataclass.KeychainSync’.

When configuring his/her iCloud Keychain, the user can apply a complex or random iCSC instead of a 4-digit code prompted by default. When you use a complex code, the mechanism of escrow system does not change; the only difference is that the key for encrypting a random password will be computed not from the four-digit iCSC but from a more complex code entered by the user.
In case of a random code, the password escrow engine is not used at all. Moreover, the random password generated by the system is iCSC, which the user must remember and store safely. The Keychain records are encrypted and stored in Key/Value store ‘com.apple.sbd3’ in the same way, but the service ‘com.apple.Dataclass.KeychainSync’ is not used.

Diagram of Keychain escrow and recovery engine

Diagram of Keychain escrow and recovery engine

 

Conclusions

We can safely say that, from a technical point of view (i.e. without considering the possibility of social engineering) and against the external threats (i.e. not Apple), the security of iCloud Keychain escrow service is at a sufficient level. The use of SRP protocol prevents the attacker from gaining access to Keychain records, even when the iCloud password is compromised, because such access additionally requires iCloud Security Code, and any brute force attack against this code is made significantly more difficult.

At the same time, by using another iCloud Keychain mechanism, such as the password syncing, an attacker that compromised the iCloud password and has a brief physical access to one of user’s devices can also fully compromise the iCloud Keychain — all he/she has to do is to add the attacker’s device to the circle of trust of user’s devices and this can be done just by knowing the iCloud password and having a brief access to the user’s device in order to confirm the request to add a new device to the circle.

As for protection against the internal threats (i.e., Apple or anyone else with access to Apple servers), the security of escrow service does not appear so rosy. Apple’s claims, that it is using HSM and the data stored on them cannot be read, are not supported by irrefutable evidence, and the cryptographic protection of escrowed data is tied to iCloud Security Code, which is extremely weak in case of default settings and allows anyone who is able to retrieve the escrowed records from Apple servers (or HSM) to almost instantly recover the four-digit iCloud Security Code.
In case of a complex alphanumeric code, such attack becomes more difficult as the number of possible passwords is greater. If iCloud Keychain is configured for using a random code, the escrow service is not used at all, which indeed makes this attack vector impossible.
The maximum security (excluding, of course, the option of completely disabling iCloud Keychain) is ensured by using a random code — this is not because such code is harder to break with a brute force attack, but because the password escrow engine is not used at all and, hence, the attack surface becomes smaller. However, the user-friendliness of this option leaves much to be desired.


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>