808bits

TPM 2.0 playground

2026-09-01 · 6 min

There is a TPM in almost every machine you own, and almost nobody has ever seen one work. It sits on a bus, speaks a terse binary protocol, and the literature about it is a 1,500 page specification. This page puts one on your desk. No silicon: the hardware is simulated. The code is not. What runs here is ms-tpm-20-ref, Microsoft’s TPM 2.0 reference implementation, the codebase the TCG specification itself is generated from, compiled to WebAssembly. Same wire format, same state machine, same behavior the spec demands of the chip in your laptop.

bootingfetching tpm2.wasm

pcr bank · sha-256

lifetime

powered this boot
powered ever
resets survived
manufacturer
firmware

non-volatile memory

NV image
persistence
counter
01 · meet the tpm

Straight from the DRBG. Seeded by this browser, stirred by the TPM.

The TPM computes SHA-256 of your text. Compare it with sha256sum.

A TPM counts its own lifetime and remembers every reset. Reload the page and check.

Power-cycle the TPM, then talk to it before TPM2_Startup. It refuses everything until the ritual is observed.

02 · the logbook

Platform Configuration Registers: the TPM’s tamper-evident logbook.

new = SHA-256(old ‖ SHA-256(your text)). This is measured boot, and it cannot be undone.

Software below the firmware is not allowed to erase the log. Watch it refuse.

03 · keys that never leave

The TPM generates a P-256 key and signs your message. Then this page verifies the signature with WebCrypto. The private key never crosses the wire: check the bytes.

04 · seal a secret to a boot state

This is BitLocker in four clicks: seal a secret to the current boot measurements, then break the boot and watch the secret become unreachable.

05 · a number that only goes up

An 8-byte monotonic counter in real NV. It survives power cycles and page reloads, and no command can decrement it: rollback protection in its purest form.

raw console

No seatbelt. The TPM’s parser will tell you exactly what it disliked.

the wire · hover a field to light up its bytes
tag sizes command code handles authorization parameters

Nothing you do here leaves the page: no server, no analytics, no network request carrying your input anywhere. The page fetches one wasm file and goes quiet; the TPM’s NV memory and your sealed blobs persist only in this browser’s localStorage. You can verify all of that in your browser’s developer tools.

What you are looking at

The right pane is the wire. Every command you send appears as two lanes of bytes, host to TPM and TPM to host, with each field colored like a logic analyzer channel: structure tags, sizes, the command code, handles, authorization areas, parameters. Hover any field and its row in the field-by-field table lights up, and the other way around. This is the fastest way there is to internalize a binary protocol, and TPM 2.0 is a beautiful one to learn: strict, type-tagged, and unforgiving.

The commands on the left are arranged as five small demonstrations, each proving one claim about what a TPM is for.

Meet the TPM is the warm-up. Draw bytes from the DRBG, hash text inside the TPM and check the digest against your own sha256sum, read the TPM’s private clock, which counts its lifetime and its deaths. Then break the rules: talk to it before TPM2_Startup and watch every command bounce off TPM_RC_INITIALIZE.

The logbook is the PCRs, the registers behind measured boot. Extending one folds your data into it irreversibly, new value = SHA-256(old value concatenated with your digest), and there is no command that writes a PCR directly. Try to reset PCR 7 and the TPM answers TPM_RC_LOCALITY: software running after boot is not allowed to erase the boot log, because if it could, the log would prove nothing.

Keys that never leave generates a P-256 signing key inside the TPM and signs a message you type. Then the page itself verifies that signature with WebCrypto, using only the public point from the response. Scroll the bytes afterwards. The private key appears nowhere, because it never existed outside the TPM.

Seal a secret to a boot state is the centerpiece, and it is BitLocker in four clicks. Seal a secret bound to PCR 7 exactly as it reads now. Unseal it and get it back. Then do what a tampered bootloader would do, extend PCR 7, and try again: TPM_RC_POLICY_FAIL, permanently, because extends are one-way. If a BIOS update has ever made your laptop demand its recovery key, this is precisely what happened. The sealed blob itself lands in your localStorage, outside the TPM, which is authentic: real systems keep sealed blobs on disk, and only the seed that unwraps them lives in the chip. Reload the page and the story resumes at step 2, because the TPM re-derives the identical parent key from the seed in its NV memory.

A number that only goes up defines a monotonic counter in real NV. Increment it, power cycle, read it back. No command can decrement it. That one property, held even against the machine’s owner, is what rollback protection is built from.

What is real and what is not

The command parser, the state machine, the crypto, the policy engine, the NV subsystem and every response code are the genuine reference code. What a real chip adds is a hardware boundary: tamper-resistant silicon, its own entropy source, and the guarantee that nobody can read the seed out. Here the “hardware” is your browser tab. The DRBG seeds from crypto.getRandomValues, NV memory is a 16 KiB byte array persisted to localStorage, and the whole TPM dies when you close the tab, except for what NV remembers. That trade is the honest one for learning: the bytes behave exactly like the datasheet says, and you can watch them do it.

How it is built

The reference implementation is C, about 250 files of it, compiled to wasm32-wasi with zig as the entire toolchain, wolfSSL underneath for the crypto primitives. Porting it surfaced a small class of bugs that x86 silently forgives and WebAssembly’s typed indirect calls do not, which will get its own write-up. The page you are reading loads one wasm module of about 270 KB and one script, and makes no other network request. Everything you type, seal, or sign stays in this tab.