diff options
Diffstat (limited to 'docs/fingerprint/fingerprint-tpm-seed.md')
-rw-r--r-- | docs/fingerprint/fingerprint-tpm-seed.md | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/docs/fingerprint/fingerprint-tpm-seed.md b/docs/fingerprint/fingerprint-tpm-seed.md deleted file mode 100644 index 904fb7243a..0000000000 --- a/docs/fingerprint/fingerprint-tpm-seed.md +++ /dev/null @@ -1,324 +0,0 @@ -# TPM Seed for Fingerprint MCU - -Authors: pmalani@google.com, norvez@google.com - -Reviewers: semenzato@google.com, apronin@google.com, mnissler@google.com and -others - -Last Updated: 2018-11-01 - -[TOC] - -## Objective - -Increase security for Fingerprint (FP) templates by using a TPM-sourced seed in -addition to internal FPMCU entropy while encrypting FP templates. The -TPM-sourced seed will be derived from the system key which is loaded from the -TPM during boot in mount-encrypted. - -## Background - -Fingerprint authorization in Chrome OS, relies on encrypted FP templates which -are stored in each user’s mount directory. These templates are created and -encrypted by the FPMCU during FP enrollment, before being sent back to the AP -(Application Processor). When the user logs in, these templates are sent to the -FPMCU where they get decrypted and loaded. - -The encryption is performed in the FPMCU using entropy which is internal to the -MCU and never leaves the MCU. That way, even if the templates are somehow -obtained by and attacker from the user mount directory, they cannot be -decrypted, since the attacker will not have access to the MCU entropy. This -entropy gets reset on every powerwash/recovery. - -The complete design doc is [Fingerprint Authentication on Chrome OS]. - -## Requirements and Scale - -The solution proposed should exhibit the following attributes: - -* Strengthens security of FP templates. -* Does not compromise the security of other sub-systems. -* Works fast and doesn’t affect time to boot, or reduce boot-time stability. - -## Design Ideas - -In addition to FPMCU entropy, we include a TPM-sourced seed (derived from the -system key) while performing template encryption. The TPM system key gets -regenerated during powerwash/recovery, so in the event that the FP templates are -accessed due to a runtime exploit, a power-wash / recovery from the user will -ensure: - -* The raw templates cannot be decrypted, since the TPM-seed would have been - lost irrevocably. -* Since a new TPM-seed is generated (since a new system key is created), old - templates can’t be re-used, even if the attacker could somehow gain access - to the FP MCU entropy. - -The overall design consists of two components: - -* Generating a TPM-seed and sending it to the Biometric sensor managers. -* The Bio sensor managers sending the seed to the FPMCU and programming it - into the encryption / decryption operations of FP templates. - -### TPM seed generation {#seed-generation} - -![TPM Seed Diagram] - -The TPM seed generation would proceed as follows: - -1. During mount-encrypted execution, after the `System_key` is loaded, the - TPM-backed system key will be HMAC-ed with a simple salt (the string - `biod`): - - ``` - TPM_Seed = HMAC_SHA256(System_key, "biod") - ``` - -2. The resulting 256-bit seed (called `TPM_Seed`) will be maintained in a - `brillo::SecureBlob`. - -3. The `TPM_seed` will be saved into a tmpfs file - (`/run/biod_crypto_init/seed`) for consumption by `bio_crypto_init`. This - file's ownership will be set up such that only user/group `biod` can access - it. - -4. `bio_crypto_init` (the binary which sends the seed to the FPMCU) will be - spawned after mount-encrypted completes. This is ensured by setting the - `bio_crypto_init` upstart rules to depend on `starting boot-services` - -5. On the `bio_crypto_init` side, the `TPM_seed` will be retrieved from the - tmpfs file and forwarded to the FP MCU via the various BiometricManagers. - Immediately after reading from the tmpfs file, `bio_crypto_init` will nuke - (write all 0’s and then delete) the tmpfs file. - -6. The upstart rules of biod will be modified such that it will start after - `bio_crypto_init` stops (this modification can be made in the `.conf` file - of biod) - -#### IPC Mechanism {#ipc} - -(For a discussion of various alternatives, please see the -[Alternatives Considered] section) - -The IPC mechanism selected should have the following features: - -* Allow to quickly pass the `TPM_seed` between mount-encrypted and - `bio_crypto_init`. -* Minimize the presence of extra/asynchronously deleted copies of the - `TPM_seed` buffer in kernel and memory. This is crucial to minimize the risk - of access to this seed. - -The currently proposed method of passing the `TPM_seed` is to use a **file in -tmpfs**. The sequence would be as follows: - -* mount-encrypted will write the `TPM_Seed` to a file in `/run` - (`/run/bio_crypto_init/seed`). `/run` is a tmpfs created by the OS for use - by various system services. -* `bio_crypto_init` will read the `TPM_Seed` from the known tmpfs file. -* As soon as `bio_crypto_init` reads the `TPM_Seed`, it will first overwrite - (`/run/biod_crypto_init/seed`) with all 0s, and immediately after will - delete `/run/biod_crypto_init/seed`. -* `bio_crypto_init` can then instantiate its BiometricManager classes and send - the data to the FP MCU. This way, even if the sending of data fails, there - will not be any stray copy of the `TPM_seed` in a process’s memory, or in - tmpfs. - -##### Advantages - -* No/minimal buffering of copies of `TPM_Seed` in kernel. -* No need to create and pass FDs between mount-encrypted and - `bio_crypto_init`. - -##### Disadvantages - -* If `bio_crypto_init` crashes / fails to start, the tmpfs file remains in the - system, i.e cleanup of tmpfs is reliant on `bio_crypto_init`. - -### Programming TPM_Seed into MCU - -#### Entropy addition v/s programming TPM Seed - -When a device boots up for the first time after going through -recovery/powerwash, biod will force an "Add Entropy" step. This involves: - -* rebooting the FP MCU to RO -* Performing an entropy addition step -* Rebooting the FP MCU to RW -* Verifying that the entropy addition has taken place (by checking the block - ID of the rollback info on the MCU). - -Unfortunately, since the `TPM_Seed` will be stored in MCU RAM, the reboot of the -FPMCU will lead to the `TPM_Seed` being lost until the next boot. In the absence -of a `TPM_Seed`, all FPMCU operations will fail (until the next boot). There is -no opportunity to reprogram the `TPM_Seed`, because that must take place during -mount-encrypted, which must necessarily run before `biod` starts. - -There are two proposals to work around this issue. The one eventually selected -has been included here, and the other alternative has been placed in the -[Alternatives Considered] section. - -##### Make bio_crypto_init solely set the TPM_Seed (don't perform entropy_add) - -In this method, `bio_crypto_init` will not perform any reboot on the MCU, and -solely program the `TPM_Seed`. This would mean that if a device was to boot for -a first time without having done any previous powerwash/recovery, the first boot -would not have FP functionality. FP functionality would be regained on all -subsequent boot (since the entropy would have been added/initialized by then). - -The downside of this approach is a poor user experience. - -The benefit is a simple implementation of the `bio_crypto_init` tool, which will -consequently also take less time to execute (booting to RO/RW are time consuming -operations). - -In practice all devices leaving the factory floor would have `bio_wash ---factory_init` done on them during finalisation to initialise the entropy, and -so this shouldn't affect a large majority of end users. - -### Signaling biod to start - -In order to avoid races which might occur because both `bio_crypto_init` and -`biod` will try to access the `BiometricManagers`' hardware. We need to ensure -that `biod` only starts after `bio_crypto_init` ends. - -To accomplish this, `biod.conf` will be modified to include a dependency on -`bio_crypto_init` to start the daemon. So, the relevant portion of `biod.conf` -will now be: - -``` -start on started system-services and started uinput and stopped bio_crypto_init -``` - -### Formula to calculate IKM used for encryption in MCU - -In the FPMCU we will use the concatenation of `TPM_Seed` and [`SBP_Src_Key`] as -Input Key Material (IKM) to derive an encryption key. Combined with a random -salt, the pseudo random key (PRK) would be derived as: - -``` -PRK = HMAC_SHA256(Random_Salt, SBP_Src_Key || TPM_Seed) -``` - -## Alternatives Considered {#alt-considered} - -A few alternatives are being considered for the IPC Mechanism - -#### pipe/socketpair - -##### Disadvantages - -* The data written to pipes is buffered in internal kernel buffers till it is - read out from the other end of the pipe/socketpair. In the case of a - `bio_crypto_init` crashing, this will leave a copy in the internal kernel - buffers. Question: How long before those internal buffers get cleared in the - case of the pipe not being read from? - -#### Anonymous file (memfd_create) / Anonymous mmap - -##### Disadvantages - -* Question: When all references to the anonymous file are dropped, are the - contents of the anonymous file re-allocated, overwritten, or is the - corresponding inode simply destroyed (and the data blocks still stick around - and are reallocated lazily ?) - -There was also another alternative considered for the sequence of programming -the TPM seed and initializing the FPMCU: make `bio_crypto_init` add entropy and -then set TPM. - -## Security Considerations - -### Security boundaries - -* A new minijailed process (`bio_crypto_init`) is run when `starting - boot-services` is signaled. -* An IPC takes place between mount-encrypted and `bio_crypto_init` via a tmpfs - file. The reading and deletion of the tmpfs file is detailed in the - [IPC Mechanism] section. - -### Privileges - -* `bio_crypto_init` runs minijail-ed and runs with user/group `biod`. Only the - files required for its functioning (i.e., the tmpfs file `/run/`, the - devnode to access the FPMCU, log directory inside - `/var/log/bio_crypto_init`) are mounted and visible inside the sandbox. See - the [minijail0 arguments] for a full explanation. - -### Untrusted input - -* The only input is the `System_key` which is retrieved from the TPM anyway - during mount-encrypted execution. Thus, no additional or new input is being - fed to the feature. -* Additionally, the derived TPM-seed is saved in a tmpfs file which has a - user/group ownership as `biod` so only users `root` or `biod` can access the - file. Since `bio_crypto_init` runs only during `starting boot-services` and - the process along with the conf file ensures that the file is deleted after - execution, there is no additional threat of the `/tmp` file being corrupted. - -### Sensitive data - -* The feature involves the storage of a `TPM_Seed` derived from the - `System_key` from TPM, in a file on tmpfs (the file is zeroed and deleted - once read by `bio_crypto_init`). - -### Attack surface - -* In the event of the contents of the tmp file being read, the `TPM_Seed` - would not be of much use to the attacker, since the use of `HMAC_SHA256` - means the attacker would still not have access to the system key (brute - force trial of HMAC 256 would be required to guess the system salt required - to produce the TPM-seed). -* In the unlikely event of the contents of the tmp file being modified before - they are programmed into the FPMCU, FP unlock would fail (since the - encrypted templates would not longer be decrypted correctly, since the FPMCU - encryption key would have changed). The FP templates encryption key is a - combination of both the `TPM_seed` as well as the internal `SBP_Src_Key` - combined with a random salt, and since only the encrypted templates are - stored on the rootfs, the templates would simply be rendered useless. A - powerwash/recovery can help restore functionality of FP unlock, but new - templates would have to be registered. -* This code should not be accessible to remote attackers. - -### Implementation robustness - -* `bio_crypto_init` uses two processes. A child process is spawned by - `bio_crypto_init` and the FPMCU programming is done on the child process. - The parent process waits for the child process to complete, or kills the - process if it exceeds a timeout limit. This ensures that the process doesn't - hang indefinitely. -* The feature uses tmpfs (`/run/bio_crypto_init/seed`) as an IPC mechanism to - transfer the `TPM_Seed` between mount-encrypted and `bio_crypto_init`. - Please see the [Alternatives Considered] and [Design Ideas] section - regarding rationale behind choosing tmpfs vis a vis socketpair/pipe. - -### Cryptography - -* `HMAC_SHA256` is used to derived `TPM_Seed` from the `System_key` as - described in section [TPM seed generation]. - -* `HMAC_SHA256` is also used to derive the FPMCU’s encryption key. This is the - same as it was earlier; the only change is that source key has been updated - to also include the `TPM_Seed`. - -## Privacy Considerations - -This implementation should not have any adverse implications on Privacy (over -and above existing functionality on Chrome OS). This provides security hardening -for the fingerprint templates to prevent their retrieval and mis-use. - -[Fingerprint Authentication on Chrome OS]: ../fingerprint/fingerprint-authentication-design-doc.md -[`SBP_Src_Key`]: ../fingerprint/fingerprint-authentication-design-doc.md#sbp-secret-generation -[IPC Mechanism]: #ipc -[minijail0 arguments]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform2/biod/init/bio_crypto_init.conf;l=36;drc=1fcefaa166e868069ad1b81091333ff75e0657f6 -[Design Ideas]: #design-ideas -[TPM seed generation]: #seed-generation -[Alternatives Considered]: #alt-considered - -<!-- Images --> - -<!-- If you make changes to the docs below make sure to regenerate the PNGs by - appending "export/png" to the Google Drive link. --> - -<!-- https://docs.google.com/drawings/d/1d0ocdnEjsO26c3usP1FwgTZ7VwEr-4ydnC0WMhOnbLY --> - -[TPM Seed Diagram]: ../images/cros_fingerprint_tpm_seed.png |