Activating after death
Activating after death
So... we found the issue that resulted in the death of our DTK. I examined the logs I had access to, and recreate them on my own machines. I brought out what I knew about how activation works in Macs with Apple silicon, and applied it to help create a definitive answer on what the problem is. And now... my eyes are more open to what Stella was complaining about before.
Update on Dec. 21th, 2024
Recently, there has been speculation that this is just a side effect of Apple updating values server-side instead of intentionally trying to break DTKs. Regardless of is these turn out to be ture, two things are always going to be fact:
- Apple has done this intentionally, whether they chose to update the servers to break DTKs on purpose, or chose not to fix DTKs via ignorance.
- There is nothing we can currently do to fix the problem, other than monitor and hope that the servers just magically begin working again for the DTKs.
I'm not holding my breath, and have repurposed my old J316sAP (M1 Pro 16-inch) as the 2014 Mac mini and DTK's replacement. I also wrote a script to send off the DTK's ucrt request to Apple, since it should still be valid... in the event that something does change.
The ucrt problem
The issue stems from this funny little certificate called a ucrt. It helps Macs with Apple silicon sign their LocalPolicy files, which then help set the security standards (and other bits) for booting an operating system. The way a ucrt works is explained in the Apples Platform Security documentation, but I'll reiterate it here:
Macs with Apple silicon have an interesting architecture for booting and activation. Each loadable operating system requires a LocalPolicy, which is a set of keys and hashes that help define the security model of each operating system. This is why you can have a copy of macOS that's in Full Security with every little thing tight as a drum, and another copy that is wide open - Permissive Security, kernel r/w, etc - right alongside each other without interfering. Additionally, each LocalPolicy contains a RemotePolicy, which helps determine constraints that should be applied to LocalPolicies. Some of these constraints are set by Apple's servers to ensure security between multiple devices, but that's out of scope for this blog post.
To reiterate:
- LocalPolicies encompass the entire suite of security and boot settings for each operating system.
- RemotePolicies help clamp down what a given LocalPolicy is capable of doing, and what machines it runs on.
So if a LocalPolicy is required in order to boot any operating system, how does it work out of the box or directly after a restore?
At restore time, Macs will create a new pair of keys (and destroy any old ones that may still exist) and sign the recoveryOS LocalPolicy, since the authenticity of recoveryOS is verified at restore and boot time. A RemotePolicy is embedded in the recoveryOS LocalPolicy to also ensure that recoveryOS is always booting with the highest levels of security - a valid APTicket that was issued for that device, boot argument filtering, SSV, etc. This ensures that recoveryOS is always available after a restore or when other LocalPolicies are unbootable.
When recoveryOS loads and there are no activation records for the current device, it will try to contact Apple for help. This is where our friend named ucrt comes in. ucrt stands for User Identity Certificate, and it's used to help create LocalPolicies, and enforce RemotePolicy rules. This certificate is generated by first creating ActivationInfo with attestation from the Secure Enclave, which is then fed into ActivationInfoXML, and shipping this data off to tbsc.apple.com:443 - if all goes well, the ucrt will be returned and everything will work great. If there is an issue, such as the Mac being Activation Locked, then the server will not return a ucrt and the Mac may ask for the correct details or fail outright.
One final reiteration:
- Devices send
ActivationInfoXMLto Apple's servers in order to receive aucrt. ucrtis then used to help form the basis of LocalPolicy signatures and RemotePolicy enforcement.ucrtwill not be returned if the device cannot meet the requirements for successful activation.
The issue that the DTKs have now is shockingly simple to explain once this is all out of the way: Apple's server is outright refusing requests from DTKs, even if they meet the requirements to activate otherwise. Instead of returning a ucrt, Apple's servers are instead serving us a big fat bowl of Server error: 400 (bad request) when -[MobileActivationMacOSDaemon issueUCRT:withCompletionBlock:] is called - from my observations, this is in mobileactivationd, findmydeviced, and restored_external.
Without a ucrt, LocalPolicies cannot be created and activation routines cannot be completed. This is why perfectly valid serials and MAC addresses (like our DTK has) exhibit the same issues as ones with mismatched or invalid ones! In fact, it should just be the same issue altogether, albeit with different causes.
End of the line.
And so begins the condemning of our - and any other unactivated - DTK to rebooting to the same screen, with the same instructions to connect to the internet, and the same "Your Mac is activated." message... teasing us with success and greeting us with failure.
It's honestly decently hard to admit this is it for our unit, but it would be more hard, as well as delusional, to ignore that this was an intentional change: it only affects DTKs, and it has been happening since December 5th.
DTKs were never supposed to be used after Apple asked for them back, and having used one, I can understand why. They don't support all of what macOS Big Sur has to offer, the instruction set isn't up to spec, the firmware is barely production, and there were a lot of quirks about the SoC itself (like the three SMC batteries or lack of fan control) that made it inconvenient or just wrong for most.
When dosdude1 managed to source a few to fix, we were so excited about the potential. When we got ours, we immediately got to work - rigging up a custom USB-C PD powered solution and running it as a bare board, playing Minecraft on it and comparing to the A12Z iPad running the same version, poking around the firmware and looking towards future macOS versions, helping out with testing Linux, getting more and more apps to run...
It was an amazing tinker machine, and a sweet ass server too. I'm definitely going to miss that potential, but I feel better knowing that our DTK was sacrificed to save all of the others that are activated, at least...
...and it's helped me truly understand the reason I'm now typing on what was Stella's M1 Max. But that's for the next blog post.
Special thanks to the people who worked with me to pinpoint the issue: chenurn, dosdude1, and a few brains in the Hack Different Discord.
Rest in peace, DTK.
- Eva