Is This An iCloud Advanced Data Protection Encryption Bug?


It does not look to me like the encryption keys used to secure iCloud data in the Advanced Data Protection regime are changed (i.e. rotated) as needed to provide the promised level of security. I base this claim on my research using Apple’s own tools, open source disclosures, and documentation. I reported this finding to Apple; they closed my report as “expected behavior”, without further clarification.

I disclose my findings to urge another researcher to definitively settle this one way or another. I believe other researchers already have access to tooling to easily do this work.

If my findings are ultimately conclusively proven to represent a security flaw, it would mean that users of iCloud accounts can be permanently compromised by an attacker who steals their encryption keys keys once and then has later access to the cipher texts stored in iCloud. It may also leave users open to attacks where Apple (or an attacker penetrating Apple’s infrastructure) stores the keys that users share with Apple before ADP is enabled, and then later uses those keys to access user content after ADP is enabled. Either of these scenarios ought to break the ADP threat model.


This is not the post I originally wanted to write. I wanted to write about how to regain the full security guarantees of iCloud Advanced Data Protection (ADP) after a trusted device compromise. My research question was: “Imagine you’re a journalist and your iPhone (which is logged into your iCloud account) got infected with some nasty malware that can steal anything on it. What do you need to do to trust your iCloud account again?” More specifically, I wanted to know how iCloud’s ADP mode maintains something like forward secrecy after a key compromise.

Unfortunately, my research has led me to doubt the possibility of recovery from such an attack. I submitted a report with my findings to Apple. They responded that my observations were “expected behavior”, and did not elaborate, so I remain unconvinced. I’ll detail what I’ve found, why I suspect it’s unsafe, and finally why I suspect someone else might be in a good position to produce some definitive proof whether this behavior is safe or unsafe1.

Intro to iCloud Advanced Data Protection

Advanced Data Protection (ADP) is Apple’s high-security iCloud mode that ensures that even Apple itself cannot read the data you store in iCloud. It is designed for use by high-risk individuals, like journalists, whistleblowers, political activists, etc. Apple’s documentation describes that it works like this:

  • Even under normal security (with ADP off), the vast majority of the content stored in iCloud is encrypted. [See: Page 113 of the Platform Security Guide PDF linked above]
  • The keys for this encryption are documented to be maintained in a tree hierarchy, rooted in a single key per CloudKit “service” (i.e. Photos/iCloud Drive/etc.), called the service key in documentation. [Page 114]
  • In normal security, Apple stores these service keys in iCloud so it can help you recover data. [Page 115]
  • With ADP enabled, Apple no longer stores copies of these keys. Instead, the user’s devices are responsible for maintaining the sole copy2 of each of the Service Keys in iCloud Keychain. [Page 115]
  • During iCloud sign-in on new devices, users go through a pairing process which adds the new device to a list of trusted devices for iCloud Keychain. [Page 130]
  • This is a slight simplification, but basically the iCloud Keychain encrypts each item stored in the keychain with a public key for each of the other devices in the trusted devices list. Each individual trusted device decrypts item updates from other devices to maintain a shared keychain. [Page 130]
  • The documentation states when ADP is enabled3 “…the device begins an asynchronous key rotation operation, which creates a new service key for each service whose key was previously available to Apple servers. After the service key rotation is successful, new data written to the service can’t be decrypted with the old service key. It’s protected with the new key which is controlled solely by the user’s trusted devices, and was never available to Apple.” [Page 116]

How I Expect Account Recovery With ADP To Work

The path for recovering an account’s security in this model seems simple. Content stored in iCloud at time of compromise must be considered compromised. However, after all compromised devices are removed from the iCloud Keychain’s trusted devices, rotating the service keys will ensure future content is encrypted with new keys unavailable to the attacker, and thus safe. (There is an added wrinkle around the the iCloud Keychain escrow mechanism, but we’ll put that aside for now.2)

So, how do we rotate those service keys? Well, the documentation indicates that the keys should rotate when ADP is enabled. Also, it seems like common sense that the keys should also rotate after the user goes through the recommended flow for an account compromise.

If Apple does not rotate the keys as they say they do after ADP is enabled, Apple could continue to access data for users that have ADP enabled. Furthermore, if the keys are not rotated after an account compromise, then an attacker who steals the keys once could persistently continue to access data from the iCloud account even after the user has tried to re-secure their account following the documented instructions.

Do The Keys Actually Rotate?

Not content to just trust the documentation, I set out to try to verify that it actually works. I relied on Apple’s open source releases and available tooling like ckksctl so that I could poke around iCloud’s internals without much difficulty.

