9

I would like to list the information stored on a TPM chip, by type, just to see that all relevant data was migrated to a new machine before clearing the TPM chip of the old machine.

I am not looking for dumping private keys, etc., just a list of IDs and uses (E.g. Bitlocker encryption keys, Virtual Smart card, etc.). Is this possible in any way in Windows and/or in Linux?

I have both dTPM and fTPM configurations.

Giacomo1968
  • 58,727
TFuto
  • 222

2 Answers2

14

It's impossible to have a complete listing, because such data is not actually stored on the chip at all. A TPM actually has very little persistent storage – Windows only stores a single "Storage Root Key" in it (aka the SRK), everything else is encrypted using the SRK and returned to the OS for storage.

This means that the TPM is completely unaware of what has been deleted and what's still stored in a file somewhere. (It also means the TPM can never "fill up", unlike smartcards.)

  • For example, BitLocker "TPM" protectors are still stored within the volume header, only encrypted using TPM_Seal() or TPM2_Create() with a policy attached. Every time the protector needs to be unsealed, the OS has to load it back into the TPM's RAM, where the TPM decrypts it with the SRK, verifies the policy (comparing the PCR values if needed), then either returns the clear data to the OS or refuses.

    So you can't list all BitLocker volumes that use a specific TPM because that information isn't tracked anywhere. (Fortunately, Windows only uses the TPM protectors for the OS C:\ volume, so you can safely rule out all "data" volumes.)

    LUKS in Linux uses the same approach, although only recently was the LUKS2 token format "agreed upon" – in the past various hand-rolled scripts were used, some of which might have stored the sealed data directly in the TPM's NV storage. However, with systemd and cryptsetup now having TPM support as a standard feature, the sealed keyslot is always written back to the LUKS2 on-disk header.

    (Here's an example of how a LUKS key is sealed using TPM 2.0. The piece of JSON with "tpm2-blob" is what holds the TPM-sealed data.)

  • Similarly, Certificate keypairs that are kept "in" the TPM (through the "Platform Crypto Provider" KSP) are actually stored in %USERPROFILE%\AppData\Local\Microsoft\Crypto\PCPKSP, within your own profile for keys created directly through CAPI/CNG, or within the LocalService profile for keys stored in VSC.

    (That's only the private keys – unlike with smartcards, certificates themselves never touch the TPM in the first place. When using a VSC they're stored in the VSC's "emulated smartcard" storage, which appears to be at %SYSTEMROOT%\ServiceProfiles\LocalService\AppData\Local\Microsoft\Windows\SmartCard\Tpm, and when using direct CNG they go wherever all other certificates go.)

    You can use certutil to get a list of all your certificates in CAPI together with the KSP that they use – look for either "Microsoft Platform Crypto Provider" (direct CNG) or "Microsoft Smart Card Provider" (VSC) to recognize such certificates:

    certutil -store -silent -user My
    

    There's no direct Linux equivalent because there's no CAPI/CNG equivalent on Linux in the first place – programs could use tpm2-pkcs11 (which stores certificates in a SQLite database), or .pem keys generated using openssl-tpm2-engine (which are just files scattered wherever), or even directly use tpm2-tss APIs.

That being said, TPM 2.0 does have some persistent storage, and as unlikely as it is that it'll have been used directly, you could use Linux tpm2-tools to try listing the contents:

  • There's usually space for 3 or so keypairs, which can be listed using tpm2_getcap handles-persistent (applying tpm2_readpublic -c <handle> to each of the shown handles in turn). Typically, only the RSA-based "storage root key" (for encrypting data) and the "endorsement key" (for identifying the TPM itself) are stored there – and the latter doesn't get reset through a TPM clear anyway.

    The handle 0x81000001 is most commonly used for the RSA-based SRK, 0x81010001 for the RSA-based EK. Sometimes you might see 0x81000000 on Linux if an older version of the tpm2-pkcs11 tool has been used.

    (Systemd LUKS support uses an ECDSA-based SRK and doesn't bother storing it persistently – just regenerates it from the "storage hierarchy seed" every time.)

  • There's also some amount of generic "NV storage" space, which can be listed using tpm2_getcap handles-nv-index and tpm2_nvread. In most cases it only contains some manufacturer predefined data, such as the EK certificate (at 0x01C00002). Since there are no names for anything, you have to basically guess – assuming the NV index in question was made readable in the first place.

AJM
  • 500
grawity
  • 501,077
2

This is not possible, and in fact is contrary to the purpose of the TPM in being a safe and inviolate repository.

The Microsoft article of Trusted Platform Module lists the PowerShell commands used for managing the TPM:

  • Clear-Tpm : Resets a TPM to its default state.
  • ConvertTo-TpmOwnerAuth : Creates a TPM owner authorization value from a supplied string.
  • Disable-TpmAutoProvisioning : Disables TPM auto-provisioning.
  • Enable-TpmAutoProvisioning : Enables TPM auto-provisioning.
  • Get-Tpm : Gets an object that contains information about a TPM.
  • Get-TpmEndorsementKeyInfo : Gets information about the endorsement key and certificates of the TPM.
  • Get-TpmSupportedFeature : Verifies whether a TPM supports specified features.
  • Import-TpmOwnerAuth : Imports a TPM owner authorization value to the registry.
  • Initialize-Tpm : Performs part of the provisioning process for a TPM.
  • Set-TpmOwnerAuth : Changes the TPM owner authorization value.
  • Unblock-Tpm : Resets a TPM lockout.

As you can see, one can manage the TPM itself as an object, but not its contents.

AJM
  • 500
harrymc
  • 498,455