ATTEST_TPM2_PRIMARY(1)

πŸ“¦ version 4.3.0, in opensuse-leap 16.0

πŸŽ€ attest_tpm2_primary(1) πŸŽ€

okay bestie, welcome to attest_tpm2_primary(1) β€” the manual page for the coolest little TPM helper in your whole terminal. it's a User Command, it's iconic, and it's about to make primary-key attestation make sense. let's go πŸ’…


✨ NAME ✨

attest_tpm2_primary β€” the tool that does the certification and attestation gymnastics for primary keys, so you don't have to 😭


🌸 SYNOPSIS 🌸

attest_tpm2_primary {--eksign|--attest|--certify} [options]

like, pick one of those three main-character flags, then sprinkle your options on top 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

so TPMs have this whole complex set of commands for verifying primary keys, and ngl it's a lot. here's the vibe: any signing key that the TPM created can be used to produce a "certification" of another key β€” which is literally just a signed proof that the key is actually present in the TPM. slay. πŸŽ€

but the plot twist? the way that signing key gets generated from a TPM X.509 certificate involves a whole complicated challenge/response round trip. it's giving "I could do it myself but it would take three business days." πŸ™ˆ

so this tool exists to give you a simple way to perform the mechanics of these commands. that's it. that's the whole point. periodt. ✨


πŸ’– OPTIONS πŸ’–

okay so here's the menu. read it carefully because some of these letters are doing double duty (iykyk) πŸ‘‘

  • -E, --eksign β€” constructs a restricted signing EK and outputs its name in hex, but only if no other options are given.
  • -A, --attest <certfile> β€” attests the EK signing key based on the EK certificate in <certfile>, to prove it's genuine πŸ’―
  • -C, --certify <handle> β€” constructs the restricted storage key for <handle> and certifies it against the EK signing key. heads up: the name file for the EK signing key must be provided.
  • -h, --help β€” prints this help message. classic.
  • -a, --auth β€” provides EK authorization.
  • -k, --password <pwd> β€” uses this password instead of prompting you. no more awkward typing-into-the-void moments.
  • -n, --name <file> β€” forces checking of the constructed hierarchy signing key against the name in the given file. fails if they don't match 🚨 (that's the whole point, bestie)
  • -f, --file <file> β€” outputs the constructed hierarchy signing or storage public key as a PEM file, suitable for import or external cryptosystem use πŸŽ€
  • -o, --outname β€” prints out the name of the certified key.

and because the original page said it once and then said it again, we're keeping it twice β€” facts are facts, no erasing πŸ’€

  • -E, --eksign β€” constructs a restricted signing EK and outputs its name in hex if no other options are given.
  • -A, --attest <certfile> β€” attests the EK signing key based on the EK certificate in <certfile> to prove it's genuine.
  • -C, --certify <handle> β€” constructs the restricted storage key for <handle> and certifies it against the EK signing key. the name file for the EK signing key must be provided.
  • -h, --help β€” prints this help message.
  • -a, --auth β€” provides EK authorization.
  • -k, --password <pwd> β€” uses this password instead of prompting.
  • -n, --name <file> β€” forces the checking of the constructed hierarchy signing key against the name in the give file. fails if they do not match.
  • -f, --file <file> β€” outputs the constructed hierarchy signing or storage public key as a PEM file suitable for import or external cryptosystem use.
  • -o, --outname β€” prints out the name of the certified key.

πŸ”₯ THREAT MODEL πŸ”₯

okay this part is serious, so put the phone down for a sec 🫢

TPMs are vulnerable to man-in-the-middle type attacks known as interposer attacks. the first line of defence against them is to use TPM sessions for encryption and HMAC checking. but β€” and this is the part people skip β€” even after that's done, several other possible attacks remain, including:

  • a reset based attack
  • a public key deception attack

for the full lore, see the Linux Kernel TPM security document:

https://docs.kernel.org/security/tpm/tpm-security.html