My best guess based on my own sleuthing and prior work by other researchers is that what the documentation calls “Service Keys” in the documentation are actually called “CloudKit Keychain Service Top-Level Keys”, or “CKKS TLKs” in Apple’s source code and utilities. You can see monitor the current status of all CKKS TLKs using the ckksctl command line utility4. You can also inspect their storage in iCloud Keychain by opening Keychain Access on macOS.5

I tried two paths to try and get my TLKs to rotate.

The first thing I tried was to simply toggle ADP on and off, and to watch to see if the keys change in ckksctl or Keychain Access. I tried multiple times on multiple accounts and never witnessed a rotation.

The second thing I tried was to reset my iCloud password. Although the iCloud password is not specifically tied to the TLKs, this is what the Apple documentation says to do in the event of an account compromise. I used the “Reset Password” path where I selected that I needed to reset my password because I thought someone had hacked my account.

Neither of these methods produced an change in the TLKs visible via Keychain Access or ckksctl. Thus, I assume the keys did not rotate.

Conclusion: Something Smells Funny To Me

I need to be clear about the limits of my findings: I cannot say for certain that this represents a security vulnerability in iCloud ADP. It is possible that I am misinterpreting the output of Apple’s undocumented ckksctl tool or that there is some other undocumented mechanism to ensure security.

I think that this warrants further investigation. The next step I would take in an investigation is to do something like this:

  1. Record the upload of the service TLKs to Apple,
  2. Enable ADP on the iCloud account under test
  3. Wait some time, as Apple specifies the rotation to be asynchronous
  4. Create some new content (e.g. a new note) and let it be synced to iCloud
  5. Fetch the ciphertext of the note from iCloud
  6. Try to use the earlier captured TLK to decrypt the key hierarchy and then ultimately the note.

I think that if this path can be done successfully, it would clearly show a vulnerability in the iCloud ADP scheme.

Unfortunately, as far as I can tell, it would take substantial time and resources for me to develop all the supporting tooling needed to carry out this test. It would basically involve re-implementing a large part of the iCloud client.

I know that some people have already done this work, so it probably does not make sense for me to duplicate it. In particular, there is at least one data forensics firm that sells proprietary tools to law enforcement to do almost exactly this task.

That is why I am now disclosing my findings publicly. If iCloud really does not rotate the service keys, this is a real security flaw presents a risk to users. I think this public disclosure gives the best chance of another researcher who does have access to the supporting tooling to see my findings. Hopefully they further investigate and validate or disprove my findings. Furthermore, if it is a real problem, it is likely that some attackers have already noticed. After all, iCloud is a popular, high profile target, and this is would be a relatively simple flaw to exploit.

If anyone does double check my work and come to a definitive conclusion, please reach out at x at g1a55er dot net.

Appendix: My Vulnerability Report to Apple

For full transparency, I have included my vulnerability report I sent to Apple. I submitted this report to Apple’s Security Research report portal on August 30, 2023. It was assigned report identifier OE1953209343515.

# Affected platform
Apple Devices and Software

# Affected area

# Title
iCloud CKKS TLKs Not Rotating After Enabling ADP

# What is required to reproduce the issue?

1. An Apple ID. (I used the test account "adp-rotation-test@g1a55er.net")
2. A Mac running macOS 13.1 or newer. I used a Mac Mini (M1, 2020) running macOS 13.5

# Summary 
According to page 116 of the the Apple Platform Security document, the user's iCloud service keys should rotate after each time the Advanced Data Protection (ADP) setting is enabled. 

I interpret this to concretely mean that the new CKKS TLKs should be generated after ADP enablement. I do not observe this rotation happening after I turn ADP on via Keychain Access or via the `/usr/sbin/ckksctl` utility. 

My concern is that if my finding is correct, this would mean that the encryption keys that Apple claims would have never been available to Apple under Advanced Data Protection might actually have been recorded by Apple. Furthermore, I am concerned that if there is no way to rotate these keys, it is impossible to recovery forward secrecy once an iCloud account including the keychain has been breached by an attacker. 

#### Steps to reproduce
1. Sign in to the Mac with an Apple ID. In my test environment, this Mac was the only trusted device on the account, as to rule out cross device syncing as a source of the problem. 
2. Record the output of `/usr/sbin/ckksctl status` as well as the contents and modification timings of the records of kind `tlk` in Keychain Access. Note that to see the `tlk` records in Keychain Access you must enable "Show Invisible Items" in the "View" menubar menu, and you must search in the iCloud Keychain. 
3. Enable Advanced Data Protection via System Settings
4. Again record the output of `/usr/sbin/ckksctl status` as well as the contents of the `tlk` items in Keychain Access. 

