Two mechanisms make the push path safe. The first is a sealed box that hides a wake token at rest and makes two tokens for the same device look unrelated. The second is an attestation (a signed proof of what code is running) that the client checks before it will hand a sealed token to anyone. This is the concrete construction of both, and an honest accounting of which half is hardware and which is, for now, software.
This is the algorithm behind Waking a Sleeping Phone. Read that first for why; this is the how.
To wake Bob's phone, someone eventually presents Bob's Apple device token (the identifier Apple issues so a server can send push notifications to one specific handset) to APNs, Apple's push notification service. That device token is the crown jewel. It links to a physical phone and a person, so it must be:
The first two are the sealed box; the third is the attestation.
The wake token is sealed with a hybrid key-encapsulation mechanism (KEM) called X-Wing. It combines the lattice KEM ML-KEM-768 (a standardized scheme built to resist quantum computers) with classical X25519, the elliptic-curve scheme in wide use today. The two independent schemes run together, so an attacker has to break both.
A KEM is the modern shape of public-key encryption. Instead of "encrypt this message under a public key," you encapsulate: you run the public key to produce two things at once: a fresh random shared secret, and a ciphertext that lets the holder of the private key recover that same secret. You then use the shared secret with a symmetric cipher (one where the same key locks and unlocks) to seal the actual payload.
The sealing, per stored row, is:
(shared_secret, kem_ct) ← X-Wing.Encap(pk_seal).
Because encapsulation draws fresh randomness every time, kem_ct and the resulting key
are different for every row: even sealing the same device token twice yields two
unrelated-looking blobs. This is what buys unlinkability at rest.aead_key ← HKDF-SHA256(shared_secret). HKDF is a key-derivation
function, which grinds a raw shared secret into a uniform symmetric key of the size the
cipher wants.aead_key with a fresh nonce (a number used once, so the same key never
encrypts the same way twice) produces the ciphertext ct.The stored blob is the concatenation kem_ct ‖ nonce ‖ ct: roughly 1120 ‖ 12 ‖ … bytes,
the 1120 being X-Wing's ciphertext (the ‖ symbol just means "glued end to end"). push-svc holds a pile of these and can open none of
them, because it has no private seal key. push-sender, which holds the private key, does the reverse
(X-Wing.Decap to recover the secret, then HKDF, then AEAD-open) for exactly one row, in memory, then
forgets.
A note for the careful reader: this is not HPKE. HPKE (RFC 9180) is the standard "seal a message to a public key" construction, and it would be the natural thing to reach for. But it has no standardized post-quantum hybrid mode we wanted to depend on. So the push seal is a purpose-built X-Wing sealed box with the same shape as HPKE (encapsulate → HKDF → AEAD) but its own post-quantum hybrid KEM. If you read the code expecting RFC 9180, you will not find it; the analogy is conceptual, the bytes are ours.
The sealed box protects the token from the registry. It does nothing against a malicious operator who simply publishes their own seal key and collects readable wake tokens sealed to it. Stopping that is the attestation's job. Before the client seals anything, it must be able to verify that a seal public key really lives inside the expected, measured software and not in an attacker's pocket.
So a seal key is never presented bare. It comes with a signed attestation over a canonical preimage (the exact, agreed byte string the signature covers):
preimage = tag ‖ alg ‖ measurement ‖ pk_seal ‖ timestamp ‖ nonce
tag: domain separation, a fixed label saying what kind of signature this is, so a
push-seal attestation can never be confused with some other signed blob,alg: which attestation algorithm/root produced it,measurement: the identity of the code holding the key. Under a hardware root this is a
real platform measurement of the running image; under today's software attester it is a hash
of a declared build identifier, so it names a build rather than measuring one (see §4),pk_seal: the seal public key being attested,timestamp + nonce: freshness (the nonce is a one-time random value), so an old
attestation can't be replayed forever.The client verifies this fail-closed: when anything is in doubt, it refuses rather than
proceeds. It checks the signature against a pinned root: a
verification key compiled into the app itself, so the relay cannot substitute one of its own. It
checks that the measurement matches the expected image. It checks freshness. If anything is
off, or the attestation is simply absent, it refuses to seal and the wake is not set up.
There is no "unverified fallback." A relay that cannot prove its sender is the real sender
gets no wake tokens.
The picture is a bonded courier. The sealed tube protects the note from everyone; the courier's bonded badge (which you inspect against a registry you trust, before you hand over the tube) protects you from handing your note to an impostor courier.
Here is where we refuse to overclaim, exactly as Waking a Sleeping Phone warned.
Shipped and tested: the sealed box, the per-row unlinkability, the attestation format, the client's fail-closed verification (pinned root, pinned measurement, freshness) and a software attester signing with an Ed25519 key (a widely used digital-signature scheme), with end-to-end tests across the whole path. Those parts are real and enforced: a release build genuinely refuses to seal against anything that does not verify.
The precision worth adding is about what is being attested. The software attester's measurement is a hash of a build identifier the operator supplies, and the signing key is held by that same operator.
So today's document binds an honest operator to a named build: it is a commitment, checkable against what they said they deployed, and it fails closed if they stop making it. What it is not is a measurement of the code that is actually running. It therefore does not constrain a compelled operator (one forced, say by a legal order, to misbehave) who can name one build and run another.
A marked, unshipped seam: the hardware root. (A seam, here, is a deliberate joint in
the code where a future piece will slot in.) The design's destination is an attestation
rooted in a real trusted execution environment: a
sealed-off compartment of a server that even the server's operator cannot look inside. Concretely,
that means an AWS Nitro
Enclave, whose attestation is an ECDSA-P384 (elliptic-curve signature) document signed by
the CPU platform itself, not by our own software. Rooted there, the seal key becomes non-exportable even by
the operator running the machine. That provider is present in the code as an explicit seam
and it fails loud: ask the verifier to accept a
hardware-rooted (Nitro) attestation today and it throws "provider unavailable"; ask
push-sender to boot in Nitro mode and it refuses. Nothing silently degrades: the hardware path
is wired for, and visibly not yet on.
So the precise statement is: the attestation format, the pinning and the fail-closed client are real and enforced; what a hardware root would add is that the measurement stops being a claim and starts being an observation, and that the key becomes non-exfiltratable even by the operator. That is the remaining work, cleanly seamed.
And, as always, even a perfect enclave leaves Apple as the disclosed floor for the wake event itself.