Remote attestation from thin air
Posted on 2026-05-24
Suppose you have a general-purpose microprocessor you can run arbitrary code on. How can you plausibly prove to a third party what code you're running on it (or more precisely: How can the code that's running on it prove that to somebody else)?
This is called remote attestation and realistically speaking, remote attestation is mostly used for boring things like DRM today. But there are useful applications too. In my case, I'm currently building an HSM-esque device (e.g. for my SSH CA) that is somewhat inspired by the Tillitis TKey in that it can run arbitrary code without losing its security guarantees (unlike the TKey it's based on Linux and a RP2350 coprocessor which has had extensive security research performed on it and is much more powerful than the PicoRV32 soft-core in the TKey. Also this design natively integrates binary transparency.).
A third party relying on remote attestation wants to be assured of two things:
- What code is running on a device
- Am I currently talking to this code or is somebody performing MitM?
For the purposes of the following discussion it is useful to distinguish between a few entities which may or may not end up being the same person in a given scenario:
M0: The manufacturer of the processor you're using. They are normally also in control of the immutable boot ROM in the chip and possibly other Root-of-Trust mechanisms that might be present in the chip. (e.g. Intel or Raspberry Pi Holdings plc)M1: The manufacturer of the device that integrates the processor. They might embed the processor in a larger system but crucially for this discussion, they can also program OTP in the processor for storing secrets or setting up verified boot mechanisms.U: The user of the device. Can run arbitrary code on it.V: The verifier. Wants to learn remotely what code is actually running on the device they're talking to.
The attestation problem is easy if U isn't able to run arbitrary code on the device: M1 just locks it down using verified boot (all of this hinges on M0 having built the hardware in a way that supports that, normally through signature verification/encryption support in the ROM bootloader), creates a per-device certificate and securely stores the private key on the device (e.g. by encrypting the storage, this is easy to bootstrap if the ROM bootloader supports an encrypted user-supplied second stage, for example). The device can now answer challenges using that certificate and V only needs to trust M1 (and M0), but not U.
However, this problem gets harder when you allow U to run arbitrary code on that system. Here, since V is talking to code provided by U (whom it doesn't trust, this is the whole point). Even if we have some mechanism in place that e.g. signs a statement about which code has been loaded into the system, how can V be certain it is actually talking to the system and not a third party MitM who is just replaying that statement?
Systems such as AMD SEV-SNP solve this with an active component provided by Mx (M0 in this case) that is out of reach of the user code and can respond to a challenge-response mechanism and provide a known-fresh attestation that way. TPM-based remote attestation works similarly (but has a bunch of practical problems, some general and some related to the specific way attestation works in TPMs).
But suppose M0 has neglected to add any such feature (this is often the case on regular embedded systems processors - you're lucky if you get verified boot and doubly so if it isn't fundamentally broken). There now is no runtime component V can rely on. What can M1 do to still provide a useful attestation mechanism?
Turns out there is a way to do this that only relies on two things being present and working:
- Secure storage that can be hidden from
Uexists. This is often the case for OTP banks which have a one-way flag to hide their contents until the next reset e.g. after a second-stage bootloader has processed them. - Verified boot (i.e.
M1can ensure only second-stage bootloaders signed by them can run on the device)
Both of these are fairly common (even if it often turns out that their security is broken, but this is something we have to deal with in any case).
Then, M1 can do the following:
- Give each device a signing key pair (e.g. Ed25519), called the attestation key here and store the secret key in secure storage (as described above)
- Sign a certificate (called the device certificate) over the public part of that key pair with a manufacturer key. Store that certificate on the device too.
- Set up verified boot such that only the manufacturer-provided second-stage bootloader can execute on the device (and thus is the only code that has access to the attestation key)
The second-stage bootloader then does the following on boot:
- Load and measure the user code it is loading (e.g. calculate a SHA256 hash over it)
- Create a fresh Ed25519 key pair (call it the runtime key)
- Use the attestation key to sign a certificate (called the attestation certificate) over the code measurement and the public part of the runtime key.
- Hand the device certificate, attestation certificate and private runtime key to the user code (e.g. put it in a well-known location in RAM)
- Lock access to the private part of the attestation key and execute the user code
The application can then use the two certificates to provide a chain of trust to V and prove that it is actually the party that this attestation covers by answering signature challenges against the runtime key.
This still doesn't prevent the attestations on malicious/buggy user code that has allowed exfiltration of this data in the past from being replayed. But the whole remote attestation idea hinges on V being able to correlate the attestation with something (i.e. the hash corresponds to an artifact reproducibly built from open source code), so they could know about and blacklist attestations for such bad versions of the code.
The active mechanisms described above fare better: They obviously take misbehaving (for whatever reason) user code out of the equation since it is not involved in the attestation process.
But if you don't have any hardware capabilities for those, this still is some improvement over not being able to do attestations at all. I haven't seen this implemented anywhere else and thought this might be a neat trick to let people know about.