# Expected results

- `/usr/sbin/ckksctl status` should indicate that new TLKs are in use for each of the services, and that the `lastNewTLKOperation` occurred recently.  
- Keychain Access should indicate that the `tlk` items have changed via inspecting their UUID names, their contents, and their modification times. 

# Actual results

- `/usr/sbin/ckksctl status` indicates that the same TLKs are in use after ADP is enabled as were in use before ADP was enabled. It indicates that `lastNewTLKOperation` was "never", although note I believe this actually this simply means the `lastNewTLKOperation` has not occurred since the start of securityd. 
- Keychain Access indicates that `tlk` items have not been modified in some time, and their names and contents match what they were before ADP was enabled. 

The documentation states that the rotation is "asynchronous", so I also repeated these tests after waiting 24 hours with the same results. 

# Implications 

My current understanding is that the CKKS TLKs are the highest root of the key hierarchy used for the iCloud service data encryption, and that these are the keys that are stored in the "available-after-authentication" hardware security modules (HSMs) under standard iCloud security protocols. I have come to this understanding after reading the Apple Platform Security document, source code released by Apple as part of its open-source contributions, and the work of other security researchers. Nonetheless, Apple has not elaborated publicly on this point explicitly, so I cannot be 100% certain. 

If this is true, and the TLKs are the highest level of the hierarchy, then the failure to rotate these keys after ADP is turned on represents a failure to deliver on the security properties promised by Apple for Advanced Data Protection, and would clearly allow an attacker who obtains the service keys before ADP was enabled (e.g. by taking it from the HSMs) to continue to steal new, fresh data uploaded to iCloud after ADP is enabled. 

If this is false, and the TLKs are only a middle level of the key hierarchy, it still may pose a security problem that these keys are not rotated. In particular, it would mean that it would be impossible to recover to full security after an iCloud account's Keychain was compromised by an attacker. The attacker might be able to still use previously stolen TLKs to continue to decrypt the victim's data after the victim changes their iCloud password and removes all trusted devices as recommended by Apple's documentation. This is because the new trusted devices signing in with the new iCloud password would still use the old TLKs for CKKS and thus Protected Cloud Storage objects. I additionally tested the password reset flow where I indicated that I believed my account was compromised to test this attack, and this flow also did not result in TLK rotation. 

# Coordinated Disclosure Timing
If I do not hear back by September 14th indicating that this report represents a genuine vulnerability and that Apple intends to make a fix, I will assume that Apple is not treating this as a vulnerability and might publicly disclose my research so far so that I may better collaborate with other researchers. 

If this is as a genuine vulnerability, I generally abide by Google Project Zero's industry standard disclosure timing guidance. 

I thank you for your time and diligence in investigating this report. As someone who handled some vulnerability disclosure reports in my previous day job, I sincerely apologize if I am misunderstanding some part of this system and have produced an erroneous "noise" report. 

Thank you again for your time, 

- g1a55er
  1. I am fully aware of Betteridge’s law of headlines. I am attempting to subvert it in my corner of the Internet. When I write a headline that ends with a question mark, it means that I am actually unsure what the answer is. In this case, I am unsure whether or not this behavior can be exploited, and am open to be persuaded in either direction. 

  2. There’s also an escrow mechanism for easier iCloud Keychain recovery. It’s described on page 131 and 132 of the Apple Platform Security documentation. It’s fairly complicated - it presents the user with a lot of options with various non-obvious trade-offs. So, I’d like to postpone discussing it at length until I can dedicate time to it justice in its own post. For the purposes of this post, I’ll just assume I have a reliable way of rotating this escrow record on demand, or that the threat model does not demand rotation of the escrow record to restore security.  2

  3. One thing I considered is that Apple might for some reason only do this when ADP is first enabled, but that does not make any sense for two reasons. The first is that I also tested freshly enabling ADP on a new account for the first time and did not see TLK rotation. The second is that if you disable ADP, according to page 117 of the Apple Platform Security documentation, your device re-uploads the service keys to Apple. So to fulfill the promise that Apple never had access to your keys, it must rotate them each time ADP is toggled. 

  4. I compared the UUIDs shown in the the “Current TLK”, “Current ClassA”, and “Current ClassC” fields shown for each service in the output of the ckksctl show command. I assume the “Current TLK” field is for the Top Level Key for that service, and then the ClassA and ClassC keys are the complete protection and “protected until first user authentication” protection levels documented here

  5. To see the TLK items in Keychain Access, make sure you have the “View” -> “Show Invisible Items” option enabled, and then search for “tlk” while selecting the iCloud Keychain in the left sidebar.