summaryrefslogtreecommitdiff
path: root/docs/fingerprint
diff options
context:
space:
mode:
Diffstat (limited to 'docs/fingerprint')
-rw-r--r--docs/fingerprint/OWNERS1
-rw-r--r--docs/fingerprint/fingerprint-authentication-design-doc.md772
-rw-r--r--docs/fingerprint/fingerprint-debugging.md254
-rw-r--r--docs/fingerprint/fingerprint-dev-for-partners.md657
-rw-r--r--docs/fingerprint/fingerprint-factory-quick-guide.md97
-rw-r--r--docs/fingerprint/fingerprint-factory-requirements.md502
-rw-r--r--docs/fingerprint/fingerprint-firmware-testing-for-partners.md112
-rw-r--r--docs/fingerprint/fingerprint-tpm-seed.md324
-rw-r--r--docs/fingerprint/fingerprint.md590
9 files changed, 0 insertions, 3309 deletions
diff --git a/docs/fingerprint/OWNERS b/docs/fingerprint/OWNERS
deleted file mode 100644
index ba92c193e0..0000000000
--- a/docs/fingerprint/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include ../../common/fpsensor/OWNERS
diff --git a/docs/fingerprint/fingerprint-authentication-design-doc.md b/docs/fingerprint/fingerprint-authentication-design-doc.md
deleted file mode 100644
index 7db552405a..0000000000
--- a/docs/fingerprint/fingerprint-authentication-design-doc.md
+++ /dev/null
@@ -1,772 +0,0 @@
-# Fingerprint Authentication on Chrome OS
-
-Authors: norvez@google.com, vpalatin@google.com
-
-Reviewers: kerrnel@google.com, mnissler@google.com
-
-Last Updated: 2019-01-14
-
-[TOC]
-
-## Objective
-
-### Goals
-
-* Let users securely unlock their device with just their fingerprint
-* Reuse the same architecture on all future platforms, don’t be tied to a
- specific technology ([Arm TrustZone], [Intel SGX]).
-* Support Android’s [fingerprint authentication framework] so users can for
- example authorise payments in Android apps with their fingerprint. The
- fingerprint implementation needs to comply with Android’s [CDD].
-
-### Non-goals
-
-* Let users log in with their fingerprint
- * Users will have to use other authentication methods (e.g. password or
- PIN) to log into their account.
- * Once logged in, users will be able to unlock the screen with their
- fingerprint
-
-## Background
-
-To unlock their Chromebook users have to enter their password or a PIN.
-[Windows] and [macOS] let the user authenticate with their fingerprint for
-faster unlocking, we want to bring that capability to Chrome OS.
-
-### Fingerprint matching basics
-
-#### Fingerprint enrollment
-
-When a user wants to register their finger for fingerprint authentication, they
-go through the _enrollment_ operation. They are asked to touch the sensor
-multiple times with different parts of their fingerprint. The
-[matching algorithm] uses the images captured during enrollment to build a model
-of that fingerprint (known as a _template_).
-
-#### Fingerprint matching
-
-When the user puts their finger on the sensor, an image of the fingerprint is
-captured and compared to the fingerprint templates of the enrolled fingerprints
-to determine if the fingerprint matches one of the templates.
-
-#### Template update (TU)
-
-When the matching algorithm determines that a fingerprint matches a template
-with a high level of certainty, it can (and normally will) use that fingerprint
-image to update the template to improve the accuracy of future matching
-operations.
-
-### Threat model
-
-There are two main objectives for potential attackers:
-
-* Large scale collection of biometric data from users by opportunistic
- attackers
- * This attack is only valuable remotely. In case an attacker has physical
- access to the device they are already able to collect fingerprint data
- left by the user on the device itself without having to attack the
- software.
-* Target a specific user, typically with physical access to the device in
- order to either:
- * Allow the attacker to enroll their own fingerprint to unlock the device
- at will later on (the “abusive partner” model).
- * Spoof positive fingerprint matches to let the rest of the system believe
- that a user has successfully identified, for example to break [2FA]
- \("spy" trying to gain access to an organisation’s resources via the
- victim’s computer).
-
-### Privacy and security
-
-* Biometric data is particularly sensitive, so all operations on fingerprint
- data must happen in a _Secure Biometric Processor_ (**SBP**). Attackers must
- not gain access to the user’s fingerprints even if they have exploited the
- software running on the AP.
-* To protect the user’s privacy, fingerprint data must not be accessible
- without the user’s consent, even by Google. Typically it will protected by
- the user’s password.
-* Fingerprint data must not leave the device.
-* For added security, only the specific Chromebook used to enroll the
- fingerprint can use it. Other Chromebooks, even of the same model, must not
- be able to use the enrolled fingerprint.
-
-### Scalability
-
-For Eve, we [considered][Old Design Doc] using SGX as the SBP. However the
-complexity of the solution makes that option unattractive, both because of the
-amount of dev work required and because of the large resulting attack surface.
-It’s also exclusive to Intel, we would have to develop a completely different
-architecture for other platforms, which would add more dev work and increase the
-attack surface again.
-
-## Overview {#overview}
-
-Devices have a dedicated microcontroller (MCU) running a firmware based on the
-[Chromium OS EC] codebase that is used as the _Secure Biometric Processor_
-(**SBP**), where all enrollment and matching operations take place. Even if
-attackers gained control of the AP, they still would not be able to access the
-fingerprint (FP) data since it never leaves the SBP unencrypted.
-
-The SBP controls the sensor directly over a dedicated SPI bus. The SBP is
-connected to the host with a different SPI bus, the host has no direct access to
-the FP data coming from the sensor.
-
-Enrolled templates for a particular user are stored in the user’s [cryptohome]
-but not synced/backed up to the cloud. They are thus encrypted with a key
-(`User_Key`) derived from the user’s password, preventing 3rd parties (including
-Google) from accessing the fingerprint templates if the user hasn’t entered
-their password.
-
-On top of that, enrolled templates are also encrypted by a device-specific
-`HW_Key`. `HW_Key` is derived from a secret that has been randomly generated by
-the SBP, which prevents decrypting the templates on another device.
-
-### Architecture
-
-![Fingerprint Architecture]
-
-### Typical workflows
-
-#### FP enrollment
-
-1. User starts the enrollment flow from the Settings UI.
-1. SBP starts the enrollment operation.
-1. SBP captures a number of FP images (exact number depends on the sensor,
- typically 3-4 to 10-12) and builds the template in the SBP’s volatile memory
-1. SBP encrypts the template with `HW_Key` and sends the encrypted template to
- the AP.
-1. AP encrypts the template with `User_Key` and saves it to non-volatile
- storage.
-1. User goes back to step 1 to enroll another finger. A user can typically
- enroll 3 to 5 fingers, depending on how many templates the SBP can hold in
- its internal volatile storage at the same time.
-
-#### User login
-
-1. User logs in by typing their password.
-1. FP templates of that user go through the first level of decryption, with
- `User_Key`.
-1. FP templates are uploaded to the SBP.
-1. FP templates go through the second level of decryption in the SBP, with
- `HW_Key`.
-1. Deciphered FP templates are kept in the SBP’s volatile memory, ready to use
- for matching operations.
-
-#### Screen unlocking operation
-
-1. User touches the sensor with their finger.
-1. SBP verifies that the FP image matches one of the user’s templates.
-1. SBP wakes up the AP and sends a “FP matched” message to the AP
-1. The AP unlocks the screen.
-1. Matcher updates the template in the SBP’s volatile memory.
-1. SBP encrypts the updated template with `HW_Key` and sends the encrypted
- template to the AP.
-1. AP encrypts the template with `User_Key` and saves it to non-volatile
- storage.
-
-## Detailed Design {#detailed-design}
-
-### FP template encryption {#template-encryption}
-
-FP templates are encrypted "twice". First, the templates are encrypted by the
-SBP with a hardware-bound key that is unique to this SBP and that only the SBP
-knows. On top of that, the AP also encrypts the FP templates with a key bound to
-the user password.
-
-#### User-bound encryption
-
-The FP templates are stored in a "[cryptohome daemon store folder]" which is
-encrypted by [cryptohome] with a key tied to the user password. We plan to
-replace this post-launch with a mechanism similar to
-[Authentication-Time User Secrets]. Separate design doc to come.
-
-#### Hardware-bound encryption
-
-FP templates are AES-encrypted with `HW_Key`. `HW_Key` is bound to this specific
-SBP so encrypted templates can only be deciphered by this specific SBP. To
-ensure that a powerwash/recovery/WP toggle/.../ makes the encryption key
-impossible to recover, `HW_Key` also depends on a secret held by the TPM.
-
-We use an AEAD cipher (AES-GCM) to detect if the encrypted templates have been
-tampered with by an attacker controlling the AP.
-
-##### SBP secret generation
-
-The SBP generates a new 128-bit random number `SBP_Src_Key` every time the user
-goes through recovery or powerwashes the device. The [clobber-state] script
-sends a command to the SBP to make it immediately regenerate a new `SBP_Src_Key`
-immediately after requesting a TPM clear.
-
-`SBP_Src_Key` is stored by the SBP’s internal Flash and never shared with the
-AP.
-
-##### TPM-held Secret
-
-To avoid potential bugs where `SBP_Src_Key` would not always be made
-unrecoverable in some corner cases of recovery or powerwash, we make the
-encryption key `HW_Key` depend on a secret that is held by the TPM and deleted
-every time the TPM is cleared, for example if someone attempts to do a
-"[ccd open]" to disable the hardware WP.
-
-The following is a summary of the mechanism, see the specific design doc
-[TPM Seed for Fingerprint MCU] for details.
-
-The TPM already holds a "[system key]" `Cros_Sys_Key` in NVRAM space that is
-used to derive the encryption key of the stateful partition. That "system key"
-can only be read once per boot, typically by [mount_encrypted].
-
-We modify mount_encrypted so that right after reading the seed, it derives a key
-`TPM_Seed`:
-
-```
-TPM_Seed = HMAC-SHA256(Cros_Sys_Key, "biod")
-```
-
-`TPM_Seed` is then uploaded to the SBP where it will part of the
-[Input Key Material (IKM)] and immediately cleared from the AP’s memory, while
-the attack surface is very small (e.g. no network connections, stateful
-partition not yet mounted) to prevent attackers from accessing it.
-
-##### `HW_Key` derivation {#hw-key-derivation}
-
-The `HW_Key` 128-bit AES key for every FP template on the device is derived from
-the SBP’s secret and the TPM’s secret to ensure uniqueness. Therefore, even two
-identical devices would have different encryption keys. The user ID is also used
-as an input for key derivation, so 2 users on the same device won’t share
-encryption keys either. Summing up, the key used to encrypt a template depends
-on:
-
-* Device-bound `TPM_Seed`, randomly generated on recovery/powerwash
-* SBP-specific `SBP_Src_Key`, randomly generated on recovery/powerwash
-* User ID on the device
-* Encryption salt, randomly generated before every encryption
-
-###### Salt for key derivation
-
-Every time we update a template, we generate a new random 128-bit salt.
-
-The salt is not required to be secret, so we store `User_Salt` in cleartext next
-to the user’s encrypted FP templates on the disk.
-
-On user login, biod sends the salt and the encrypted FP templates to the SBP.
-biod also sends the User ID to the SBP. The SBP derives the AES key using [HKDF]
-with HMAC-SHA256:
-
-```
-HW_Key = HKDF(HMAC-SHA256, SBP_Src_Key, TPM_Seed, User_Salt, User_ID)
-```
-
-At that point, the SBP [authenticates and deciphers](#aead) the FP templates.
-The SBP then generates a new 128-bit salt `User_Salt_New` randomly and derives a
-new AES key:
-
-```
-HW_Key_New = HKDF(HMAC-SHA256, SBP_Src_Key, TPM_Seed, User_Salt_New, User_ID)
-```
-
-Updated FP templates are then encrypted with `HW_Key_New` before being stored on
-the host, along with the new salt `User_Salt_New`.
-
-*Note*: The SBP has a unique serial number hwID that could also be used as an
-additional input to the KDF (though it never changes). The entropy is pretty low
-and though not easily accessible an attacker who had stolen the device could
-gain access to it. After consulting with the security team, using the hwID was
-deemed unnecessary since it wasn’t adding real entropy.
-
-##### AEAD (AES-GCM) Encryption {#aead}
-
-To encrypt the FP templates with `HW_Key` we use BoringSSL’s implementation of
-AES-GCM128.
-
-###### Initialisation Vector
-
-The encryption operations are done by the R/W firmware that doesn’t have write
-access to the Flash, so it can’t keep track of IVs that could have already been
-used during previous boots since it has no way to persist state. Instead, the
-SBP will generate a random 96-bit IV every time it needs to encrypt a template
-with `HW_Key` before sending it back to the host for storage. This only happens
-every time a user successfully matches their finger, which assuming 1 match
-every second for 10 years would result in 3600\*24\*365\*10 < 350,000,000, so
-the risk of reusing an IV is acceptable. To ensure that a compromised host could
-not try to generate too many messages to find collisions, the SBP rate-limits
-the number of encryption operations to 1 per second.
-
-The IV will be stored on the host with the salt, the encrypted templates and the
-16-byte tag for authentication.
-
-###### Authentication Tag
-
-To authenticate the encrypted templates, we use a 128-bit tag that we store in
-clear text with the encrypted template.
-
-Authentication of the encrypted templates prevents attackers from generating
-random templates to try to attack directly the matching libraries rather than
-the AES-GCM128 implementation. It also prevents attackers from trying to pass
-their own template instead of the user’s FP template.
-
-###### Encryption Flowchart
-
-Encryption of the FP template in the SBP before the ciphered data is sent to the
-AP for storage.
-
-![Encryption Flowchart]
-
-###### Decryption Flowchart
-
-Decryption of the ciphered FP template coming from the AP when the user logs in.
-
-![Decryption Flowchart]
-
-#### FP template disk format
-
-Encrypted templates are stored in a “[cryptohome daemon store folder]” that is
-only mounted/decrypted when the user has logged in. The templates are stored as
-JSON files with the following fields:
-
-```JSON
-{
- "biomanager": “CrosFpBiometricsManager” string
- "version": integer describing the version of the file format. Set to 1 at launch
- "data": Base64-encoded string containing the `HW_Key`-encrypted template
- "label": user-configurable human-readable string listed in the UI
- "record_id": UUID of that template generated at enrollment time
-}
-```
-
-##### `HW_Key`-encrypted template format
-
-The content of the "data" field is the encrypted template that can be deciphered
-by the SBP.
-
-Field Name | Field description | Field size (bytes) | Field offset (bytes)
----------- | --------------------------------------------------------------------- | ------------------ | --------------------
-Version | Number describing the version of the file format. Set to 3 at launch. | 2 | 0
-Reserved | Reserved bytes, set to 0 | 2 | 2
-Nonce | Randomly-generated IV | 12 | 4
-Salt | Randomly-generated salt | 16 | 16
-Tag | AES-GCM Authentication Tag | 16 | 32
-Template | Encrypted template | 47552 | 48
-
-When the user logs in, the cryptohome daemon store folder of that user is
-mounted and the JSON files become available to biod. For every enrolled finger,
-biod sends the `HW_Key`-encrypted template to the SBP. The SBP
-[derives `HW_Key`](#hw-key-derivation) for that template and deciphers the
-template.
-
-### Protection of the SBP
-
-To access the unencrypted data and/or `HW_Key`, attackers have 3 main options:
-
-* Temporarily gain read or even execution access in the SBP through a firmware
- bug
- * Would allow an attacker to gain access to the clear text FP data and/or
- the encryption key
- * Mitigation strategy in [Prevent RW exploits](#prevent-rw-exploits)
-* Turn a temporary compromise of the SBP’s firmware into a permanent exploit
- by replacing the SBP’s firmware with a firmware controlled by the attacker
- * Would allow an attacker to gain access to the clear text FP data and/or
- the encryption key
- * Would allow an attacker to spoof positive FP matches, defeating 2FA
- * Mitigation in [Verified firmware](#verified-firmware)
-* Use physical access and control of WP to load a compromised firmware to the
- SBP
- * Mitigation in [Control WP/BOOT0](#control-wp-boot0)
-
-#### Verified firmware {#verified-firmware}
-
-To verify the integrity of the firmware we use a mechanism similar to the one
-used to protect the EC in detachable keyboards as described in
-[Detachable Base Verified Boot].
-
-The SBP has a minimalistic RO firmware that contains the public part of an
-RSA-3072 exponent 3 key pair. The corresponding private key is only accessible
-by the Chrome OS signers and is used to sign SBP firmwares. On boot the RO
-firmware verifies the signature of the RW firmware. If the RW signature is
-valid, the RO firmware protects itself by setting the WP bit of the Flash then
-jumps to RW.
-
-##### Anti-rollback
-
-On top of verifying the signature of the RW firmware, the RO firmware must
-verify that the RW firmware is not an outdated version with known
-vulnerabilities. This is required to prevent attackers from loading valid but
-vulnerable RW firmwares. This is achieved with an anti-rollback mechanism as
-described in
-[Detachable Base Verified Boot][Detachable Base Verified Boot Anti-Rollback].
-
-###### Nocturne-specific anti-rollback
-
-On nocturne, the SBP is an STM32H7 MCU, with 128K Flash blocks. We still need 2
-pingpong RB blocks to prevent data loss, so the Flash map looks like this:
-
-Name | Size
-------------------- | -------
-RO firmware | 128 KB
-Blank | 640 KB
-RB1 + `SBP_Src_Key` | 128 KB
-RB2 + `SBP_Src_Key` | 128 KB
-RW firmware | 1024 KB
-
-The Nocturne SBP uses the same Flash block for the anti-rollback mechanism and
-`SBP_Src_Key`. Most of the anti-rollback mechanism is identical to the one
-described in
-[Detachable Base Verified Boot][Detachable Base Verified Boot Anti-Rollback],
-and the key is similar to the entropy/secret stored for
-[Detachable Base Swap Detection].
-
-The rollback minimum version is updated whenever RO has verified RW signature,
-and the RW rollback version is larger than what is stored in the RB block.
-
-When re-keying is desired, `SBP_Src_Key` is updated by doing the following
-operation:
-
-```
-SHA256(SBP_Src_Key || entropy)
-```
-
-where `entropy` is generated from STM32H7 True Random Number Generator (see
-[RM0433] Chapter 33 for details). Since there are 2 rollback blocks, and we
-ping-pong between them, re-keying should involve updating `SBP_Src_Key` twice,
-so that both blocks are erased, and no remnant of the previous key is left over.
-
-#### Prevent RW exploits {#prevent-rw-exploits}
-
-Even non-persistent exploits in the RW firmware would be problematic if the
-attacker was able to read the content of the memory or the Flash, e.g. via a
-buffer overflow, since they could gain access to the clear text FP data and/or
-the encryption key. If the attacker was also able to execute code in RW, they
-would be able to spoof positive FP matches.
-
-##### Attack through host command interface {#attack-host-command}
-
-The AP can send a number of commands to the SBP, for example to wait for a match
-or to update the RW firmware. In case of a vulnerability in the protocol an
-attacker with (potentially remote) access to the AP<->SBP SPI bus could send bad
-specially crafted commands to the SBP and potentially gain read, write or even
-execute permissions in the SBP.
-
-###### Mitigation strategies
-
-* Limit the size of the API exposed by the SBP to the AP
-* Fuzz the host command interface
-
-##### Attack through crafted templates uploaded to the SBP {#template-attack}
-
-The AP partially deciphers (with `User_Key`) the templates stored on the disk
-then sends the `HW_Key`-encrypted templates to the SBP where they will be
-deciphered and then passed to the matching algorithm. An attacker could submit a
-carefully crafted template to the SBP that would exploit holes in the closed
-source matching algorithm library.
-
-###### Mitigation strategies
-
-We use AEAD to decipher and authenticate the templates received from the AP,
-they are not passed directly to the matching library. Bad templates will be
-intercepted by the decryption code.
-
-##### RAM noexec
-
-Even if an attacker gained some level of access to the SBP, the RAM is not
-executable so it would be hard for the attacker to execute compromised code, for
-example to spoof successful authentication and break 2FA or to attempt to turn
-into a persistent compromission of the SBP by writing a new compromised firmware
-to Flash.
-
-#### Control WP/BOOT0 {#control-wp-boot0}
-
-The BOOT0 pin of the MCU is gated by the WP controlled by Haven. Since toggling
-the WP bit from Haven requires physical access to the device, remote attackers
-can’t toggle the BOOT0 pin to make the MCU start in bootloader mode and
-read/write the Flash from the AP.
-
-However, with physical access (> 5 minutes) an attacker could disable the WP
-signal from Haven and toggle the BOOT0 pin to start the MCU in bootloader mode.
-
-##### Flash protected with RDP Level 1
-
-We will set the Flash in [Global Read-out Protection (RDP) mode Level 1]. This
-means that attackers with physical access who would manage to start the MCU in
-bootloader mode would not be able to read `SBP_Src_Key` from the Flash.
-Attackers would still be able to read the content of the RAM and registers but
-at that point the MCU would just have rebooted and the RAM would be empty.
-
-If the attacker attempted to write their own code to the Flash (for example to
-replace RO), RDP Level 1 would only allow that after a complete erasure of the
-Flash that would wipe `SBP_Src_Key`, preventing the user from decrypting FP
-templates.
-
-*Note*: An attacker with that level of access could in theory replace the RO
-firmware with their own firmware. This would however have wiped enrolled
-fingers, giving the user an indication that their device might have been
-tampered with. This wouldn’t give access to existing FP templates or images to
-the attacker, only future enrollments.
-
-##### RMA
-
-To ensure that a device is clean after e.g. refurbishing, the RMA procedure
-would require that the operator disabled the WP bit from Haven and toggled BOOT0
-to switch to bootloader mode. After that a known good RO and RW firmware can be
-written to the Flash and the operator will reenable the WP bit from Haven.
-
-## Security Considerations
-
-### Security boundaries
-
-#### Chrome to system services
-
-Biod and Chrome communicate over D-Bus (defined [here][biod D-Bus API]).
-
-* Chrome lets biod know when the user has signed in, so biod can load the
- templates to the [SBP](#overview).
-* Biod lets Chrome know when the SBP has detected a positive or negative match
- so Chrome can unlock the screen.
-* Chrome tells biod to start/end enrolling a finger.
-* Chrome tells biod to start/end authentication (matching) mode.
-
-#### Kernel to firmware
-
-The SBP uses the `cros_ec` interface, same as the EC. There are additional
-SBP-specific host commands that the AP can send to the SBP, see
-[Attack through host command interface](#attack-host-command).
-
-### Privileges
-
-#### Sandboxing
-
-Biod uses Minijail ([upstart script][biod upstart script]) for [sandboxing], and
-has a [seccomp filter].
-
-### Untrusted input
-
-Encrypted templates are read from the stateful partition where they could be
-corrupted or tampered with. Biod itself doesn’t parse that input -it’s still
-encrypted by the SBP- and merely marshalls the data around to and from the SBP.
-To ensure the integrity of the input, we use [AEAD] with an
-[implementation][AEAD implementation] based on BoringSSL.
-
-The encrypted templates are wrapped inside JSON files that could be corrupted or
-tampered with. Biod does parse and interpret some fields of those JSON files.
-That input is [fuzzed].
-
-### Sensitive data
-
-The SBP handles biometric data, see the [Detailed Design](#detailed-design)
-section that describes how we keep that data protected from attackers.
-
-### Attack surface
-
-#### Libraries
-
-* Biod uses libbrillo and libchrome
-* The SBP firmware is based on the cros_ec code already used in the EC. Two
- significant additions:
- * Parts of BoringSSL (AES and AES-GCM) ported to cros_ec
- * 3rd-party proprietary blob used for matching, see
- [Closed source blobs in the SBP](#closed-source-blobs).
-
-#### Remote attacks
-
-Neither biod nor the SBP are exposed directly to remote attackers. Since biod
-communicates with Chrome over D-Bus, and attacker who had compromised Chrome
-could start sending D-Bus commands to biod.
-
-#### Closed source blobs in the SBP {#closed-source-blobs}
-
-The enrollment/matching and image capture libraries are provided by a 3rd-party
-vendor in binary form. That proprietary blob went through a security audit by a
-3rd party auditor (see the auditor’s [report][Security Audit Report].
-
-On top of the security audit of the 3rd-party proprietary code, we limit the
-attack surface of those libraries by not directly exposing them to user input.
-Data (e.g. FP templates) that is fed to those libraries isn’t directly coming
-from untrusted user input, it is sanitized by the opensource glue logic and
-wrappers. For example, we use AEAD to ensure that the encrypted data that is
-deciphered before being passed to the 3rd-party libraries has been generated by
-the SBP itself. For more details, see section
-[Attack through crafted templates uploaded to the SBP](#template-attack).
-
-### Implementation robustness
-
-#### biod (userspace daemon)
-
-##### Multi-threading/multi-process
-
-biod uses `base::MessageLoopForIO`, no custom multi-thread or multi-process
-implementation.
-
-##### State machine implementation
-
-biod has 3 main states:
-
-* Idle
-* Waiting for a match: controlled by the [AuthSession] object
-* Enrolling a new fingerprint: controlled by the [EnrollSession] object.
-
-#### cros_fp (SBP firmware)
-
-##### Multi-threading/multi-process
-
-We use the [primitives][EC primitives] of the Chromium OS EC: tasks, hooks, and
-deferred functions.
-
-##### Memory allocation
-
-Most buffers (e.g. for FP images and templates) are [statically allocated]. The
-vendor libraries do require some dynamic memory allocation, we provide
-[wrappers functions] that use the [malloc/free memory module for Chrome EC].
-
-##### State machine implementation
-
-There is one main [state machine] that configures the matching/enrollment code
-to be ready for a match or to enroll a finger.
-
-### Cryptography
-
-See detailed discussion in the ["FP template encryption"](#template-encryption)
-section.
-
-### Metrics {#metrics}
-
-Metrics related to security that we’re collecting through UMA:
-
-* `Ash.Login.Lock.AuthMethod.Used.ClamShellMode` to know if FP is used to
- authenticate
-* `Ash.Login.Lock.AuthMethod.Used.TabletMode` to know if FP is used to
- authenticate
-* `Fingerprint.Unlock.AuthSuccessful` tracks whether FP authentication was
- successful or not
-* `Fingerprint.Unlock.AttemptsCountBeforeSuccess` tracks how many attempts it
- takes for users to unlock with their fingerprint
-* `Fingerprint.UnlockEnabled` tracks whether FP unlocking is enabled or not
-* `Fingerprint.Unlock.EnrolledFingerCount` reports the number of fingers that
- users have enrolled
-
-Complete list of metrics collected via UMA:
-[New UKM collection review - CrOS FP Unlock]
-
-### Potential attacks
-
-#### Enroll a rogue fingerprint
-
-An attacker with physical access to the device could enroll their own
-fingerprint under the victim’s account and use it to unlock the device at-will
-in the future.
-
-* Enrollment UI requires the user password before telling biod to start an
- enrollment session, so the attacker would need some form of exploit to
- bypass Chrome and trigger the enrollment. We plan to replace this
- post-launch with a mechanism similar to [Authentication-Time User Secrets].
- Separate design doc to come.
-* Even if it’s not a persistent exploit, a rogue enrolled fingerprint would
- persist.
-* The victim’s fingerprint data would still be secure.
-* The enrollment UI shows how many fingers are enrolled.
-
-## Privacy Considerations
-
-### Fingerprint data is kept locally on the device
-
-The raw fingerprint images themselves never leave the SBP. The fingerprint
-templates are kept on the local storage (encrypted both with the `HW_Key` and
-the `User_Key`) of the device and not synced to the cloud, encrypted or not.
-
-### Fingerprint data decryption requires the user password
-
-The fingerprint templates are stored in a "[cryptohome daemon store folder]"
-which is only mounted when the user logs in. To do so, they must have entered
-their password.
-
-### FP matching is not used for login, only unlocking
-
-Before using their fingerprint to unlock the device the user must have logged
-in, typically with the Google Account password.
-
-### Lock screen will display a FP icon if enabled
-
-If a user has enabled FP unlocking, a FP icon will be associated to that user on
-the lock screen. This potentially lets others know that a user has enabled FP
-unlocking. This seems reasonable when the small resulting decrease in privacy is
-weighed against the fact that adding an icon greatly improves UX.
-
-### Metrics collection
-
-We collect anonymous metrics through [UMA], see section [Metrics](#metrics) for
-details.
-
-### Logs
-
-Biod, the SBP, and Chrome have logs related to the fingerprint process.
-[Privacy fields for Fingerprints] lists the log entries and their privacy
-implications. Full [PDD is here].
-
-#### Biod
-
-The log files are in `/var/log/biod/`.
-
-#### SBP
-
-The log file is `/var/log/cros_fp.log`.
-
-<!-- Links -->
-
-[2FA]: https://en.wikipedia.org/wiki/Multi-factor_authentication
-[AEAD implementation]: https://chromium.googlesource.com/chromiumos/platform/ec/+/aed008f87c3c880edecf7608ab24eaa4bee1bc46/common/fpsensor.c#574
-[AEAD]: https://en.wikipedia.org/wiki/Authenticated_encryption
-[Arm TrustZone]: https://www.arm.com/products/security-on-arm/trustzone
-[Authentication-Time User Secrets]: http://go/authentication-time-user-secrets
-[AuthSession]: https://chromium.googlesource.com/chromiumos/platform2/+/eae39a9ad1239f8fbfa8164255578b306ff6ba5c/biod/biometrics_manager.h#96
-[biod D-Bus API]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/system_api/dbus/biod/
-[biod upstart script]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/biod/init/biod.conf
-[ccd open]: https://chromium.googlesource.com/chromiumos/platform/ec/+/cr50_stab/docs/case_closed_debugging_cr50.md#Open-CCD
-[CDD]: https://source.android.com/compatibility/android-cdd#7_3_10_fingerprint_sensor
-[Chromium OS EC]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/README.md
-[clobber-state]: https://chromium.googlesource.com/chromiumos/platform2/+/962ab1bc481db0cf504b5449eb3a3d5008ea7601/init/clobber_state.cc#475
-[cryptohome daemon store folder]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/sandboxing.md#securely-mounting-cryptohome-daemon-store-folders
-[cryptohome]: https://www.chromium.org/chromium-os/chromiumos-design-docs/protecting-cached-user-data
-[Detachable Base Swap Detection]: https://docs.google.com/document/d/1WYdkkSAL_RHVc5mUXnAvBBfAeM7Wj3ABa1dbeTdvm74/edit#heading=h.g74ijelumqop
-[Detachable Base Verified Boot Anti-Rollback]: http://go/detachable-base-vboot#heading=h.fimcm174ok3
-[Detachable Base Verified Boot]: http://go/detachable-base-vboot#heading=h.dolfbdpggye6
-[EC primitives]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/README.md#Software-Features
-[EnrollSession]: https://chromium.googlesource.com/chromiumos/platform2/+/eae39a9ad1239f8fbfa8164255578b306ff6ba5c/biod/biometrics_manager.h#92
-[fingerprint authentication framework]: https://developer.android.com/about/versions/marshmallow/android-6.0.html#fingerprint-authentication
-[fuzzed]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/biod/biod_storage_fuzzer.cc
-[Global Read-out Protection (RDP) mode Level 1]: https://www.st.com/content/ccc/resource/technical/document/application_note/b4/14/62/81/18/57/48/05/DM00075930.pdf/files/DM00075930.pdf/jcr:content/translations/en.DM00075930.pdf
-[HKDF]: https://tools.ietf.org/html/rfc5869
-[Input Key Material (IKM)]: https://en.wikipedia.org/wiki/HKDF
-[Intel SGX]: https://software.intel.com/en-us/sgx
-[macOS]: https://support.apple.com/en-us/HT207054
-[malloc/free memory module for Chrome EC]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/common/shmalloc.c
-[matching algorithm]: https://en.wikipedia.org/wiki/Fingerprint#Algorithms
-[mount_encrypted]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/cryptohome/mount_encrypted
-[New UKM collection review - CrOS FP Unlock]: https://docs.google.com/document/d/1qjDCMcBcrhSeg_uwyEIRsXHKmzUTJahcg6a4YVhkuLo
-[Old Design Doc]: https://docs.google.com/document/d/1MdPRmCDkVg1HO9DdbvPT5fDZS2ICg5ys9_ok_K95EEU
-[PDD is here]: http://go/cros-fingerprint-pdd
-[Privacy fields for Fingerprints]: https://docs.google.com/spreadsheets/d/1jLfnuhfbrImpoxuj92OkAxS_GGrm7QkpQhsUQCkO9ec
-[Privacy fields for Fingerprints]: https://docs.google.com/spreadsheets/d/1jLfnuhfbrImpoxuj92OkAxS_GGrm7QkpQhsUQCkO9ec/
-[RM0433]: https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/c9/a3/76/fa/55/46/45/fa/DM00314099/files/DM00314099.pdf/jcr:content/translations/en.DM00314099.pdf
-[sandboxing]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/sandboxing.md
-[seccomp filter]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/biod/init/seccomp/biod-seccomp-amd64.policy
-[Security Audit Report]: https://drive.google.com/a/google.com/file/d/0B1HHKpeDpzYnMDdocGxwWUhpckpWM0hMU0tPa2ZjdEFnLU53/
-[state machine]: https://chromium.googlesource.com/chromiumos/platform/ec/+/90d177e3f0ae729bea7e24934a3c6ef9f2520d45/common/fpsensor.c#252
-[statically allocated]: https://chromium.googlesource.com/chromiumos/platform/ec/+/90d177e3f0ae729bea7e24934a3c6ef9f2520d45/common/fpsensor.c#57
-[system key]: https://chromium.googlesource.com/chromiumos/platform2/+/23b79133514ac2cd986bce21c398fb6658bda248/cryptohome/mount_encrypted/encryption_key.h#125
-[UMA]: http://go/uma
-[Windows]: https://www.microsoft.com/en-us/windows/windows-hello
-[wrappers functions]: https://chrome-internal.googlesource.com/chromeos/platform/ec-private/+/9ebb3f10c611afff695f679aaeed1a35551a116b/fpc_sensor_pal.c#52
-[TPM Seed for Fingerprint MCU]: ../fingerprint/fingerprint-tpm-seed.md
-
-<!-- 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/1-JUWTF7sUTND29BfhDvIudzX_S6g-iwoxG1InPedmVw -->
-
-[Decryption Flowchart]: ../images/cros_fingerprint_decryption_flowchart.png
-
-<!-- https://drive.google.com/open?id=1uUprgLsTUZZ2G2QWRYcRn6zBAh6ejvJagVRD7eZQv-k -->
-
-[Encryption Flowchart]: ../images/cros_fingerprint_encryption_flowchart.png
-
-<!-- https://docs.google.com/drawings/d/1DFEdxfDXEtYY3LNOOJFAxVw2A7rKouH98tnb1yiXLAA -->
-
-[Fingerprint Architecture]: ../images/cros_fingerprint_architecture_diagram.png
diff --git a/docs/fingerprint/fingerprint-debugging.md b/docs/fingerprint/fingerprint-debugging.md
deleted file mode 100644
index c77874e7bb..0000000000
--- a/docs/fingerprint/fingerprint-debugging.md
+++ /dev/null
@@ -1,254 +0,0 @@
-# Fingerprint Debugging
-
-This document describes how to attach a debugger with SWD in order to debug the
-FPMCU with [`gdb`](#gdb) or to [flash the FPMCU](#flash).
-
-[TOC]
-
-## Overview
-
-### SWD
-
-`SWD` (Single Wire Debug) was introduced by ARM with the Cortex-M family to
-reduce the pin count required by JTAG. JTAG requires 5 pins, but SWD can be done
-with only 3 pins. Furthermore, one of the freed up pins can be repurposed for
-tracing.
-
-See [CoreSight Connectors] for details on the three standard types of connectors
-used for JTAG and SWD for ARM devices.
-
-## Hardware Required
-
-* JTAG/SWD Debugger Probe: Any debug probe that supports SWD will work, but
- this document assumes that you're using a
- [Segger J-Trace PRO for Cortex-M][J-Trace].
-* [Dragonclaw v0.2 Development board][FPMCU dev board] or
- [Icetower v0.1 Development board][FPMCU dev board].
-* [Servo Micro].
-
-## Software Required
-
-* [JLink Software] \(when using [J-Trace] or other Segger debug probes). This
- is the only software required for flashing.
-* In order to perform breakpoint debugging, you will need a tool that supports
- connecting `gdbserver`. This document will assume [CLion] \(Googlers see
- [CLion for Chrome OS]) and was tested with `JLink_Linux_V684a_x86_64`.
- Alternatively, you can use [Ozone], a standalone debugger from Segger.
-
-## JLink Software {#software}
-
-Download the [JLink Software], choosing the `J-Link Software and Documentation
-pack for Linux, TGZ archive, 64-bit` version. This version is recommended
-because it's simple to extract the tarball into a directory that is accessible
-to the Chrome OS chroot. The instructions in this document assume that you have
-extracted the tarball in
-`~/chromiumos/src/platform/ec/JLink_Linux_V684a_x86_64`.
-
-## Connecting SWD {#connect-swd}
-
-### Dragonclaw v0.2
-
-The connector for SWD is `J4` on Dragonclaw v0.2.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: Pay attention to the location of pin 1 (red wire) in the
-photos below so that you connect with the correct orientation.
-
-`SW2` on the bottom of Dragonclaw must be set to `CORESIGHT`.
-
-If you want to connect a 20-Pin ARM Standard JTAG Connector (0.10" / 2.54 mm),
-you can use the following [adapter][JTAG to SWD Adapter] and [cable][SWD Cable].
-***
-<!-- mdformat on -->
-
-Dragonclaw v0.2 with 20-pin SWD (0.05" / 1.27mm) on J4. Only half the pins are connected. |
------------------------------------------------------------------------------------------ |
-![Dragonclaw with 20-pin SWD] |
-
-Dragonclaw v0.2 with 10-pin SWD (0.05" / 1.27mm) on J4. |
-------------------------------------------------------- |
-![Dragonclaw with 10-pin SWD] |
-
-### Icetower v0.1
-
-The connector for SWD is `J4` on Icetower v0.1.
-
-`SW2` on Icetower must be set to `CORESIGHT` (not `SERVO`).
-
-Icetower v0.1 with 20-pin SWD (0.05" / 1.27mm) on J4. |
------------------------------------------------------ |
-![Icetower with 20-pin SWD] |
-
-## Powering the Board {#power}
-
-[Servo Micro] can provide both the 3.3V for the MCU and 1.8V for the sensor.
-
-Run the following to start `servod`, which will enable power to these rails by
-default:
-
-```bash
-(chroot) $ sudo servod --board=<BOARD>
-```
-
-where `<BOARD>` is the board you are working with
-([`dartmonkey` or `bloonchipper`][fingerprint hardware]).
-
-Theoretically, it's also possible to power through J-Trace, though the
-[power pin] on J-Trace only outputs 5V, whereas the MCU runs at 3.3V and the
-sensor runs at 1.8V. The pin is also not connected on the current designs.
-
-## Flashing the FPMCU with JLink {#flash}
-
-* Install the [JLink Software](#software).
-* [Connect SWD](#connect-swd).
-* [Power the board with servo](#power).
-* Start the JLink server:
-
-```bash
-(chroot) $ cd ~/trunk/src/platform/ec
-```
-
-```bash
-# JLinkRemoteServerCLExe will listen on port 19020 (among others) by default.
-# This can be overridden with the -Port argument.
-(outside) $ ./JLink_Linux_V684a_x86_64/JLinkRemoteServerCLExe -select USB
-```
-
-You should see the following:
-
-```bash
-SEGGER J-Link Remote Server V6.84a
-Compiled Sep 7 2020 18:28:13
-
-'q' to quit '?' for help
-
-Connected to J-Link with S/N 123456
-
-Waiting for client connections...
-```
-
-* Build the FPMCU image:
-
-```bash
-(chroot) $ cd ~/trunk/src/platform/ec
-```
-
-```bash
-(chroot) $ make BOARD=<BOARD> -j
-```
-
-replacing `<BOARD>` with [`bloonchipper` or `dartmonkey`][fingerprint hardware].
-
-* Run the [`flash_jlink.py`] script:
-
-```bash
-(chroot) $ ~/trunk/src/platform/ec/util/flash_jlink.py --board <BOARD> --image ./build/<BOARD>/ec.bin
-```
-
-replacing `<BOARD>` with [`bloonchipper` or `dartmonkey`][fingerprint hardware].
-
-## Using JLink gdbserver {#gdb}
-
-Start the JLink gdbserver for the appropriate MCU type:
-
-* Dragonclaw / [Nucleo STM32F412ZG]: `STM32F412CG`
-* Icetower / [Nucleo STM32H743ZI]: `STM32H743ZI`
-
-```bash
-(outside) $ ./JLink_Linux_V684a_x86_64/JLinkGDBServerCLExe -select USB -device STM32F412CG -endian little -if SWD -speed auto -noir -noLocalhostOnly
-```
-
-You should see the port that `gdbserver` is running on in the output:
-
-```bash
-Connecting to J-Link...
-J-Link is connected.
-Firmware: J-Trace PRO V2 Cortex-M compiled Dec 13 2019 11:19:22
-Hardware: V2.00
-S/N: XXXXX
-Feature(s): RDI, FlashBP, FlashDL, JFlash, GDB
-Checking target voltage...
-Target voltage: 3.30 V
-Listening on TCP/IP port 2331 <--- gdbserver port
-Connecting to target...
-Connected to target
-Waiting for GDB connection...
-```
-
-Configure your editor to use this [`.gdbinit`], taking care to set the correct
-environment variables for the `BOARD` and `GDBSERVER` being used. For CLion, if
-you want to use a `.gdbinit` outside of your `HOME` directory, you'll need to
-[configure `~/.gdbinit`].
-
-In your editor, specify the IP address and port for `gdbserver`:
-
-```
-127.0.0.1:2331
-```
-
-You will also want to provide the symbol files:
-
-* RW image: `build/<board>/RW/ec.RW.elf`
-* RO image: `build/<board>/RO.ec.RO.elf`
-
-Also, since we're compiling the firmware in the chroot, but your editor is
-running outside of the chroot, you'll want to remap the source code path to
-account for this:
-
-* "Remote source" is the path inside the chroot:
- `/home/<username>/trunk/src/platform/ec`
-* "Local source" is the path outside the chroot:
- `${HOME}/chromiumos/src/platform/ec`
-
-To debug with CLion, you will create a new [GDB Remote Debug Configuration]
-called `EC Debug`, with:
-
-* `'target remote' args` (gdbserver IP and port from above): `127.0.0.1:2331`
-* `Symbol file` (RW or RO ELF): `/path/to/build/<board>/RW/ec.RW.elf`
-* `Path mapping`: Add remote to local source path mapping as described above.
-
-After configuring this if you select the `EC Debug` target in CLion and
-[click the debug icon][CLion Start Remote Debug], CLion and JLink will handle
-automatically flashing the ELF file and stepping through breakpoints in the
-code. Even if not debugging, this may help with your iterative development flow
-since the JLink tool can flash very quickly since it performs a differential
-flash. Note that you still need to recompile after making changes to the source
-code before launching the debugger.
-
-## Using Ozone
-
-Ozone is a free standalone debugger provided by Segger that works with the
-[J-Trace]. You may want to use it if you need more powerful debug features than
-gdbserver can provide. For example, Ozone has a register mapping for the MCUs we
-use, so you can easily inspect CPU registers. It can also be automated with a
-scripting language and show code coverage when used with a [J-Trace] that is
-connected to the trace pins on a board. Note that the Dragonclaw v0.2 uses an
-STM32F412 package that does not have the synchronous trace pins, but the
-[Nucleo STM32F412ZG] does have the trace pins.
-
-[CoreSight Connectors]: http://www2.keil.com/coresight/coresight-connectors
-[FPMCU dev board]: ./fingerprint-dev-for-partners.md#fpmcu-dev-board
-[J-Trace]: https://www.segger.com/products/debug-probes/j-trace/models/j-trace/
-[JLink Software]: https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack
-[Servo Micro]: ./fingerprint-dev-for-partners.md#Servo-Micro
-[JTAG to SWD Adapter]: https://www.adafruit.com/product/2094
-[SWD Cable]: https://www.adafruit.com/product/1675
-[Ozone]: https://www.segger.com/products/development-tools/ozone-j-link-debugger/
-[CLion]: https://www.jetbrains.com/clion/
-[CLion for Chrome OS]: http://go/clion-for-chromeos
-[GDB Remote Debug Configuration]: https://www.jetbrains.com/help/clion/remote-debug.html#remote-config
-[CLion Start Remote Debug]: https://www.jetbrains.com/help/clion/remote-debug.html#start-remote-debug
-[Nucleo STM32F412ZG]: https://www.st.com/en/evaluation-tools/nucleo-f412zg.html
-[Nucleo STM32H743ZI]: https://www.st.com/en/evaluation-tools/nucleo-h743zi.html
-[`.gdbinit`]: /util/gdbinit
-[configure `~/.gdbinit`]: https://www.jetbrains.com/help/clion/configuring-debugger-options.html#gdbinit-lldbinit
-[power pin]: https://www.segger.com/products/debug-probes/j-link/technology/interface-description/
-[fingerprint hardware]: ./fingerprint.md#hardware
-[`flash_jlink.py`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/util/flash_jlink.py
-
-<!-- Images -->
-
-[Dragonclaw with 20-pin SWD]: ../images/dragonclaw_with_20_pin_swd.jpg
-[Dragonclaw with 10-pin SWD]: ../images/dragonclaw_with_10_pin_swd.jpg
-[Icetower with 20-pin SWD]: ../images/icetower_with_20_pin_swd.jpg
diff --git a/docs/fingerprint/fingerprint-dev-for-partners.md b/docs/fingerprint/fingerprint-dev-for-partners.md
deleted file mode 100644
index 2d9332db5b..0000000000
--- a/docs/fingerprint/fingerprint-dev-for-partners.md
+++ /dev/null
@@ -1,657 +0,0 @@
-# FPMCU Development for Partners
-
-This document is intended to help partners (sensor vendors, MCU vendors, etc)
-that are currently (or interested in) developing fingerprint solutions for
-Chromebooks. The document assumes that you're using Linux to do the development;
-preferably a recent version of Ubuntu or Debian. Some partners have had success
-developing in a VM, but please note that we don't test that configuration.
-
-See the [FPMCU documentation] for additional development information.
-
-[TOC]
-
-## Hardware Required for Standalone Development (no Chromebook)
-
-The following hardware components can be used to set up a standalone development
-environment for FPMCU development (i.e., it does not rely on a Chromebook).
-Development for other [EC]s is often done in a similar manner, but some of them
-have their own standalone development or evaluation kits that don't require the
-use of [servo].
-
-You will need an [FPMCU reference board](#fpmcu-dev-board) and a
-[servo debugger](#servo).
-
-### FPMCU board {#fpmcu-dev-board}
-
-The Fingerprint MCU (FPMCU) board has the MCU that handles all
-fingerprint-related functionality (matching, encryption, etc). The fingerprint
-sensor itself connects to the FPMCU board.
-
-This FPMCU board is the Dragonclaw Rev 0.2. |
-------------------------------------------- |
-![Dragonclaw board] |
-
-Download the [Dragonclaw schematics, layout, and BOM][dragonclaw schematics].
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**Googlers**: You can pick up the Dragonclaw development board at Chromestop.
-**Partners**: You can request a Dragonclaw development board from Google.
-***
-
-*** note
-Dragonclaw Rev 0.2 needs a [rework](#dragonclaw-rev-0.2-rework) for the FPC
-sensor to work while being powered through Servo. All of the boards at Chromestop
-have already been reworked.
-***
-<!-- mdformat on -->
-
-This FPMCU board is the Dartmonkey Rev 0.1. |
-------------------------------------------- |
-![Dartmonkey board] |
-
-### Servo
-
-Servo is a general purpose debug board that connects to a header on the FPMCU
-board. Among other things, the servo supplies power to the FPMCU and can be used
-to program the FPMCU, interact with the EC console, take power measurements, and
-debug a running program. It supports SPI, UART, I2C, as well as JTAG/SWD.
-
-There are two different servo debugger setups supported, the
-[Servo Micro](#servo-micro) and the [Servo V2 + Yoshi](#servo-v2-yoshi). The
-servo micro is recommended for its simplicity. It lacks builtin JTAG/SWD support
-for single step debugging, but Dragonclaw v0.2 has an
-[SWD connector](#servo-micro-swd) that can be used.
-
-[Servo Micro](#servo-micro) | [ServoV2 + Yoshi](#servo-v2-yoshi)
---------------------------- | ----------------------------------
-![Servo Micro] | ServoV2 ![Servo v2] Yoshi Flex ![Standard Yoshi Flex]
-
-<!-- mdformat off(b/139308852) -->
-*** note
-For more information about both servos, see [servo].
-***
-<!-- mdformat on -->
-
-### Servo Micro
-
-Unlike the Servo V2, the newer servo micro does not require any adapters to
-interface with the FPMCU board.
-
-As you can see below, one end connects to the FPMCU board and the other connect
-to the developer's computer over micro USB.
-
-![Servo Micro with Dragonclaw]
-
-<!-- mdformat off(b/139308852) -->
-*** note
-For more information about Servo Micro, see [Servo Micro Info].
-***
-<!-- mdformat on -->
-
-#### Using SWD (Optional) {#servo-micro-swd}
-
-Instructions for setup are described in [Fingerprint Debugging].
-
-### Servo V2 + Yoshi
-
-Servo V2 is the original full featured debugger. It requires a
-[Yoshi Flex Cable](#yoshi-flex-cable) to interface with the FPMCU.
-
-![Servo v2]
-
-<!-- mdformat off(b/139308852) -->
-*** note
-NOTE: More information on servo can be found in the [servo] documentation.
-***
-<!-- mdformat on -->
-
-#### Yoshi Flex Cable
-
-The Yoshi Flex cable is used to connect Servo v2 to the FPMCU board. The
-standard cable does not work with SWD, but a simple rework can be performed to
-support SWD.
-
-Standard Yoshi Flex | Yoshi Flex Reworked to Support SWD
----------------------- | -------------------------------------
-![Standard Yoshi Flex] | ![Yoshi Flex Reworked to Support SWD]
-
-Rework steps:
-
-* Remove R18 and R19
-* Wire from Pin 6 of U21 to right side of R18
-* Wire from Pin 6 of U21 to right side of R19
-
-#### Micro USB Cable
-
-A micro USB cable is needed to connect the the servo v2 board to your host Linux
-development machine.
-
-* [Micro USB Cable]
-
-#### Servo V2 Hardware Setup
-
-1. Connect the Yoshi Flex cable to servo, paying attention to the pin
- numbering.
-
- ![Connect Yoshi Flex] ![Another Yoshi Flex image]
-
-2. Connect the other end of the Yoshi Flex cable to the servo header on the
- FPMCU board.
-
- ![Connect Yoshi Flex to FPMCU board] ![Another image]
-
-3. Connect the fingerprint sensor to the header on the FPMCU board.
-
-4. Connect the micro USB cable to servo's `HOST_IN` port. The other end of the
- USB cable should be plugged into your host development machine.
-
- ![Connect USB to Servo]
-
-5. Optional: Connect SWD Debugger
-
- If you want to use SWD for debugging, connect your debugger to the `JTAG`
- header on servo v2.
-
- ![Connect SWD Debugger]
-
-## Software Setup
-
-### Get the Chromium OS source code
-
-* First, make sure you [have the prerequisites].
-* Then [get the source].
-* Create and [enter the `chroot`].
- * You can stop after the `enter the chroot` step.
-
-### Build the [EC]\ (embedded controller) codebase
-
-Open **two** terminals and enter the chroot in each:
-
-```bash
-# from a terminal on your machine
-(outside chroot) $ cd ~/chromiumos/src
-
-# enter the chroot (the flag is important)
-(outside chroot) $ cros_sdk --no-ns-pid
-```
-
-<!-- mdformat off(b/139308852) -->
-*** note
-NOTE: More information on servo can be found in the [servo] documentation.
-***
-<!-- mdformat on -->
-
-In one of the terminals, build and start `servod`
-
-Build and install `servod` in the chroot:
-
-```bash
-(chroot) $ sudo emerge hdctools
-```
-
-<!-- mdformat off(b/139308852) -->
-*** note
-In all of the following commands, replace `<BOARD>` in the command with
-`bloonchipper` or `dartmonkey` depending on the development board you are using.
-***
-<!-- mdformat on -->
-
-Run `servod`:
-
-```bash
-(chroot) $ sudo servod --board=<BOARD>
-```
-
-You should see something like this. Leave it running:
-
-```bash
-2019-04-11 15:21:53,715 - servod - INFO - Start
-2019-04-11 15:21:53,765 - servod - INFO - Found servo, vid: 0x18d1 pid: 0x5002 sid: 911416-00789
-2019-04-11 15:21:53,766 - servod - INFO - Found XML overlay for board zerblebarn
-2019-04-11 15:21:53,766 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_v2_r1.xml, None, 0)
-2019-04-11 15:21:53,767 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_v2_r0.xml, None, 0)
-2019-04-11 15:21:53,771 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/common.xml, None, 0)
-2019-04-11 15:21:53,772 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/power_tools.xml, None, 0)
-2019-04-11 15:21:53,774 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/keyboard.xml, None, 0)
-2019-04-11 15:21:53,775 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/uart_common.xml, None, 0)
-2019-04-11 15:21:53,777 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/ftdii2c_cmd.xml, None, 0)
-2019-04-11 15:21:53,777 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/usb_image_management.xml, None, 0)
-2019-04-11 15:21:53,784 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servo_zerblebarn_overlay.xml, None, 0)
-2019-04-11 15:21:53,785 - SystemConfig - INFO - Loading XML config (/usr/lib64/python2.7/site-packages/servo/data/servoflex_v2_r0_p50.xml, None, 0)
-2019-04-11 15:21:53,792 - Servod - INFO - Initializing interface 1 to ftdi_empty
-2019-04-11 15:21:53,792 - Servod - INFO - Initializing interface 2 to ftdi_i2c
-2019-04-11 15:21:53,795 - Servod - INFO - Initializing interface 3 to ftdi_uart
-2019-04-11 15:21:53,799 - Servod - INFO - /dev/pts/8
-2019-04-11 15:21:53,799 - Servod - INFO - Initializing interface 4 to ftdi_uart
-2019-04-11 15:21:53,802 - Servod - INFO - /dev/pts/9
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 5 to ftdi_empty
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 6 to ftdi_empty
-2019-04-11 15:21:53,802 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,802 - Servod - INFO - Initializing interface 7 to ftdi_uart
-2019-04-11 15:21:53,805 - Servod - INFO - /dev/pts/10
-2019-04-11 15:21:53,805 - Servod - INFO - Use the next FTDI part @ pid = 0x5003
-2019-04-11 15:21:53,805 - Servod - INFO - Initializing interface 8 to ftdi_uart
-2019-04-11 15:21:53,808 - Servod - INFO - /dev/pts/11
-2019-04-11 15:21:53,808 - Servod - INFO - Initializing interface 9 to ec3po_uart
-2019-04-11 15:21:53,811 - PD/Cr50 - EC3PO Interface - INFO - -------------------- PD/Cr50 console on: /dev/pts/12
-2019-04-11 15:21:53,811 - Servod - INFO - Initializing interface 10 to ec3po_uart
-2019-04-11 15:21:53,812 - EC - EC3PO Interface - INFO - -------------------- EC console on: /dev/pts/14
-2019-04-11 15:21:54,316 - Servod - INFO - Initialized i2c_mux to rem
-2019-04-11 15:21:54,317 - Servod - INFO - Initialized i2c_mux_en to on
-2019-04-11 15:21:54,319 - Servod - INFO - Initialized pch_disable to off
-2019-04-11 15:21:54,320 - Servod - INFO - Initialized jtag_buf_on_flex_en to off
-2019-04-11 15:21:54,321 - Servod - INFO - Initialized cold_reset to off
-2019-04-11 15:21:54,322 - Servod - INFO - Initialized warm_reset to off
-2019-04-11 15:21:54,323 - Servod - INFO - Initialized spi1_buf_on_flex_en to off
-2019-04-11 15:21:54,324 - Servod - INFO - Initialized spi_hold to off
-2019-04-11 15:21:54,326 - Servod - INFO - Initialized pwr_button to release
-2019-04-11 15:21:54,327 - Servod - INFO - Initialized lid_open to yes
-2019-04-11 15:21:54,328 - Servod - INFO - Initialized spi2_buf_on_flex_en to off
-2019-04-11 15:21:54,330 - Servod - INFO - Initialized rec_mode to off
-2019-04-11 15:21:54,331 - Servod - INFO - Initialized fw_up to off
-2019-04-11 15:21:54,332 - Servod - INFO - Initialized usb_mux_sel1 to dut_sees_usbkey
-2019-04-11 15:21:54,333 - Servod - INFO - Initialized prtctl4_pwren to on
-2019-04-11 15:21:54,334 - Servod - INFO - Initialized uart3_en to on
-2019-04-11 15:21:54,334 - Servod - INFO - Initialized dut_hub_pwren to on
-2019-04-11 15:21:54,335 - Servod - INFO - Initialized kbd_en to off
-2019-04-11 15:21:54,337 - Servod - INFO - Initialized spi1_vref to pp3300
-2019-04-11 15:21:54,338 - Servod - INFO - Initialized spi2_vref to pp1800
-2019-04-11 15:21:54,339 - Servod - INFO - Initialized uart2_en to on
-2019-04-11 15:21:54,340 - Servod - INFO - Initialized uart1_en to on
-2019-04-11 15:21:54,341 - Servod - INFO - Initialized jtag_buf_en to off
-2019-04-11 15:21:54,342 - Servod - INFO - Initialized fw_wp_en to off
-2019-04-11 15:21:54,343 - Servod - INFO - Initialized sd_vref_sel to off
-2019-04-11 15:21:54,343 - Servod - INFO - Initialized ec_ec3po_interp_connect to on
-2019-04-11 15:21:54,344 - Servod - INFO - Initialized uart3_vref to off
-2019-04-11 15:21:54,345 - Servod - INFO - Initialized jtag_vref_sel0 to pp3300
-2019-04-11 15:21:54,346 - Servod - INFO - Initialized jtag_vref_sel1 to pp3300
-2019-04-11 15:21:54,346 - Servod - INFO - Initialized fpmcu_ec3po_interp_connect to on
-2019-04-11 15:21:54,349 - ServoDeviceWatchdog - INFO - Watchdog setup for devices: set([(6353, 20482, '911416-00789')])
-2019-04-11 15:21:54,351 - servod - INFO - Listening on localhost port 9999
-```
-
-In the other terminal, build and flash the firmware:
-
-Navigate to the EC source:
-
-```bash
-(chroot) $ cd ../platform/ec
-```
-
-Build the firmware:
-
-```bash
-(chroot) $ make BOARD=<BOARD> -j
-```
-
-The resulting file will be in `build/<BOARD>/ec.bin`
-
-Flash the firmware file:
-
-```bash
-(chroot) $ ./util/flash_ec --board=<BOARD> --image=./build/<BOARD>/ec.bin
-```
-
-Prepare a serial terminal in your chroot:
-
-```bash
-(chroot) $ sudo emerge screen
-```
-
-Connect to the UART pty:
-
-```bash
-(chroot) $ sudo screen $(dut-control raw_fpmcu_console_uart_pty | cut -d: -f2)
-```
-
-Press enter key several times (may need to wait up to 20 seconds). Then you will
-see a prompt:
-
-```
->
-```
-
-At this point you are connected to the MCU's serial (UART) console. You can list
-all of the available console commands with "help":
-
-```
-> help
-```
-
-```bash
-Known commands:
-  chan           fpcapture      hcdebugsherase     fpenroll       history        spixfer        waitms
-  flashinfo      fpmatch        hostevent      sysinfo
-  flashread      gettime        md             sysjump
-  flashwp        gpioget        panicinfo      syslock
-  flashwrite     gpioset        reboot         taskinfo
-HELP LIST = more info; HELP CMD = help on CMD.
-```
-
-Start a fingerprint enrollment:
-
-```
-> fpenroll
-```
-
-### Measuring Power {#measure-power}
-
-The Dragonclaw reference board has an onboard INA that monitors the voltage and
-power draw of the MCU and FP Sensor independently.
-
-Signal Name | Description
---------------- | -------------------------------------
-`pp3300_dx_mcu` | 3.3V supplying the MCU
-`pp3300_dx_fp` | 3.3V supplying the fingerprint sensor
-`pp1800_dx_fp` | 1.8V supplying the fingerprint sensor
-
-You can monitor all power and voltages by using the following command:
-
-```bash
-(chroot) $ watch -n0.5 dut-control pp3300_dx_mcu_mv pp3300_dx_fp_mv pp1800_dx_fp_mv pp3300_dx_mcu_mw pp3300_dx_fp_mw pp1800_dx_fp_mw
-```
-
-You can get a summary of the power over `N` seconds with:
-
-```bash
-(chroot) $ dut-control -t N pp3300_dx_mcu_mv pp3300_dx_fp_mv pp1800_dx_fp_mv pp3300_dx_mcu_mw pp3300_dx_fp_mw pp1800_dx_fp_mw
-```
-
-<!-- mdformat off(b/139308852) -->
-*** note
-The `_mv` suffix denotes millivolt and `_mw` suffix denotes milliwatt.
-***
-
-*** note
-See [Power Measurement Documentation] for more information.
-***
-<!-- mdformat on -->
-
-### Toggling Hardware Write Protect
-
-When using a fingerprint development board connected to servo, you can toggle
-hardware write protect for testing.
-
-**NOTE**: `servod` must be running.
-
-Check the state of hardware write protect:
-
-```bash
-(chroot) $ dut-control fw_wp_en
-```
-
-Enable hardware write protect:
-
-```bash
-(chroot) $ dut-control fw_wp_en:on
-```
-
-Disable hardware write protect:
-
-```bash
-(chroot) $ dut-control fw_wp_en:off
-```
-
-### Contributing Changes
-
-#### Using Gerrit and git
-
-If you’re not familiar with `git`, Gerrit (code review) and `repo`, here are
-some docs to help you get started:
-
-* [Git and Gerrit Intro for Chromium OS]: Useful to get started as quickly as
- possible, but does not explain how `git` works under the hood.
-* [Set your editor]: Use your favorite editor when writing `git` commit
- messages.
-* [Chromium OS Contributing Guide]: Detailed overview of contributing changes
- to Chromium OS and the workflow we use.
-* [Git: Concepts and Workflow]: Good overview of how `git` actually works.
-* [Gerrit: Concepts and Workflow]: Good overview of how Gerrit works; assumes
- you understand `git` basics.
-* [Life of a patch]: Android workflow, but similar to Chrome OS.
-
-The Gerrit dashboard that will show your pending reviews (and ones we have for
-you):
-
-* [Public Gerrit]
-* [Internal Gerrit]
-
-#### Registering for a chromium.org *Internal* Account
-
-If your partnership agreement requires non-public code sharing you will need to
-register for an account on the [Internal Gerrit]. Refer to the
-[Gerrit Credentials Setup] page for details. Once you register for an internal
-account, your contact at Google can make sure you have the necessary permissions
-to access the private repository.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: In order to use a private repository you will have to manually add it
-to the repo manifest file before running `repo sync`. Check with your contact
-at Google for the exact values to use below:
-
-**`(outside) $ ~/chromiumos/.repo/manifests/default.xml`**
-
-```xml
-<project remote="cros-internal"
- path="CHECK WITH GOOGLE"
- groups="firmware"
- name="CHECK WITH GOOGLE" />
-```
-
-**`(outside) $ ~/chromiumos/.repo/manifests/remote.xml`**
-
-```xml
-<remote name="cros-internal"
- fetch="https://chrome-internal.googlesource.com"
- review="https://chrome-internal-review.googlesource.com" />
-```
-***
-<!-- mdformat on -->
-
-### Tracking Issues and Communication
-
-Development issue tracking and communication is done through the
-[Partner Issue Tracker]. You will use your [Partner Domain] account to access
-the [Partner Issue Tracker]. If you do not already have a [Partner Domain]
-account, please request one from your Google contact.
-
-In order to make sure that you receive email notifications for issues, please
-make sure that you [set up email forwarding] and set your
-[notification settings] appropriately. Communication should primarily be done
-through the [Partner Issue Tracker] and not email so that it can be more easily
-tracked by multiple people and a record is preserved for posterity.
-
-[Partner Issue Tracker]: https://developers.google.com/issue-tracker/guides/partner-access
-[Partner Domain]: https://developers.google.com/issue-tracker/guides/partner-domains
-[set up email forwarding]: https://developers.google.com/issue-tracker/guides/partner-domains#email_forwarding
-[notification settings]: https://developers.google.com/issue-tracker/guides/set-notification-preferences
-
-## Working with Chromebooks
-
-Chromebooks have an FPMCU (e.g., Dragonclaw) board attached to the motherboard.
-You can use the device to run `ectool` commands and test the fingerprint sensor
-from the UI.
-
-### Developer Mode and Write Protection
-
-Make sure that your fingerprint-equipped Chrome OS device is in [developer mode]
-with a *test* image flashed and [hardware write protection] disabled. Using the
-test image will allow you to SSH into the device and disabling hardware write
-protection allows you to have full access to flashing the FPMCU firmware.
-
-See [Installing Chromium] for details on flashing test images and enabling
-[developer mode].
-
-### Connecting
-
-In general, most of our development is done by connecting to the DUT (device
-under test) via SSH. We usually connect the DUT to ethernet (e.g., via USB-C to
-Ethernet converter), but WiFi should also work (assuming corporate firewall
-restrictions don’t block SSH port 22). To get the IP address, tap the
-battery/time icon in the lower right corner. Then tap on “Ethernet” followed by
-the gear icon in the upper right.
-
-```bash
-(chroot) $ ssh root@<IP_ADDRESS>
-Password: test0000
-```
-
-Once you have SSH’ed into the DUT, you should be able to run `ectool` commands.
-
-**Example**: Capture a "test_reset" image from the sensor and write it to a
-[PNM] file (viewable with the ImageMagick `display` command):
-
-```bash
-(device) $ ectool --name=cros_fp fpmode capture test_reset; ectool --name=cros_fp waitevent 5 500; ectool --name=cros_fp fpframe > /tmp/test_reset.pnm
-```
-
-Alternatively, you can access a shell via the UI on device by pressing
-`CTRL+ALT+F2` (third key on top row). Log in with `root` and `test0000`.
-
-### Flashing FPMCU from DUT
-
-Copy the firmware to the DUT:
-
-```bash
-(chroot) $ scp ./build/bloonchipper/ec.bin <DUT_IP>:/tmp/ec.bin
-```
-
-From the DUT, flash the firmware you copied:
-
-```bash
-(device) $ flash_fp_mcu /tmp/ec.bin
-```
-
-## Commit-queue Prototype Environment
-
-![CQ Prototype Environment]
-
-## Troubleshooting
-
-### Dragonclaw Rev 0.2 Rework {#dragonclaw-rev-0.2-rework}
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: All Dragonclaw v0.2 boards have been reworked, so it is not necessary
-to perform the rework yourself.
-***
-<!-- mdformat on -->
-
-Dragonclaw **Rev 0.2** has two load switches (`U4` and `U6`) that enable the
-1.8V power rail from the servo connector or motherboard connector. However, this
-switch is not compatible with 1.8V, so will always output 0V.
-
-The [rework document][Dragonclaw Rev 0.2 1.8V Rework] describes replacing these
-two switches with ones compatible with 1.8V.
-
-### Dragonclaw Rev 0.1 Servo Fix
-
-Dragonclaw **Rev 0.1** has a known issue with UART and JTAG. Most notably, this
-issue causes servo micro to fail to program the FPMCU over UART.
-
-This issue can be fixed with the following rework steps:
-
-* Connect servo header pin 13 to pin 18
-* Connect servo header pin 13 to pin 29
-
-![Dragonclaw servo fix diagram]
-
-### Verify that servo and debugger are connected to USB {#servo-connected}
-
-Check whether servo is enumerating on USB. If you are using a debugger
-(Lauterbach, J-Link, etc), also check to make sure it enumerates. Depending on
-the debugger being used, it may need to be powered with an external power
-supply.
-
-```bash
-(chroot) $ lsusb
-
-Bus 002 Device 003: ID 0897:0004 Lauterbach # ← This is my Lauterbach (debugger)
-Bus 001 Device 013: ID 18d1:5002 Google Inc. # ← This is servo
-```
-
-### "No servos found" when running servod
-
-If you get the following message, make sure that
-[servo is connected to USB](#servo-connected). You may also want to try
-restarting your machine (or VM).
-
-```bash
-(chroot) $ sudo servod --board=bloonchipper
-2019-04-12 14:53:42,236 - servod - INFO - Start
-2019-04-12 14:53:42,270 - servod - ERROR - No servos found
-```
-
-### Losing characters in servo UART console
-
-Make sure that this interface is disabled:
-
-```bash
-(chroot) $ dut-control usbpd_ec3po_interp_connect:off
-```
-
-### FPMCU console commands
-
-* Once the console is working you can use `help` to see the commands.
-* There should be fingerprint commands that start with `fp` (see `fpsensor.c`
- in the [EC] code).
-
-<!-- Links -->
-
-[EC]: https://chromium.googlesource.com/chromiumos/platform/ec
-[ectool_servo_spi]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/util/comm-servo-spi.c#15
-[servo]: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/HEAD/README.md
-[developer mode]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/debug_buttons.md#firmware-keyboard-interface
-[hardware write protection]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/write_protection.md
-[have the prerequisites]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#Prerequisites
-[get the source]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#get-the-source
-[enter the `chroot`]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#building-chromium-os
-[Chromium OS Contributing Guide]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/contributing.md
-[Servo Micro Info]: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/HEAD/docs/servo_micro.md
-[Set your editor]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#Set-your-editor
-[Life of a patch]: https://source.android.com/setup/contribute/life-of-a-patch
-[Git: Concepts and Workflow]: https://docs.google.com/presentation/d/1IQCRPHEIX-qKo7QFxsD3V62yhyGA9_5YsYXFOiBpgkk/
-[Gerrit: Concepts and Workflow]: https://docs.google.com/presentation/d/1C73UgQdzZDw0gzpaEqIC6SPujZJhqamyqO1XOHjH-uk/
-[Public Gerrit]: https://chromium-review.googlesource.com
-[Power Measurement Documentation]: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/HEAD/docs/power_measurement.md
-[Internal Gerrit]: https://chrome-internal-review.googlesource.com
-[Gerrit Credentials Setup]: https://www.chromium.org/chromium-os/developer-guide/gerrit-guide
-[Micro USB Cable]: https://www.monoprice.com/product?p_id=9762
-[PNM]: https://en.wikipedia.org/wiki/Netpbm_format
-[Git and Gerrit Intro for Chromium OS]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/git_and_gerrit_intro.md
-[Installing Chromium]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#installing-chromium-os-on-your-device
-[FPMCU documentation]: ./fingerprint.md
-[Fingerprint Debugging]: ./fingerprint-debugging.md
-[dragonclaw schematics]: ../schematics/dragonclaw
-
-<!-- Images -->
-
-[Servo Micro]: ../images/servo_micro.jpg
-[Servo Micro with Dragonclaw]: ../images/servomicro_dragonclaw.jpg
-[Servo v2]: ../images/servo_v2.jpg
-[Standard Yoshi Flex]: ../images/yoshi_flex.jpg
-[Yoshi Flex Reworked to Support SWD]: ../images/yoshi_flex_swd_rework.jpg
-[Dragonclaw board]: ../images/dragonclaw_rev_0.2.jpg
-[Dragonclaw servo fix diagram]: ../images/dragonclaw_servo_fix.jpg
-[Connect USB to Servo]: ../images/servo_v2_with_micro_usb.jpg
-[Connect Yoshi Flex]: ../images/servo_v2_with_yoshi_flex.jpg
-[Another Yoshi Flex image]: ../images/servo_v2_with_yoshi_flex2.jpg
-[Connect Yoshi Flex to FPMCU board]: ../images/dragonclaw_yoshi_flex_header.jpg
-[Another image]: ../images/dragonclaw_yoshi_flex_header2.jpg
-[Connect SWD Debugger]: ../images/servo_v2_jtag_header.jpg
-[Dartmonkey board]: ../images/dartmonkey.jpg
-
-<!-- If you make changes to the docs below make sure to regenerate the JPEGs by
- appending "export/pdf" to the Google Drive link. -->
-
-<!-- https://docs.google.com/drawings/d/1YhOUD-Qf69NUdugT6n0cX7o7CWvb5begcdmJwv7ch6I -->
-
-[Dragonclaw Rev 0.2 1.8V Rework]: https://github.com/coreboot/chrome-ec/blob/master/docs/images/dragonclaw_rev_0.2_1.8v_load_switch_rework.pdf
-
-<!-- https://docs.google.com/drawings/d/1w2qbb4AsSxY-KTK2vXZ6TKeWHveWvS3Dkgh61ocu0wc -->
-
-[CQ Prototype Environment]: ../images/CQ_Prototype_Environment.jpg
diff --git a/docs/fingerprint/fingerprint-factory-quick-guide.md b/docs/fingerprint/fingerprint-factory-quick-guide.md
deleted file mode 100644
index c9478bf99a..0000000000
--- a/docs/fingerprint/fingerprint-factory-quick-guide.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# Chrome OS Fingerprint Sensor: Quick Factory Guide
-
-The goal of this document is to outline how ODM partners can make use of the
-existing Chrome OS factory scripts to meet Chrome OS FPS factory requirements.
-
-[TOC]
-
-## Factory Requirements
-
-### Flash firmware for fingerprint sensor microcontroller (FPMCU)
-
-FPMCU firmware must be flashed before fingerprint functional test is run. ODM
-partners may work with the module house to preflash FPMCU firmware before
-factory SMT. However, this way ODM partners have to coordinate with the module
-house to make sure the preflash FPMCU firmware blob is extracted from the FSI
-release image (from /opt/google/biod/fw/). If the FPMCU firmware doesn’t match
-the FPMCU firmware blob checked into the release image, the end users will see
-the ‘critical update’ screen in their out-of-box experience, because
-bio\_fw\_updater tries to update FPMCU firmware at boot time. This is a bad user
-experience we want to avoid. Most importantly, in PVT/MP build, only the FPMCU
-firmware in the release image would be signed by MP key. So you **MUST** ensure
-FPMCU is flashed with the MP-signed firmware blob extracted from FSI, before
-shipping the devices.
-
-As opposed to pre-flashing FPMCU in the module house, ODM partners are
-encouraged to make use of
-[update\_fpmcu\_firmware.py](https://chromium.googlesource.com/chromiumos/platform/factory/+/e5e903d0a0d8327dd8b9e47d2c808fd845ed73a4/py/test/pytests/update_fpmcu_firmware.py)
-to update FPMCU firmware in the factory flow. This script can detect fingerprint
-MCU board name, find the right FPMCU firmware blob for the DUT from the release
-partition, and then flash FPMCU by flash\_fp\_mcu tool. Please note that this
-script may take more than 30 secs to complete, which is slow.
-
-Since bio\_fw\_update has been disabled in factory test image via
-[crrev/c/1913645](https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1913645),
-in the factory flow, the FPMCU firmware should not be overwritten by
-boot-update-firmware service during reboot.
-
-### Run fingerprint sensor functional test
-
-Please add
-[fingerprint\_mcu.py](https://chromium.git.corp.google.com/chromiumos/platform/factory/+/a283609cd8446ba4a4b75c2e1d84c9ba24ea8422/py/test/pytests/fingerprint_mcu.py)
-to your device test list. A more detailed description about this test can be
-found
-[here](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/fingerprint/fingerprint-factory-requirements.md).
-
-### Initialize FPMCU entropy in factory finalization
-
-The support for FPMCU entropy initialization has been integrated into the
-factory finalization script. So FPMCU entropy should be automatically
-initialized in factory finalization, if a FPMCU is found on DUT. Note that FPMCU
-entropy initialization would fail if rollback\_block\_id is not equal to zero,
-which means the entropy has been initialized before. It is usually caused by
-biod trying to initialize FPMCU entropy and increment rollback\_block\_id at
-boot time. Since we have disabled biod and bio\_crypto\_init in factory test
-image via
-[crrev/c/1910290](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1910290),
-we expect rollback\_block\_id would stay zero during the factory flow, and FPMCU
-entropy initialization should succeed in factory finalization. So just run
-factory finalization as any other CrOS boards.
-
-### Enable FPMCU software write protection (SWWP) in factory finalization in PVT/MP
-
-The support for FPMCU SWWP has been integrated into factory finalization script.
-So FPMCU SWWP should be automatically enabled in factory finalization together
-with AP/EC SWWP when write\_protection arg is set to true and a FPMCU is found
-on DUT. Just run factory finalization as any other CrOS boards.
-
-### Reset entropy for factory re-finalization (in case of RMA or OQC)
-
-For the boards that have been finalized, FPMCU entropy has been initialized. So
-running re-finalization for those boards are expected to fail at FPMCU entropy
-initialization. Before running re-finalization for those boards, ODM partners
-have to remove hardware write protection (HWWP) and then run
-[update\_fpmcu\_firmware.py](https://chromium.googlesource.com/chromiumos/platform/factory/+/d399a0a1bdeb7249de2721b269e7365e4486e23c/py/test/pytests/update_fpmcu_firmware.py)
-to reset rollback\_block\_id and entropy. So the follow-up re-finalization
-(which re-initialize entropy) can succeed.
-
-## References
-
-* CrOS fingerprint factory requirements:
- [doc link](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/fingerprint/fingerprint-factory-requirements.md)
-* The summary of CLs:
- * Add a factory script to update FPMCU firmware:
- [crrev/c/1918679](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1918679),
- [crrev/c/1913493](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1913493),
- [crrev/c/1927149](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1927149),
- [crrev/c/1984618](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1984618),
- [crrev/c/2036574](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/2036574)
- * Disable FPS-related services that will interfere with the factory flow:
- [crrev/c/1913645](https://chromium-review.googlesource.com/c/chromiumos/platform2/+/1913645),
- [crrev/c/1910290](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1910290)
- * Support FPMCU in factory finalization:
- [crrev/c/1868795](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1868795),
- [crrev/c/1902267](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1902267),
- [crrev/c/1900503](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1900503),
- [crrev/c/1925927](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1925927),
- [crrev/c/1948163](https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/1948163)
diff --git a/docs/fingerprint/fingerprint-factory-requirements.md b/docs/fingerprint/fingerprint-factory-requirements.md
deleted file mode 100644
index 0fc99e2740..0000000000
--- a/docs/fingerprint/fingerprint-factory-requirements.md
+++ /dev/null
@@ -1,502 +0,0 @@
-# Chrome OS Fingerprint Factory Requirements
-
-This document provides an overview of factory requirements and testing for the
-fingerprint sensor.
-
-[TOC]
-
-## Contact
-
-For questions regarding this document, please contact the
-[Chrome OS Fingerprint Team].
-
-## Terminology
-
-* `AP`: Application Processor.
-* `FPMCU`: Fingerprint Microcontroller.
-* `FATP`: Final Assembly, Test, and Pack
-* `FP sensor`: Fingerprint sensor. Directly connected to the FPMCU, not the
- AP.
-* `firmware`: Software that runs on the FPMCU.
-* `finalization`: Process that is run in the factory before the device being
- built leaves the factory.
-* `entropy`: Cryptographically secure random bytes stored in FPMCU flash. Used
- for encrypting/decrypting fingerprint templates.
-* `software write protect`: Prevents the RO portion of the FPMCU’s flash from
- being overwritten. Full details in [EC docs][Software Write Protect].
-* `ITS`: In-Device Test Specification.
-* `MTS`: Module Test Specification.
-* `MQT`: Module Quality Test.
-* `MQT2`: Module Quality Test 2.
-
-## Documents
-
-* [FPC1025: Module Test Specification]
-* [FPC1145: Module Test Specification]
-* [FPC In-Device Test Specification]
-* [Factory Fingerprint Sensor Testing for `nocturne` ]
-
-## FPMCU Firmware Location
-
-The binaries for the FPMCU firmware are located in `/opt/google/biod/fw`. Now
-that Chrome OS supports unibuild, there may be multiple firmware binaries in the
-directory since multiple sensors may be used across a single "board" (e.g., the
-`hatch` board can use either `bloonchipper` or `dartmonkey`).
-
-The correct firmware type to use for a given board can be discovered with the
-[Chrome OS Config] tool:
-
-```bash
-(dut) $ cros_config /fingerprint board
-dartmonkey
-```
-
-OR
-
-```bash
-(chroot) $ cros_config_host -c /build/<BOARD>/usr/share/chromeos-config/yaml/config.yaml -m <MODEL> get /fingerprint board
-dartmonkey
-```
-
-The corresponding firmware for the above command would be
-`/opt/google/biod/fw/dartmonkey_*.bin`.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: If you get an empty response when running the above commands, the
-Chrome OS Config settings may not have been updated for the Chrome OS board.
-See the instructions on [updating Chrome OS Config] for fingerprint.
-***
-<!-- mdformat on -->
-
-Note that the fingerprint team continuously releases updates to the firmware, so
-SIEs should watch for version changes in ToT if they are maintaining a separate
-factory branch.
-
-## Flashing the FPMCU
-
-When the FPMCU is completely blank a low-level flashing tool must be used to
-program an initial version of the FPMCU firmware. It’s possible to use the
-[`flash_fp_mcu`] script as this low-level flashing tool, though since it
-requires the AP and is not necessarily robust against failures, it is not
-recommended for mass-production. More details about [`flash_fp_mcu`] are in the
-[Fingerprint flashing documentation].
-
-The initial version of the FPMCU firmware should be flashed either by the module
-house or by the factory. Once an initial version of the FPMCU firmware has been
-flashed (i.e., the FPMCU is not blank), the `bio_fw_updater` tool runs on
-startup and handles updating the FPMCU firmware to match the version that is in
-the rootfs. Note that this update process can take around 30 seconds; if that
-length of time is an issue then the factory or module house should pre-flash the
-latest firmware beforehand.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: If the FPMCU is not flashed in the factory as part of development
-builds (EVT, etc.), it's possible for developers (or Chromestop) to manually
-run [`flash_fp_mcu`], as long as they can disable [hardware write protect].
-Obviously this only applies during development, not mass production.
-***
-<!-- mdformat on -->
-
-## biod and timberslide
-
-Since `biod` communicates with the FPMCU, it’s best to disable it when running
-the fingerprint factory tests. This can be done with upstart:
-
-```bash
-(dut) $ stop biod
-```
-
-Once testing is complete `biod` should be restarted (or you can reboot the
-device).
-
-`timberslide` is the daemon that periodically sends commands to the FPMCU to
-read the latest FPMCU logs. It writes the results to `/var/log/cros_fp.log`. It
-should be fine to leave running during tests, though it should be stopped before
-running the [`flash_fp_mcu`] script, since that script erases the entire FPMCU:
-
-```bash
-(dut) $ stop timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log
-```
-
-## Factory Tests
-
-### Fingerprint Sensor (standalone module)
-
-When using an FPC sensor (e.g., FPC 1025, FPC 1145), the fingerprint sensor
-itself must be tested by the module manufacturer with FPC’s tools. FPC provides
-a Module Test Tool (MTT), which requires additional hardware (FPC Module Test
-Card). FPC also provides design drawings for the rubber stamp. The stamp,
-test-fixture and test station need to be implemented by the OEM/ODM/Module House
-(often only module house).
-
-The `MTS` _must_ be followed by the module manufacturer, but Google does not
-provide direct support for this testing. FPC is the main point of contact.
-
-The module testing procedure is documented in the following:
-
-[FPC1025: Module Test Specification]
-
-[FPC1145: Module Test Specification]
-
-### Fingerprint Sensor + FPMCU (in device)
-
-In-device tests are run during the `FATP` process once the device has been fully
-assembled. Google provides source code for these tests in
-[`fingerprint_mcu.py`].
-
-Hardware Required: Chrome OS DUT before finalization.
-
-Documentation: [FPC In-Device Test Specification]
-
-#### Test Image Checkerboard and Inverted Checkerboard Test (CB/ICB)
-
-##### Purpose
-
-Capture a checkerboard (and inverted checkerboard) pattern and verify that the
-values of the individual pixels do not deviate from the median.
-
-##### Implementation
-
-Use `ectool` to capture the first checkerboard pattern image:
-
-```bash
-(dut) $ ectool --name=cros_fp fpmode capture pattern0; ectool --name=cros_fp waitevent 5 500
-FP mode: (0x20000008) capture
-MKBP event 5 data: 00 00 00 80
-```
-
-Copy the first checkerboard image to a file:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe > /tmp/pattern0.pnm
-```
-
-Use `ectool` to capture the second checkerboard pattern image:
-
-```bash
-(dut) $ ectool --name=cros_fp fpmode capture pattern1; ectool --name=cros_fp waitevent 5 500
-FP mode: (0x30000008) capture
-MKBP event 5 data: 00 00 00 80
-```
-
-Copy the second checkerboard image to a different file:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe > /tmp/pattern1.pnm
-```
-
-Perform median analysis on the resulting image as described in the `MTS`
-document. The factory toolkit does this in
-[`fingerprint_mcu.py`][Checkerboard Test].
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**TIP**: You can view the `.pnm` files generated by the commands below on your
-Linux desktop with ImageMagick: `display /path/to/file.pnm`.
-***
-<!-- mdformat on -->
-
-##### Success/Failure
-
-The median pixel value (type 1 and type 2), pixel errors, finger detect zone
-errors, and pixel error deviation limit must fall within the acceptance criteria
-limits specified in "4.3.5 Acceptance Criteria Test Image CB / iCB" in the `MTS`
-document for the sensor being tested.
-
-#### Hardware Reset Test (aka IRQ test)
-
-##### Purpose
-
-Perform a hardware reset of the sensor and test that the IRQ line is asserted
-after 5 ms. See "Section 4.1 Reset test pattern procedure" and "2.8 HW Reset" in
-the FPC `MTS` document for the sensor being tested.
-
-##### Implementation
-
-This is implemented by the FPMCU on every boot. The results can be checked with
-the `ectool` command. The factory toolkit does this in
-[`fpmcu_utils.py`][GetSensorIdErrors].
-
-##### Success/Failure
-
-The `Error flags` line of the `fpinfo` `ectool` command must be empty.
-
-```bash
-(dut) $ ectool --name=cros_fp fpinfo
-
-Fingerprint sensor: vendor 20435046 product 9 model 1401 version 1
-Image: size 56x192 8 bpp
-Error flags:
-Dead pixels: UNKNOWN
-Templates: version 4 size 47616 count 0/5 dirty bitmap 0
-```
-
-#### Hardware ID (HWID) check
-
-##### Purpose
-
-Ensure that communications between the sensor and the FPMCU are working and that
-the correct sensor has been assembled.
-
-##### Implementation
-
-`ectool` can be used to request the hardware ID, which can be compared with the
-expected hardware ID. The factory toolkit does this in
-[`fpmcu_utils.py`][GetSensorId].
-
-##### Success/Failure
-
-The `Fingerprint sensor` line of the `fpinfo` `ectool` command must show the
-expected ID and the `Error flags` line must be empty:
-
-```bash
-(dut) $ ectool --name=cros_fp fpinfo
-
-Fingerprint sensor: vendor 20435046 product 9 model 1401 version 1 # FPC 1145
-Image: size 56x192 8 bpp
-Error flags:
-Dead pixels: UNKNOWN
-Templates: version 4 size 47616 count 0/5 dirty bitmap 0
-```
-
-#### Reset Pixel (RP)
-
-##### Purpose
-
-Capture a white image, compare the individual pixel values and ensure that the
-deviation to the median is within the specified range.
-
-##### Implementation
-
-Capture the test image with `ectool` and analyze the output. The factory toolkit
-does this in [`fingerprint_mcu.py`][ProcessResetPixelImage].
-
-Switch to correct capture mode and wait:
-
-```bash
-(dut) $ ectool --name=cros_fp fpmode capture test_reset; ectool --name=cros_fp waitevent 5 500
-FP mode: (0x50000008) capture
-MKBP event 5 data: 00 00 00 80
-```
-
-Retrieve the test image:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe > /tmp/test_reset.pnm
-```
-
-##### Success/Failure
-
-A pixel is considered to be a bad pixel ("reset pixel error") if the value read
-out deviates more than a defined value from the median. The median value and the
-max number of pixels that have "reset pixel error" are defined in section "Reset
-Pixel" (4.4 or 4.5) of the MTS for the given sensor.
-
-#### Module Quality Test (or Module Quality Test 2) with Rubber Stamp Zebra (Optional)
-
-##### Purpose
-
-The Module Quality Test (`MQT`) uses a rubber stamp with a "zebra" pattern to
-characterize module performance and image quality after the top layer (including
-stack-up) is applied. Although this test is optional, OEMs are strongly
-encouraged to perform it.
-
-##### Implementation
-
-Capture the image when the rubber stamp is applied:
-
-```bash
-(dut) $ ectool --name=cros_fp fpmode capture qual
-FP mode: (0x40000008) capture
-```
-
-Wait for the capture to be finished, timeout after 10s:
-
-```bash
-(dut) $ ectool --name=cros_fp waitevent 5 10000
-MKBP event 5 data: 00 00 00 80
-```
-
-Copy the raw captured from to the AP:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe raw > /tmp/fp.raw
-```
-
-Run the analysis tool on the captured frame:
-
-```bash
-(dut) $ /usr/local/opt/fpc/fputils.py --mqt /tmp/fp.raw
-Error, MQT status : (5)
-MQT failed (-1)
-```
-
-The factory toolkit does this in [`fingerprint_mcu.py`][rubber_finger_present].
-
-##### Success/Failure
-
-See "Section 5.1.5" Acceptance Criteria for `MQT2` or "Section 5.2.5 Acceptance
-Criteria" in the MTS for the given sensor.
-
-## Finalization
-
-The finalization process must perform two tasks:
-
-1. Initialize the FPMCU’s `entropy`.
-1. When building for PVT or mass production, enable `software write protect`.
-
-### Initialize FPMCU Entropy
-
-The `bio_wash` tool is intended to support both the first time factory
-initialization and RMA, depending on the flag. When run with the
-`--factory_init` argument (`bio_wash --factory_init`), it will ensure that the
-`entropy` is set. If the `entropy` has already been set it will do nothing.
-
-A side-effect of running `bio_wash` is that the `rollback_id` changes (`ectool
---name=cros_fp rollbackinfo`). Initially when the firmware is first flashed, the
-`rollback_id` should be zero. After `entropy` is initialized the `rollback_id`
-should be set to 1.
-
-Note that for new devices coming out of the factory we expect `rollback_id` to
-be 1, which indicates that the entropy has been set exactly once.
-
-### Enable Software Write Protect
-
-`Software write protect` must be enabled for PVT and mass production devices. It
-ensures that the RO portion of the FPMCU firmware cannot be overwritten, so it
-is critical for FPMCU security.
-
-The following commands will enable software write protection:
-
-```bash
-(dut) $ ectool --name=cros_fp flashprotect enable # enable
-(dut) $ sleep 2
-(dut) $ ectool --name=cros_fp reboot_ec # reboot so it takes effect
-(dut) $ sleep 2
-```
-
-To validate that software write protection has taken effect, run the following:
-
-```bash
-(dut) $ ectool --name=cros_fp flashprotect # get flashprotect state
-
-# output should match below
-Flash protect flags: 0x0000000b wp_gpio_asserted ro_at_boot ro_now
-Valid flags: 0x0000003f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT
-Writable flags: 0x00000004 all_now
-```
-
-If software write protection is not enabled, you will see the following instead:
-
-```bash
-(dut) $ ectool --name=cros_fp flashprotect # get flashprotect state
-
-# not protected
-Flash protect flags: 0x00000000
-Valid flags: 0x0000003f wp_gpio_asserted ro_at_boot ro_now all_now STUCK INCONSISTENT
-Writable flags: 0x00000001 ro_at_boot
-```
-
-Capturing a raw frame from the sensor will only work when software write
-protection is not enabled, so the test should check the following command works
-*before* write protection is enabled and then fails *after* write protection is
-enabled:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe raw
-
-# write protection disabled, exit code 0 and output will be raw bytes
-
-# write protection enabled, exit code 1 and output will be
-EC result 4 (ACCESS_DENIED)
-Failed to get FP sensor frame
-```
-
-## RMA Process
-
-As part of the RMA process, the `entropy` needs to be reset so that the new
-device owner has a new unique encryption key.
-
-The `bio_wash` tool is intended to support both the first time factory
-initialization and RMA, depending on the flag. When run without any arguments
-(`bio_wash`), it will forcibly reset the entropy.
-
-The RMA process should either run `bio_wash` without any arguments or re-flash
-the FPMCU firmware and then run `bio_wash --factory_init` to make sure that the
-entropy has been reset.
-
-## Miscellaneous Commands for Test Implementations
-
-### FPMCU Image Version
-
-```bash
-(dut) $ ectool --name=cros_fp version
-
-RO version: nocturne_fp_v2.2.64-58cf5974e
-RW version: nocturne_fp_v2.2.110-b936c0a3c
-Firmware copy: RW
-Build info: nocturne_fp_v2.2.110-b936c0a3c 2018-11-02 14:16:46 @swarm-cros-461
-Tool version: v2.0.2144-1524c164f 2019-09-09 06:50:36 @chromeos-ci-legacy-us-central2-d-x32-7-3ay8
-```
-
-### Capture Raw Images
-
-Put your finger on the sensor, then run:
-
-```bash
-(dut) $ ectool --name=cros_fp fpmode capture vendor
-```
-
-Wait for the capture to be finished, timeout after 10s:
-
-```bash
-(dut) $ ectool --name=cros_fp waitevent 5 10000
-MKBP event 5 data: 00 00 00 80
-```
-
-Remove the finger from the sensor, then start the retrieval of the frame from
-the MCU to the AP:
-
-```bash
-(dut) $ ectool --name=cros_fp fpframe raw > /tmp/fp.raw
-```
-
-To convert the images from FPC’s proprietary format to PNG, you will need to
-have `cros deploy`’d `libfputils-nocturne`, which will install the required
-utilities in `/opt/fpc`.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: As of 2019-05-21, the `libfputils` library only works for the FPC 1145
-sensor (in nocturne), not the FPC 1025 sensor (hatch).
-***
-<!-- mdformat on -->
-
-Convert the buffer in proprietary format into png:
-
-```bash
-(dut) $ /opt/fpc/fputils.py /tmp/fp.raw --png
-Extraction found 2 images
-Wrote /tmp/fp.0.png (14085 bytes)
-Wrote /tmp/fp.1.png (14025 bytes)
-```
-
-[Software Write Protect]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/write_protection.md#Software-Write-Protect
-[hardware write protect]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/docs/write_protection.md#hw_wp
-[FPC1025: Module Test Specification]: http://go/cros-fingerprint-fpc1025-module-test-spec
-[FPC1145: Module Test Specification]: http://go/cros-fingerprint-fpc1145-module-test-spec
-[FPC In-Device Test Specification]: http://go/cros-fingerprint-fpc-indevice-test-spec
-[`fingerprint_mcu.py`]: https://chromium.googlesource.com/chromiumos/platform/factory/+/HEAD/py/test/pytests/fingerprint_mcu.py
-[Checkerboard Test]: https://chromium.googlesource.com/chromiumos/platform/factory/+/d23ebc7eeb074760e8a720e3acac4cfe4073b2ae/py/test/pytests/fingerprint_mcu.py#166
-[GetSensorIdErrors]: https://chromium.googlesource.com/chromiumos/platform/factory/+/d23ebc7eeb074760e8a720e3acac4cfe4073b2ae/py/test/utils/fpmcu_utils.py#73
-[GetSensorId]: https://chromium.googlesource.com/chromiumos/platform/factory/+/d23ebc7eeb074760e8a720e3acac4cfe4073b2ae/py/test/utils/fpmcu_utils.py#65
-[ProcessResetPixelImage]: https://chromium.googlesource.com/chromiumos/platform/factory/+/d23ebc7eeb074760e8a720e3acac4cfe4073b2ae/py/test/pytests/fingerprint_mcu.py#268
-[rubber_finger_present]: https://chromium.googlesource.com/chromiumos/platform/factory/+/d23ebc7eeb074760e8a720e3acac4cfe4073b2ae/py/test/pytests/fingerprint_mcu.py#330
-[Chrome OS Fingerprint Team]: http://go/cros-fingerprint-docs
-[Factory Fingerprint Sensor Testing for `nocturne`]: http://go/fingerprint-factory-testing-nocturne
-[`flash_fp_mcu`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/util/flash_fp_mcu
-[Fingerprint flashing documentation]: ./fingerprint.md#factory-rma-dev-updates
-[Chrome OS Config]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md
-[updating Chrome OS Config]: ./fingerprint.md#update-chromeos-config
diff --git a/docs/fingerprint/fingerprint-firmware-testing-for-partners.md b/docs/fingerprint/fingerprint-firmware-testing-for-partners.md
deleted file mode 100644
index 3432bb0aac..0000000000
--- a/docs/fingerprint/fingerprint-firmware-testing-for-partners.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# Fingerprint Firmware Testing Instructions for Partners
-
-This document is intended to help partners (sensor vendors, MCU vendors, etc)
-run the Chrome OS fingerprint team's firmware tests, as part of the AVL process.
-The document assumes that you‘re using Linux to do the development; preferably a
-recent version of Ubuntu or Debian. It may be possible to use a virtual machine,
-but that is not a configuration we test.
-
-[TOC]
-
-## Hardware Requirements
-
-You will need a Chromebook with the fingerprint sensor and fingerprint MCU
-(FPMCU), and a [servo debugger].
-
-### Chromebook with fingerprint sensor
-
-The Chromebook needs to be in [developer mode] and running a test image so that
-the test can ssh into it. The fingerprint firmware tests will run a series of
-bash commands, including flashing the FPMCU firmware and rebooting the
-Chromebook. You do not need [CCD] because servo will handle the firmware write
-protection for you.
-
-### Servo
-
-Servo is a general purpose debug board used in many automated tests in Chromium
-OS. Among other things, servo enables the tests to toggle hardware write
-protect.
-
-While there are multiple versions of servo, for firmware tests we strongly
-recommend [Servo V4] as that's the simplest and most often used in autotests.
-This document will assume you are using Servo V4.
-
-### Hardware Setup
-
-* Connect the "HOST" side of Servo V4 to your host machine (which should have
- a Chromium OS chroot).
-* Connect the other side of Servo V4 to a USB port on the Chromebook with
- fingerprint sensor.
-* Connect the "DUT POWER" side of Servo V4 to power supply.
-* Make sure the USB cable from the host machine to Servo V4 is in data
- transfer mode (i.e. if there's an LED, it should be yellow instead of
- green).
-* Make sure the you can ssh into the Chromebook from the chroot on the host
- machine.
-
-## Software Setup
-
-### Get the Chromium OS source code.
-
-* First, make sure you [have the prerequisites].
-* Then [get the source].
-
-### Build the autotest codebase
-
-```bash
-# from a terminal on your machine
-(outside chroot) $ cd ~/chromiumos/src
-
-# enter the chroot (the flag is important)
-(outside chroot) $ cros_sdk --no-ns-pid
-
-# build autotest for the board to be tested
-(chroot) $ emerge-<BOARD> autotest
-```
-
-### Start servod
-
-```bash
-(chroot) $ sudo servod --board=<BOARD>
-```
-
-At this point the servod daemon should be running and listening to port 9999 by
-default. If it isn't, check the hardware connection.
-
-## Run a Single Fingerprint Firmware Test
-
-Use another terminal and enter the chroot like before:
-
-```bash
-(outside chroot) $ cd ~/chromiumos/src
-(outside chroot) $ cros_sdk --no-ns-pid
-```
-
-To run a single test, use this command in your chroot:
-
-```bash
-test_that --board=<BOARD> <IP> <test name>
-```
-
-For example:
-
-```bash
-test_that --board=nocturne <IP> firmware_Fingerprint.ReadFlash
-```
-
-## Run the Entire Fingerprint Firmware Test Suite
-
-To run the entire suite, use this command in your chroot:
-
-```bash
-test_that --board=<BOARD> <IP> suite:fingerprint
-```
-
-<!-- Links -->
-
-[servo debugger]: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/HEAD/docs/servo.md
-[developer mode]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_mode.md
-[CCD]: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/cr50_stab/docs/case_closed_debugging.md
-[Servo V4]: https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/HEAD/docs/servo_v4.md
-[have the prerequisites]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#Prerequisites
-[get the source]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#get-the-source
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
diff --git a/docs/fingerprint/fingerprint.md b/docs/fingerprint/fingerprint.md
deleted file mode 100644
index 39785f5afb..0000000000
--- a/docs/fingerprint/fingerprint.md
+++ /dev/null
@@ -1,590 +0,0 @@
-# Fingerprint Firmware (FPMCU)
-
-[TOC]
-
-<!-- mdformat off(b/139308852) -->
-*** note
-NOTE: The build commands assume you are in the `~/trunk/src/platform/ec`
-directory inside the chroot.
-***
-<!-- mdformat on -->
-
-<!-- mdformat off(b/139308852) -->
-*** note
-WARNING: When switching branches in the EC codebase, you probably want to nuke
-the `build` directory or at least the board you're working on: `rm -rf
-build/<board>` or `make clobber` to prevent compilation errors.
-***
-<!-- mdformat on -->
-
-## Software
-
-The main source code for fingerprint sensor functionality lives in the
-[`common/fpsensor`] directory. The driver code for specific sensors lives in the
-[`driver/fingerprint`] directory.
-
-## Hardware {#hardware}
-
-The following "boards" (specified by the `BOARD` environment variable when
-building the EC code) are for fingerprint:
-
-MCU | Sensor | Firmware (EC "board") | Dev Board | Nucleo Board
----------------------- | ---------- | ---------------------------------------------- | -------------------------------------------- | ------------
-[STM32H743] \(Cortex-M7) | [FPC 1145] | `dartmonkey`<br>(aka `nocturne_fp`, `nami_fp`) | [Icetower v0.2] <br>(Previously Dragontalon) | [Nucleo H743ZI2]
-[STM32F412] \(Cortex-M4) | [FPC 1025] | `bloonchipper`<br>(aka `hatch_fp`) | [Dragonclaw v0.2] | [Nucleo F412ZG]
-
-### Sensor Template Sizes
-
-Sensor | Fingerprint Template Size
----------- | --------------------------------
-[FPC 1145] | [~48 KB][FPC 1145 Template Size]
-[FPC 1025] | [~5 KB][FPC 1025 Template Size]
-
-### Determining Hardware {#chromeos-config-fingerprint}
-
-If you have access to a shell on your Chromebook, you can use [Chrome OS Config]
-to determine the FPMCU that it contains:
-
-```bash
-(dut) $ cros_config /fingerprint board
-```
-
-Alternatively, if you have a Chromium OS build, you can use [Chrome OS Config]
-in the chroot to determine the FPMCU:
-
-```bash
-(chroot) $ cros_config_host -c /build/<BOARD>/usr/share/chromeos-config/yaml/config.yaml -m <MODEL> get /fingerprint board
-```
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: If you get an empty response when running these commands, the
-[Chrome OS Config] properties for fingerprint may not have been set up yet. See
-the [section on updating Chrome OS Config](#update-chromeos-config).
-***
-<!-- mdformat on -->
-
-## Building FPMCU Firmware Locally
-
-### See `Makefile` target options
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make help
-```
-
-### Build
-
-Replace `<BOARD_NAME>` in the command below with the fingerprint MCU that you
-are targeting (e.g., `nocturne_fp`, `dartmonkey`, `bloonchipper`).
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make BOARD=<BOARD_NAME> -j
-```
-
-### Verbose Build output
-
-Use `V=1` to see the complete compiler output (all flags).
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make V=1 BOARD=nocturne_fp -j
-```
-
-## Building all EC firmware (before "repo upload")
-
-Before uploading a change to Gerrit via `repo upload`, you'll need to build
-*all* the boards in the EC codebase to make sure your changes do not break any
-others.
-
-<!-- mdformat off(b/139308852) -->
-*** note
-NOTE: If you forget to do this, do not worry. `repo upload` will warn you and
-prevent you from uploading.
-***
-<!-- mdformat on -->
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make buildall -j
-```
-
-## Building and running unit tests
-
-See the [Unit Tests] documentation for details on how to [run the unit tests].
-
-## Build ectool
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make BOARD=nocturne_fp utils-host -j
-```
-
-## Build and run the `host_command` fuzz test
-
-```bash
-(chroot) ~/trunk/src/platform/ec $ make run-host_command_fuzz
-```
-
-## Logs
-
-[`timberslide`] is a simple daemon that collects logs from the FPMCU and writes
-them to disk. [`timberslide`] reads from sysfs, where the kernel driver
-[periodically dumps the FPMCU console output][cros_ec_debugfs]. [`timberslide`]
-writes the resulting logs to `/var/log/cros_fp.log`. There are multiple
-instances of [`timberslide`] that run; one for each MCU running the EC codebase.
-
-### Starting timberslide
-
-```bash
-(dut)$ start timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log
-```
-
-### Stopping timberslide
-
-```bash
-(dut)$ stop timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log
-```
-
-### Manually running timberslide
-
-```bash
-(dut)$ timberslide --device_log=/sys/kernel/debug/cros_fp/console_log
-```
-
-### Reading logs from kernel
-
-If [`timberslide`] is not running you can just `cat` the logs directly from the
-kernel:
-
-```bash
-(dut)$ cat /sys/kernel/debug/cros_fp/console_log
-```
-
-## Production Updates (Auto-Update)
-
-### `fp_updater.sh` and `bio_fw_updater`
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: The auto-update process requires a working version of the firmware
-running on the FPMCU. See [Fingerprint Factory Requirements] for details on
-flashing in the factory.
-***
-<!-- mdformat on -->
-
-[`fp_updater.sh`] and [`bio_fw_updater`] are wrappers around [`flashrom`] and
-require already-functioning RO firmware running on the FPMCU. It’s meant to be
-used in production to update the RW firmware. `fp_updater.sh` was used prior to
-M77; `bio_fw_updater` replaces it.
-
-It's also possible to use the updater to update the RO firmware if you disable
-*both* HW and SW write protect, which we use for updating development devices
-that do not have write protect enabled (dogfood devices, EVT, etc.)
-
-In production, only the RW portion of the firmware can be updated (unless the
-user disables [hardware write protection]).
-
-## Factory / RMA / Development Updates {#factory-rma-dev-updates}
-
-### `flash_fp_mcu`
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: This tool is really just for us to use during development or during
-the RMA flow (must go through finalization again in that case). We never update
-RO in the field (can’t by design). See [Fingerprint Factory Requirements] for
-details on flashing in the factory.
-***
-<!-- mdformat on -->
-
-[`flash_fp_mcu`] enables spidev and toggles some GPIOs to put the FPMCU (STM32)
-into bootloader mode. At that point it uses [`stm32mon`] to rewrite the entire
-flash (both RO and RW). The FPMCU can only be put into bootloader mode when
-[hardware write protection] is disabled, which means [`flash_fp_mcu`] can only
-be used when [hardware write protection] is disabled.
-
-[`flash_fp_mcu`] is available in the [Chromium OS test image].
-
-### `stm32mon`
-
-[`stm32mon`] is a tool used to send commands to the STM32 bootloader. We use it
-for development (through [`flash_fp_mcu`]) to erase and flash the entire chip.
-
-[`stm32mon`] is available in the [Chromium OS test image].
-
-## Keys
-
-The `RO` section of the fingerprint firmware contains the public portion of the
-key used to sign the RW firmware. The RO firmware uses the public key to
-validate the signature of the RW firmware before jumping to it. It is not
-possible to update the public key stored in the RO firmware once a device has
-been shipped (i.e., once [hardware write protection] is enabled).
-
-Different keys are used to sign the firmware during development and production.
-The `dev` key is used for local builds and development and is not private; it is
-called `dev_key.pem` and located in the "board" directory for the given FPMCU
-(e.g., [`board/nocturne_fp/dev_key.pem`]). After doing a build, the `ec.bin` in
-the `build` directory (e.g., `build/nocturne_fp/ec.bin`) will be signed with the
-`dev` key.
-
-The two other types of keys are `premp` and `mp`, which stand for "pre-mass
-production" and "mass production", respectively. Both the `premp` and `mp` keys
-are only available to the buildbots as part of the official build. The `premp`
-is typically used during bringup of new hardware to validate the signing flow of
-the buildbots, while the `mp` key is used for PVT and production devices.
-
-Switching keys is only possible when the `RO` firmware is not write protected,
-since the public portion of the keypair is stored in the `RO` firmware.
-
-### Generate Key
-
-For testing, you can generate a new key by using the following openssl command:
-
-```bash
-openssl genrsa -3 -out board/$BOARD/dev_key.pem 3072
-```
-
-### Resources
-
-* https://sites.google.com/a/google.com/chromeos/resources/engineering/releng/signer-documentation
-* https://sites.google.com/a/google.com/chromeos/paygen---payload
-* https://b.corp.google.com/issues/77882970
-
-## Signing
-
-[`futility`] is used to sign EC firmware. There’s a wrapper script around it for
-signing called [`sign_official_build.sh`].
-
-### Key ID
-
-The output of `futility show` will show a `Public Key File` and `Signature`
-section, each of which have an `ID` field. This ID lets you match the key to the
-signature in case there is more than one.
-[It’s just a sha1sum of the public key,][vboot_key_id] so it lets you
-[uniquely identify the key being used][vb2_public_key].
-
-If you have the key (e.g., in PEM format), you can compute the `ID` with the
-`futility show` command:
-
-```bash
-(chroot) $ futility show ./path/to/key.pem
-```
-
-#### Example
-
-If you are building the `hatch_fp` "board" on your local machine (which signs
-the resulting `ec.bin` with the `dev` key, you can check the `ID` with:
-
-```bash
-(chroot)$ futility show board/hatch_fp/dev_key.pem
-```
-
-```
-Private Key file: board/hatch_fp/dev_key.pem
- Key length: 3072
- Key sha1sum: 61382804da86b4156d666cc9a976088f8b647d44
-```
-
-```bash
-(chroot)$ futility show build/hatch_fp/ec.bin
-```
-
-```
-Public Key file: build/hatch_fp/ec.bin
- Vboot API: 2.1
- Desc: ""
- Signature Algorithm: 7 RSA3072EXP3
- Hash Algorithm: 2 SHA256
- Version: 0x00000001
- ID: 61382804da86b4156d666cc9a976088f8b647d44
-Signature: build/hatch_fp/ec.bin
- Vboot API: 2.1
- Desc: ""
- Signature Algorithm: 7 RSA3072EXP3
- Hash Algorithm: 2 SHA256
- Total size: 0x1b8 (440)
- ID: 61382804da86b4156d666cc9a976088f8b647d44
- Data size: 0x2864c (165452)
-Signature verification succeeded.
-```
-
-### Showing Key ID (fingerprint) for running FW
-
-[Asked on chromeos-chatty-firmware][chatty-firmware-q] about adding an EC
-command to show the Key ID (fingerprint) from the RO version. This would make it
-a lot easier during both development and testing.
-
-## Power
-
-See [Measuring Power] for instructions on how to measure power with the
-fingerprint development boards.
-
-### Dragonclaw v0.2
-
-```bash
-(chroot) $ dut-control -t 60 pp3300_dx_mcu_mv pp3300_dx_fp_mv pp1800_dx_fp_mv pp3300_dx_mcu_mw pp3300_dx_fp_mw pp1800_dx_fp_mw
-```
-
-**Firmware Version**:
-`bloonchipper_v2.0.4277-9f652bb3-RO_v2.0.7314-3dfc5ff6-RW.bin`
-
-#### MCU is idle
-
-```
-(chroot) $ dut-control fpmcu_slp_alt:off
-```
-
-```
-@@ NAME COUNT AVERAGE STDDEV MAX MIN
-@@ sample_msecs 113 533.56 40.91 658.52 447.06
-@@ pp1800_dx_fp_mv 113 1800.00 0.00 1800.00 1800.00
-@@ pp1800_dx_fp_mw 113 0.00 0.00 0.00 0.00
-@@ pp3300_dx_fp_mv 113 3280.00 0.00 3280.00 3280.00
-@@ pp3300_dx_fp_mw 113 0.01 0.05 0.26 0.00
-@@ pp3300_dx_mcu_mv 113 3280.00 0.00 3280.00 3280.00
-@@ pp3300_dx_mcu_mw 113 24.67 0.00 24.67 24.67
-```
-
-#### MCU in low power mode (suspend)
-
-```
-(chroot) $ dut-control fpmcu_slp_alt:on
-```
-
-```
-@@ NAME COUNT AVERAGE STDDEV MAX MIN
-@@ sample_msecs 115 526.56 36.79 607.60 426.58
-@@ pp1800_dx_fp_mv 115 1800.00 0.00 1800.00 1800.00
-@@ pp1800_dx_fp_mw 115 0.00 0.00 0.00 0.00
-@@ pp3300_dx_fp_mv 115 3287.30 2.25 3288.00 3280.00
-@@ pp3300_dx_fp_mw 115 0.00 0.02 0.26 0.00
-@@ pp3300_dx_mcu_mv 115 3280.97 2.62 3288.00 3280.00
-@@ pp3300_dx_mcu_mw 115 4.02 0.64 10.76 3.94
-```
-
-### Icetower v0.1
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: Icetower v0.1 has a hardware bug in the INA connections, so you cannot
-measure the 1.8V fingerprint sensor rail. See http://b/178098140.
-
-Additionally, before https://crrev.com/c/2689101, the sleep GPIOs were not
-configured correctly, so the change needs to be cherry-picked in order to
-measure releases before that point.
-***
-<!-- mdformat on -->
-
-```bash
-(chroot) $ dut-control -t 60 pp3300_dx_mcu_mv pp3300_dx_fp_mv pp3300_dx_mcu_mw pp3300_dx_fp_mw
-```
-
-**Firmware Version**:
-`dartmonkey_v2.0.2887-311310808-RO_v2.0.7304-441100b93-RW.bin`
-
-#### MCU is idle
-
-```
-(chroot) $ dut-control fpmcu_slp_alt:off
-```
-
-```
-@@ NAME COUNT AVERAGE STDDEV MAX MIN
-@@ sample_msecs 178 337.13 20.91 404.32 289.82
-@@ pp3300_dx_fp_mv 178 3256.00 0.00 3256.00 3256.00
-@@ pp3300_dx_fp_mw 178 0.00 0.00 0.00 0.00
-@@ pp3300_dx_mcu_mv 178 3248.00 0.00 3248.00 3248.00
-@@ pp3300_dx_mcu_mw 178 45.17 0.09 45.21 44.95
-```
-
-#### MCU in low power mode (suspend)
-
-```
-(chroot) $ dut-control fpmcu_slp_alt:on
-```
-
-```
-@@ NAME COUNT AVERAGE STDDEV MAX MIN
-@@ sample_msecs 174 345.60 31.93 457.62 283.00
-@@ pp3300_dx_fp_mv 174 3264.00 0.00 3264.00 3264.00
-@@ pp3300_dx_fp_mw 174 0.00 0.00 0.00 0.00
-@@ pp3300_dx_mcu_mv 174 3260.69 3.94 3264.00 3256.00
-@@ pp3300_dx_mcu_mw 174 5.47 0.10 5.48 4.17
-```
-
-## Chrome OS Build (portage / ebuild)
-
-In order to use the fingerprint sensor with a given [Chrome OS board], a few
-things need to be configured for the [Chrome OS board].
-
-### Enable biod USE flag
-
-The biod [`USE` flag] needs to be enabled for the [Chrome OS board]. This `USE`
-flag
-[determines whether the `biod` daemon is built and installed][biod chromium-os].
-
-To enable the `USE` flag, update the `make.defaults` for the [Chrome OS board].
-See the [`make.defaults` for the Hatch board][hatch make.defaults] as an
-example.
-
-#### Verifying biod is installed in the rootfs
-
-After enabling the `biod` [`USE` flag] and building the `biod` package for your
-target [Chrome OS board], the `biod` binary should be in the build directory:
-
-```bash
-(chroot) $ emerge-<BOARD> biod
-```
-
-```bash
-(chroot) $ ls /build/<BOARD>/usr/bin/biod
-/build/<BOARD>/usr/bin/biod
-```
-
-### Update FPMCU_FIRMWARE
-
-`FPMCU_FIRMWARE` should be set to the set of fingerprint firmware that should be
-built and installed for the [Chrome OS board].
-
-`FPMCU_FIRMWARE` is a [`USE_EXPAND` variable][`USE` flag],
-[defined in the base `make.defaults`][FPMCU_FIRMWARE make.defaults].
-
-The `biod` ebuild uses the resulting [`USE` flags] to
-[determine which FPMCU release firmware to build][biod release firmware] and the
-[`chromeos-firmware-fpmcu` ebuild] uses the resulting [`USE` flags] to
-[determine which firmware to install][firmware ebuild] to the rootfs in
-`/opt/google/biod/fw`.
-
-Possible values for `FPMCU_FIRMWARE` can be found by looking at the
-`FIRMWARE_EC_BOARD` values in the [`chromeos-fpmcu-release*` ebuilds], which
-correspond to the [FPMCU hardware](#hardware).
-
-See the [Hatch baseboard `make.defaults`] for an example.
-
-#### Verifying FPMCU firmware is installed in the rootfs
-
-Once you have added the `FPMCU_FIRMWARE` flag and rebuilt the
-[`chromeos-firmware-fpmcu` ebuild], the firmware will show up in the the chroot:
-
-<!-- mdformat off(b/139308852) -->
-*** note
-**NOTE**: This requires access to the [internal manifest].
-***
-<!-- mdformat on -->
-
-```bash
-(chroot) $ emerge-<BOARD> chromeos-firmware-fpmcu
-```
-
-```bash
-(chroot) $ ls /build/<BOARD>/opt/google/biod/fw
-bloonchipper_v2.0.2626-3c315108.bin dartmonkey_v2.0.2887-311310808.bin
-```
-
-The above output assumes you selected the `bloonchipper` and `dartmonkey`
-firmware by setting `FPMCU_FIRMWARE="bloonchipper dartmonkey"`. The actual
-version numbers displayed will not necessarily match since the firmware is
-constantly updated.
-
-### Update Chrome OS Config {#update-chromeos-config}
-
-With "unibuild", the same OS image (build) for a given [Chrome OS board] is used
-across multiple devices. Often there will be some devices that have a
-fingerprint sensor, some that do not, and even different sensors for the same
-board.
-
-Determining what fingerprint hardware is on a given [Chrome OS board] is thus
-done at runtime, using [Chrome OS Config].
-
-The `fingerprint` config needs to be in the `model.yaml` for the given
-[Chrome OS board]. The [Chrome OS Config fingerprint] section describes the
-attributes for the `fingerprint` config in more detail.
-
-The [`ec_extras` attribute] needs to be set to the list of fingerprint firmware
-that should be built as part of the build.
-
-See the [`model.yaml` for the Hatch board][hatch model.yaml] as an example.
-
-Instead of crafting the `model.yaml` by hand, newer boards are moving to the
-[Chrome OS Project Configuration] model, where the config is generated using
-[Starlark]. The common [`create_fingerprint`] function can be used across models
-to configure the fingerprint settings. See the [Morphius `config.star`] for an
-example of how to call `create_fingerprint`. After you modify a `config.star`
-file you will need to [regenerate the config]. If you need to change many
-projects (e.g., modifying [`create_fingerprint`]), you can use the [`CLFactory`]
-tool.
-
-Once you have updated the config, you can test your changes by
-[running `cros_config`](#chromeos-config-fingerprint). The Chrome OS Config
-documentation has a [section on testing properties] that describes this in more
-detail.
-
-### SKUs
-
-The fingerprint sensor may only be included on certain SKUs for a given device.
-The fingerprint code uses [Chrome OS Config] to determine whether a device has a
-fingerprint sensor or not. For each SKU, there is an associated
-[fingerprint config][Chrome OS Config fingerprint]. [Chrome OS Config]
-determines the [SKU information][Chrome OS Config SKU] (and thus the
-[fingerprint config][Chrome OS Config fingerprint]) from [CBI Info]. The SKU for
-a given device can be found by viewing `chrome://system/#platform_identity_sku`.
-
-[`common/fpsensor`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/common/fpsensor/
-[`driver/fingerprint`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/driver/fingerprint
-[`nocturne_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/nocturne_fp/
-[`nami_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/nami_fp/
-[`hatch_fp`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/hatch_fp/
-[`bloonchipper`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/bloonchipper/
-[`dartmonkey`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/dartmonkey/
-[hardware write protection]: ../write_protection.md
-[`flash_fp_mcu`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/util/flash_fp_mcu
-[`stm32mon`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/e1f3f89e7ea7945adddd0c2e6838f5e59856cff2/util/stm32mon.c#14
-[`futility`]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/HEAD/futility/
-[`sign_official_build.sh`]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/HEAD/scripts/image_signing/sign_official_build.sh
-[vboot_key_id]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/e7db36856ce418552637d1981c173d22dfe5bf39/firmware/2lib/include/2id.h#5
-[vb2_public_key]: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/e7db36856ce418552637d1981c173d22dfe5bf39/firmware/2lib/include/2rsa.h#14
-[chatty-firmware-q]: https://groups.google.com/a/google.com/d/msg/chromeos-chatty-firmware/ZSg423wsFPg/26UbdGwjFQAJ
-[`fp_updater.sh`]: http://go/cros-fp-updater-nocturne-source
-[`bio_fw_updater`]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/biod/tools
-[`flashrom`]: https://chromium.googlesource.com/chromiumos/third_party/flashrom/
-[STM32F412]: https://www.st.com/resource/en/reference_manual/dm00180369.pdf
-[STM32H743]: https://www.st.com/resource/en/reference_manual/dm00314099.pdf
-[`board/nocturne_fp/dev_key.pem`]: https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/board/nocturne_fp/dev_key.pem
-[`timberslide`]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/timberslide
-[cros_ec_debugfs]: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/9db44685934a2e4bc9180ea2de87a6c429672395/drivers/platform/chrome/cros_ec_debugfs.c
-[Fingerprint Factory Requirements]: ./fingerprint-factory-requirements.md
-[Chromium OS test image]: https://chromium.googlesource.com/chromiumos/platform/factory/+/HEAD/README.md#building-test-image
-[Chrome OS Config]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md
-[Chrome OS Config fingerprint]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#fingerprint
-[section on testing properties]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#adding-and-testing-new-properties
-[Chrome OS board]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#Select-a-board
-[biod chromium-os]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/4ea72b588af3394cb9fd1c330dcf726472183dfd/virtual/target-chromium-os/target-chromium-os-1.ebuild#154
-[hatch make.defaults]: https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/2f075f0e7ce09d3eb460f3c529da463a6201276c/overlay-hatch/profiles/base/make.defaults#22
-[Hatch baseboard `make.defaults`]: https://chrome-internal.googlesource.com/chromeos/overlays/baseboard-hatch-private/+/HEAD/profiles/base/make.defaults#17
-[hatch model.yaml]: https://chrome-internal.googlesource.com/chromeos/overlays/overlay-hatch-private/+/HEAD/chromeos-base/chromeos-config-bsp-hatch-private/files/model.yaml
-[`ec_extras` attribute]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#build_targets
-[FPMCU_FIRMWARE make.defaults]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/4ea72b588af3394cb9fd1c330dcf726472183dfd/profiles/base/make.defaults#157
-[`USE` flag]: https://devmanual.gentoo.org/general-concepts/use-flags/index.html
-[`USE` flags]: https://devmanual.gentoo.org/general-concepts/use-flags/index.html
-[biod release firmware]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/4ea72b588af3394cb9fd1c330dcf726472183dfd/chromeos-base/biod/biod-9999.ebuild#49
-[`chromeos-firmware-fpmcu` ebuild]: https://chrome-internal.googlesource.com/chromeos/overlays/chromeos-overlay/+/HEAD/chromeos-base/chromeos-firmware-fpmcu/chromeos-firmware-fpmcu-9999.ebuild
-[firmware ebuild]: https://chrome-internal.googlesource.com/chromeos/overlays/chromeos-overlay/+/HEAD/chromeos-base/chromeos-firmware-fpmcu/chromeos-firmware-fpmcu-9999.ebuild#40
-[`chromeos-fpmcu-release*` ebuilds]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/HEAD/sys-firmware
-[internal manifest]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/developer_guide.md#get-the-source-code
-[Unit Tests]: ../unit_tests.md
-[run the unit tests]: ../unit_tests.md#running
-[Measuring Power]: ./fingerprint-dev-for-partners.md#measure-power
-[dragonclaw]: ./fingerprint-dev-for-partners.md#fpmcu-dev-board
-[FPC 1145]: ../../driver/fingerprint/fpc/libfp/fpc1145_private.h
-[FPC 1025]: ../../driver/fingerprint/fpc/bep/fpc1025_private.h
-[FPC 1145 Template Size]: https://chromium.googlesource.com/chromiumos/platform/ec/+/127521b109be8aac352e80e319e46ed123360408/driver/fingerprint/fpc/libfp/fpc1145_private.h#46
-[FPC 1025 Template Size]: https://chromium.googlesource.com/chromiumos/platform/ec/+/127521b109be8aac352e80e319e46ed123360408/driver/fingerprint/fpc/bep/fpc1025_private.h#44
-[Dragonclaw v0.2]: ./fingerprint-dev-for-partners.md#fpmcu-dev-board
-[Icetower v0.2]: ./fingerprint-dev-for-partners.md#fpmcu-dev-board
-[Nucleo F412ZG]: https://www.digikey.com/en/products/detail/stmicroelectronics/NUCLEO-F412ZG/6137573
-[Nucleo H743ZI2]: https://www.digikey.com/en/products/detail/stmicroelectronics/NUCLEO-H743ZI2/10130892
-[CBI Info]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md
-[Chrome OS Config SKU]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/chromeos-config/README.md#identity
-[Chrome OS Project Configuration]: https://chromium.googlesource.com/chromiumos/config/+/HEAD/README.md
-[Starlark]: https://docs.bazel.build/versions/master/skylark/language.html
-[`create_fingerprint`]: https://chromium.googlesource.com/chromiumos/config/+/e1fa0d7f56eb3dd6e9378e4326de086ada46b7d3/util/hw_topology.star#444
-[Morphius `config.star`]: https://chrome-internal.googlesource.com/chromeos/project/zork/morphius/+/593b657a776ed6b320c826916adc9cd845faf709/config.star#85
-[regenerate the config]: https://chromium.googlesource.com/chromiumos/config/+/HEAD/README.md#making-configuration-changes-for-your-project
-[`CLFactory`]: https://chromium.googlesource.com/chromiumos/config/+/HEAD/README.md#making-bulk-changes-across-repos