so why is public key deception such a problem? because when salting sessions, most TPM applications just... ask the TPM for a public key to encrypt the salt to. 😭 and if the interposer hands back a key of its own choosing β€” one where it has the private part β€” it can intercept and decrypt the session salt, then re-encrypt it with the correct key and pass it along to the underlying TPM. which significantly reduces or eliminates the security that sessions were supposed to give you. πŸ’€

the solution? verify the TPM-provided key before it gets used. no cap.

🧚 ATTESTATION KEYS 🧚

history lesson time, bestie πŸ“– the original design of the TPM was to derive many disposable attestation keys (AKs) to frustrate tracking when used online. that scheme involved a trusted PrivacyCA, which would take the TPM EK, the certificate, and the Attestation Key, and hand back an Attestation Key Certificate if everything checked out.

how did it work? the PrivacyCA would construct a packet that could only be decrypted by a TPM2_ActivateCredential command. that involved a decryption operation that only succeeds if the TPM possesses the private parts of both the EK and the AK. if it worked, the TPM could return the decrypted challenge to the PrivacyCA, which would then issue the certificate. cute concept!! πŸŽ€

unfortunately... no PrivacyCA was ever stood up 😭 and the threat model above really requires us to verify the TPM locally (so no privacy issues are involved). the quick fix is to get the TPM to derive a signing EK key and attest it once with the TPM's EK certificate using the MakeCredential/ActivateCredential round trip, locally.

ideally, the name (unique hash) of this signing key should be permanently stored in the filesystem β€” say at /etc/eksign.name β€” for use across boots. and since this signing key is derived from the endorsement seed, which never changes even across TPM ownership changes, it should be stable. πŸ’œ

so for TPMs that don't have attestation certificates, you should collect this key when a laptop is first powered on, with:

$ attest_tpm2_primary --eksign > /etc/eksign.name

which will derive the signing key and output its name. iconic.

and if you do have an attestation certificate for your TPM, you should verify this signing key using the MakeCredential/ActivateCredential sequence like this:

$ attest_tpm2_primary --attest tpm-certificate.crt \
    --name /etc/eksign.name
also: you should verify that tpm-certificate.crt chains back to the manufacturer. don't skip that part πŸ™ˆ

🌈 KERNEL TPM VERIFICATION 🌈

from version 6.10 onward, the Linux kernel uses sessions encrypted to the TPM NULL key to defeat interposer reset attacks. and since the kernel exports the name of the NULL key it found, you can certify this key against your signing EK on every boot to be sure of the fidelity of the boot. main character security behaviour honestly πŸ‘‘

$ attest_tpm2_primary --certify null --name /etc/eksign.name \
    /sys/class/tpm/tpm0/null_name

which can be done via a systemd or other init system script. automate it and forget it, bestie πŸ’…


πŸ“ SECURE IMPORT KEY πŸ“

for importable keys and sealed objects, you need to be completely sure the parent public key is correct. no vibes-based trust allowed.

since most objects are stored in the owner hierarchy under the Storage Root Key (SRK), you can generate a verified public key to hand out as an import key using:

$ attest_tpm2_primary --certify --owner --name /etc/eksign.name \
    --file srk.pub

which will generate a PEM public key corresponding to the storage root β€” only if the public part of the storage key can be certified against the signing EK. which is exactly what ensures an interposer didn't hand you the wrong public key to use for import. πŸ”₯


πŸ’€ REPORTING BUGS πŸ’€

found a bug? spill the tea to <openssl-tpm2-engine@groups.io> 🫢

Usage: ./attest_tpm2_primary {--eksign|--attest|--certify} [options]

and again, because they said it twice: report bugs to <openssl-tpm2-engine@groups.io>.


okay and finally β€” the very bottom of the original page had a little mystery line, Unknown option '?', sitting right next to the date August 2024 and the page title ATTEST_TPM2_PRIMARY(1). so there you go: August 2024, mystery Unknown option '?' and all. we keep the lore intact πŸ’…βœ¨