Lockbox

Cryptohome manages a tamper-evident file which is meant to contain install-lifetime system attributes.

Overview

Tamper-evident storage can be accessed by consumers over D-Bus using the InstallAttributes* calls. Essentially, this provides a name-value storage interface for Get()ing and Set()ing values during install. The datastore is made tamper-evident by serializing it to a bytestream and persisting it to the filesystem via the Lockbox class. This is done when InstallAttributes::Finalize() is called. After finalization, the data becomes read-only.

The Lockbox class provides a clear interface for implemented TPM NVRAM-backed, tamper-evident data storage. It allows for the creation, destruction, storage, and retrieval of tamper-evident data. InstallAttributes stores its serialized data via this mechanism and reloads it similarly to ensure data integrity.

Each lockbox assures tamper-evidence cryptographically by storing a SHA256 digest of the supplied data blob in a TPM NVRAM space. The space itself is logically defined as follows:

struct {
  uint32_t data_size;
  uint8_t flags;
  uint8_t salt[SHA256_DIGEST_LENGTH];
  uint8_t hash[SHA256_DIGEST_LENGTH];
} __attribute__((packed));

The data size is the expected size of the “locked” data. This provides a simple validity check and ensures collision attacks against the stored data are size-limited.

Flags is reserved for future use, primarily in anticipation of future digest changes or data serialization changes (encrypted versus not). At present, flags is always 0.

The salt is 32 bytes of randomly generated data sourced from the TPM itself. This also aids in collision attack deterrence. Many devices will likely share the same file. If a collision is found for the hash of that file, arbitrary replacement attacks would be feasible. The added salt serves to increase the difficulty of these forms of attack.

The hash is computed as SHA256(data||salt).

Once the struct is filled, it is written to the NVRAM space. A subsequent 0 byte write locks the NVRAM space (bWriteDefine) from future modification without redefinition using the TPM Owner passphrase or by asserting physical presence.

See cryptohome.xml for the exact D-Bus API calls. See lockbox.h and install_attributes.h for more information on what each provides.

Device integration

InstallAttributes and Lockbox are initialized by default whenever the cryptohomed service is started. On any system that is upgraded to support InstallAttributes, it will treat the InstallAttributes as an empty-locked store by observing that no NVRAM space was defined nor backing lockbox file created.

On a fresh installation, cryptohomed will start and immediately begin the TPM ownership process. Upon completion, InstallAttributes will perform one-time initialization that creates its Lockbox and destroys any existing Lockbox data. cryptohomed will then “forget” the TPM owner password when told to by Chrome (such as at the end of the EULA view or at the login screen). Chrome will populate the InstallAttributes during the system's first boot and call Finalize() upon completion. In addition, cryptohomed will call Finalize() any time a (Async)Mount request is received over D-Bus. This is to ensure that the InstallAttributes are fully populated prior to the system going into general use. On first login, a very fast user may perform the first Mount call prior to the TPM being owned. In that case, the InstallAttributes will remain freshly initialized and unlocked until the next Mount attempt occurs (after TPM ownership has completed).

Recovery from a corrupt Lockbox requires the TPM to be cleared of a TPM owner. This can be triggered by toggling the developer mode switch and rebooting, or by going through the system recovery flow.

NVRAM Index Selection

This value was picked by reviewing the related specification documents. The index is a managed namespace as laid out below:

    3                   2                   1
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|P|U|D| resvd |   Purview      |         Index                |
(T=TPM, P=platform maker, U=platform user, D=pre-defined)

(from TCG TPM Structures rev 103)

Some ranges have been declared reserved in other specs:

  • 0xFFFFFFFF is the NVRAM lock (permanent).
  • 0x50010000 is reserved for BIOS use.
  • 0x0000Fxxx preallocated/reserved by for locality use.
  • 0x0001xxxx are a handful of TSS reserved ranges.
  • 0x10000001 is the deprecated NV_INDEX_DIR.
  • 0x00000000 is the bGlobalLock index.

In addition, there is at least one other major user. For tboot, Intel uses:

  • 0x20000001: 00100000000000000000000000000001
  • 0x20000002: 00100000000000000000000000000010

in the Platform User range. It‘s unclear if they’ll expand further out in the future, so we leave room for them to add a single space.

  • 0x20000004: 00100000000000000000000000000100

Arguably, we could use a ‘P’ space, but that would complicate Chromium OS use on non-Chrome hardware.