diff options
Diffstat (limited to 'roms/skiboot/doc/secvar/secboot_tpm.rst')
-rw-r--r-- | roms/skiboot/doc/secvar/secboot_tpm.rst | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/roms/skiboot/doc/secvar/secboot_tpm.rst b/roms/skiboot/doc/secvar/secboot_tpm.rst new file mode 100644 index 000000000..8da0c2f01 --- /dev/null +++ b/roms/skiboot/doc/secvar/secboot_tpm.rst @@ -0,0 +1,175 @@ +.. _secvar/secboot_tpm: + +secboot_tpm secvar storage driver for P9 platforms +================================================== + +Overview +-------- + +This storage driver utilizes the SECBOOT PNOR partition and TPM NV space to +persist secure variables across reboots in a tamper-resistant manner. While +writes to PNOR cannot be completely prevented, writes CAN be prevented to TPM +NV. On the other hand, there is limited available space in TPM NV. + +Therefore, this driver uses both in conjunction: large variable data is written +to SECBOOT, and a hash of the variable data is stored in TPM NV. When the +variables are loaded from SECBOOT, this hash is recalculated and compared +against the value stored in the TPM. If they do not match, then the variables +must have been altered and are not loaded. + +See the following sections for more information on the internals of the driver. + + +Storage Layouts +--------------- + +At a high-level, there are a few major logical components: + + - (PNOR) Variable storage (split in half, active/staging) + - (PNOR) Update storage + - (TPM) Protected variable storage + - (TPM) Bank hashes & active bit + +Variable storage consists of two smaller banks, variable bank 0 and variable +bank 1. Either of the banks may be designated "active" by setting the active +bank bit to either 0 or 1, indicating that the corresponding bank is now +"active". The other bank is then considered "staging". See the "Persisting +Variable Bank Updates" for more on the active/staging bank logic. + +Protected variable storage is stored in ``VARS`` TPM NV index. Unlike the other +variable storage, there is only one bank due to limited storage space. See the +TPM NV Indices section for more. + + +Persisting the Variable Bank +---------------------------- + +When writing a new variable bank to storage, this is (roughly) the procedure the +driver will follow: + +1. write variables to the staging bank +2. calculate hash of the staging bank +3. store the staging bank hash in the TPM NV +4. flip the active bank bit + +This procedure ensures that the switch-over from the old variables to the +new variables is as atomic as possible. This should prevent any possible +issues caused by an interruption during the writing process, such as power loss. + +The bank hashes are a SHA256 hash calculated over the whole region of +storage space allocated to the bank, including unused storage. For consistency, +unused space is always written as zeroes. Like the active/staging variable +banks, there are also two corresponding active/staging bank hashes stored in +the TPM. + + +TPM NV Indices +-------------- + +The driver utilizes two TPM NV indices: + +.. code-block:: c + + # size). datadefine SECBOOT_TPMNV_VARS_INDEX 0x01c10190 + #define SECBOOT_TPMNV_CONTROL_INDEX 0x01c10191 + +The ``VARS`` index stores variables flagged with ``SECVAR_FLAG_PROTECTED``. +These variables are critical to the state of OS secure boot, and therefore +cannot be safely stored in the SECBOOT partition. This index is defined to be +1024 bytes in size, which is enough for the current implementation on P9. It +is kept small by default to preserve the very limited NV index space. + +The ``CONTROL`` index stores the bank hashes, and the bit to determine which +bank is active. See the Active/Staging Bank Swapping section for more. + +Both indices are defined on first boot with the same set of attributes. If the +indices are already defined but not in the expected state, (different +attributes, size, etc), then the driver will halt the boot. Asserting physical +presence will redefine the indices in the correct state. + + +Locking +------- + +PNOR cannot be locked, however the TPM can be. The TPM NV indices are double +protected via two locking mechanisms: + + - The driver's ``.lock()`` hook sends the ``TSS_NV_WriteLock`` TPM command. +This sets the ``WRITELOCKED`` attribute, which is cleared on the next +TPM reset. + + - The TPM NV indices are defined under the platform hierarchy. Skiboot will add +a global lock to all the NV indices under this hierarchy prior to loading a +kernel. This is also reset on the next TPM reset. + +NOTE: The TPM is only reset during a cold reboot. Fast reboots or kexecs will +NOT unlock the TPM. + + +Resetting Storage / Physical Presence +------------------------------------- + +In the case that secure boot/secvar has been rendered unusable, (for example: +corrupted data, lost/compromised private key, improperly defined NV indices, etc) +this storage driver responds to physical presence assertion as a last-resort +method to recover the system. + +Asserting physical presence undefines, and immediately redefines the TPM NV +indices. Defining the NV indices then causes a cascading set of reformats for +the remaining components of storage, similar to a first-boot scenario. + +This driver considers physical presence to be asserted if any of the following +device tree nodes are present in ``ibm,secureboot``: + - ``clear-os-keys`` + - ``clear-all-keys`` + - ``clear-mfg-keys`` + + +Storage Formats/Layouts +======================= + +SECBOOT (PNOR) +-------------- + +Partition Format: + - 8b secboot header + - 4b: u32. magic number, always 0x5053424b + - 1b: u8. version, always 1 + - 3b: unused padding + - 32k: secvars. variable bank 0 + - 32k: secvars. variable bank 1 + - 32k: secvars. update bank + +Variable Format (secvar): + - 8b: u64. key length + - 8b: u64. data size + - 1k: string. key + - (data size). data + +TPM VARS (NV) +------------- + +NV Index Format: + - 8b secboot header + - 4b: u32. magic number, always 0x5053424b + - 1b: u8. version, always 1 + - 3b: unused padding + - 1016b: packed secvars. protected variable storage + +Variable Format (packed secvar): + - 8b: u64. key length + - 8b: u64. data size + - (key length): string. key + - (data size). data + +TPM CONTROL (NV) +---------------- + + - 8b secboot header + - 4b: u32. magic number, always 0x5053424b + - 1b: u8. version, always 1 + - 3b: unused padding + - 1b: u8. active bit, 0 or 1 + - 32b: sha256 hash of variable bank 0 + - 32b: sha256 hash of variable bank 1 + |