EXTENDED PLAY
. . . but not how you'd expect
Seriously, PCRs are not involved
depth = 2, alg= sha256, num_blocks = 32767 [ root ] / . . . \ [entry_0] [entry_1] / . . . \ . . . \ [entry_0_0] . . . [entry_0_127] . . . . [entry_1_127] / ... \ / . . . \ / \ blk_0 ... blk_127 blk_16256 blk_16383 blk_32640 . . . blk_32767
The vault key is stored encrypted by a key wrapped as follows:
When the TPM is enabled, there is a system-wide cryptohome RSA key that is used during the encryption/decryption of these keys. The method when TPM is enabled:
UP - | + AES (no padding) => IEVKK - | | EVKK - | + RSA (in TPM) => VKK | | TPM_CHK - Where: UP - User Passkey EVKK - Encrypted vault keyset key (stored on disk) IEVKK - Intermediate vault keyset key TPM_CHK - TPM-wrapped system-wide Cryptohome Key VKK - Vault Keyset Key
The end result, the Vault Keyset Key (VKK), is an AES key that is used to decrypt the Vault Keyset, which holds the ecryptfs keys (filename encryption key and file encryption key). The User Passkey (UP) is used as an AES key to do an initial decrypt of the encrypted "tpm_key" field in the SerializedVaultKeyset (see vault_keyset.proto). This is done without padding as the decryption is done in-place and the resulting buffer is fed into an RSA decrypt on the TPM as the cipher text. That RSA decrypt uses the system-wide TPM-wrapped cryptohome key. In this manner, we can use a randomly-created system-wide key (the TPM has a limited number of key slots), but still require the user's passkey during the decryption phase. This also increases the brute-force cost of attacking the SerializedVaultKeyset offline as it means that the attacker would have to do a TPM cipher operation per password attempt (assuming that the wrapped key could not be recovered).
The VKK then wraps the final vault key:
VKK - | + AES (PKCS#5 padding + SHA1 verification) => VK | EVK - Where: EVK - Encrypted vault key (stored on disk) VKK - Vault Keyset Key