diff --git a/security/keymint/RKP_README.md b/security/keymint/RKP_README.md new file mode 100644 index 0000000000..89a2598f66 --- /dev/null +++ b/security/keymint/RKP_README.md @@ -0,0 +1,374 @@ +# Remote Provisioning HAL + +## Objective + +Design a HAL to support over-the-air provisioning of certificates for asymmetric +keys. The HAL must interact effectively with Keystore (and other daemons) and +protect device privacy and security. + +Note that this API is designed for KeyMint, but with the intention that it +should be usable for other HALs that require certificate provisioning. +Throughout this document we'll refer to the Keystore and KeyMint (formerly +called Keymaster) components, but only for concreteness and convenience; those +labels could be replaced with the names of any system and secure area +components, respectively, that need certificates provisioned. + +## Key design decisions + +### General approach + +To more securely and reliably get keys and certificates to Android devices, we +need to create a system where no party outside of the device's secure components +is responsible for managing private keys. The strategy we've chosen is to +deliver certificates over the air, using an asymmetric key pair created +on-device in the factory as a root of trust to create an authenticated, secure +channel. In this document we refer to this device-unique asymmetric key pair as +Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device +Key Certificate containing DK\_pub is denoted DKC. + +In order for the provisioning service to use DK (or a key authenticated by DK), +it must know whether a given DK\_pub is known and trusted. To prove trust, we +ask device OEMs to use one of two mechanisms: + +1. (Preferred, recommended) The device OEM extracts DK\_pub from each device it + manufactures and uploads the public keys to a backend server. + +1. The device OEM signs the DK\_pub to produce DKC and stores it on the device. + This has the advantage that they don't need to upload a DK\_pub for every + device immediately, but the disadvantage that they have to manage their + private signing keys, which means they have to have HSMs, configure and + secure them correctly, etc. Some backend providers may also require that the + OEM passes a factory security audit, and additionally promises to upload the + keys eventually as well. + +Note that in the full elaboration of this plan, DK\_pub is not the key used to +establish a secure channel. Instead, DK\_pub is just the first public key in a +chain of public keys which ends with the KeyMint public key, KM\_pub. All keys +in the chain are device-unique and are joined in a certificate chain called the +_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote +provisioning project it is a chain of certificates corresponding to boot phases. +We speak of the BCC even for phase 1, though in phase 1 it contains only a +single self-signed DKC. This is described in more depth in the Phases section +below. + +The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have +additional DKCs, from the SoC vendor, the device OEM, or both. Those are not +part of the BCC but included as optional fields in the certificate request +structure. + +The format of the the DK and BCC is specified within [Open Profile for DICE] +(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md). To +map phrases within this document to their equivalent terminology in the DICE +specification, read the terms as follows: the DK corresponds to the UDS-derived +key pair, DKC corresponds to the UDS certificate, and the BCC entries between +DK\_pub and KM\_pub correspond to a chain of CDI certificates. + +Note: In addition to allowing 32 byte hash values for fields in the BCC payload, +this spec additionally constrains some of the choices allowed in open-DICE. +Specifically, these include which entries are required and which are optional in +the BCC payload, and which algorithms are acceptable for use. + +### Phases + +RKP will be deployed in three phases, in terms of managing the root of trust +binding between the device and the backend. To briefly describe them: + +* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are + the same key and the certificate is self-signed. +* Phase 2: This is identical to phase 1, except it leverages the hardware root + of trust process described by DICE. Instead of trust being rooted in the TEE, + it is now rooted in the ROM by key material blown into fuses which are only + accessible to the ROM code. +* Phase 3: This is identical to Phase 2, except the SoC vendor also does the + public key extraction or certification in their facilities, along with the OEM + doing it in the factory. This tightens up the "supply chain" and aims to make + key upload management more secure. + +### Privacy considerations + +Because DK and the DKCs are unique, immutable, unspoofable hardware-bound +identifiers for the device, we must limit access to them to the absolute minimum +possible. We do this in two ways: + +1. We require KeyMint (which knows the BCC and either knows or at least has the +ability to use KM\_priv) to refuse to ever divulge the BCC or additional +signatures in plaintext. Instead, KeyMint requires the caller to provide an +_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before +returning it. When provisioning production keys, the EEK must be signed by an +approved authority whose public key is embedded in KeyMint. When certifying test +keys, KeyMint will accept any EEK without checking the signature, but will +encrypt and return a test BCC, rather than the real one. The result is that +only an entity in possession of an Trusted EEK (TEEK) private key can discover +the plaintext of the production BCC. +1. Having thus limited access to the public keys to the trusted party only, we +need to prevent the entity from abusing this unique device identifier. The +approach and mechanisms for doing that are beyond the scope of this document +(they must be addressed in the server design), but generally involve taking care +to ensure that we do not create any links between user IDs, IP addresses or +issued certificates and the device pubkey. + +Although the details of the mechanisms for preventing the entity from abusing +the BCC are, as stated, beyond the scope of this document, there is a subtle +design decision here made specifically to enable abuse prevention. Specifically +the `CertificateRequest` message sent to the server is (in +[CDDL](https://tools.ietf.org/html/rfc8610)): + +``` +cddl +CertificateRequest = [ + DeviceInfo, + challenge : bstr, + ProtectedData, + MacedKeysToSign +] +``` + +The public keys to be attested by the server are in `MacedKeysToSign`, which is +a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The +MAC key is signed by DK\_pub. + +This structure allows the backend component that has access to EEK\_priv to +decrypt `ProtectedData`, validate that the request is from an authorized device, +check that the request is fresh and verify and extract the MAC key. That backend +component never sees any data related to the keys to be signed, but can provide +the MAC key to another backend component that can verify `MacedKeysToSign` and +proceed to generate the certificates. + +In this way, we can partition the provisioning server into one component that +knows the device identity, as represented by DK\_pub, but never sees the keys to +be certified or certificates generated, and another component that sees the keys +to be certified and certificates generated but does not know the device +identity. + +### Key and cryptographic message formatting + +For simplicity of generation and parsing, compactness of wire representation, +and flexibility and standardization, we've settled on using the CBOR Object +Signing and Encryption (COSE) standard, defined in [RFC +8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably +simple, yet easily-extensible, wire formats for: + +* Keys, +* MACed messages, +* Signed messages, and +* Encrypted messages + +COSE enables easy layering of these message formats, such as using a COSE\_Sign +structure to contain a COSE\_Key with a public key in it. We call this a +"certificate". + +Due to the complexity of the standard, we'll spell out the COSE structures +completely in this document and in the HAL and other documentation, so that +although implementors will need to understand CBOR and the CBOR Data Definition +Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)), +they shouldn't need to understand COSE. + +Note, however, that the certificate chains returned from the provisioning server +are standard X.509 certificates. + +### Algorithm choices + +This document uses: + +* ECDSA P-256 for attestation signing keys; +* Remote provisioning protocol signing keys: + * Ed25519 / P-256 +* ECDH keys: + * X25519 / P-256 +* AES-GCM for all encryption; +* SHA-256 for all message digesting; +* HMAC-SHA-256 for all MACing; and +* HKDF-SHA-256 for all key derivation. + +We believe that Curve25519 offers the best tradeoff in terms of security, +efficiency and global trustworthiness, and that it is now sufficiently +widely-used and widely-implemented to make it a practical choice. + +However, since Secure Elements (SE) do not currently offer support for curve +25519, we are allowing implementations to instead make use of EC P-256 for +signing and ECDH. To put it simply, the device unique key pair will be a P-256 +key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt +message will have its payload encrypted with P-256 ECDH key exchange instead of +X25519. + +The CDDL in the rest of the document will use the '/' operator to show areas +where either curve 25519 or P-256 may be used. Since there is no easy way to +bind choices across different CDDL groups, it is important that the implementor +stays consistent in which type is chosen. E.g. taking ES256 as the choice for +algorithm implies the implementor should also choose the P256 public key group +further down in the COSE structure. + +### Testability + +It's critical that the remote provisioning implementation be testable, to +minimize the probability that broken devices are sold to end users. To support +testing, the remote provisioning HAL methods take a `testMode` argument. Keys +created in test mode are tagged to indicate this. The provisioning server will +check for the test mode tag and issue test certificates that do not chain back +to a trusted public key. In test mode, any EEK will be accepted, enabling +testing tools to use EEKs for which they have the private key so they can +validate the content of certificate requests. The BCC included in the +`CertificateRequest` must contain freshly-generated keys, not the real BCC keys. + +Keystore (or similar) will need to be able to handle both testMode keys and +production keys and keep them distinct, generating test certificate requests +when asked with a test EEK and production certificate requests when asked with a +production EEK. Likewise, the interface used to instruct Keystore to create keys +will need to be able to specify whether test or production keys are desired. + +## Design + +### Certificate provisioning flow + +TODO(jbires): Replace this with a `.png` containing a sequence diagram. The +provisioning flow looks something like this: + +Provisioner -> Keystore: Prepare N keys +Keystore -> KeyMint: generateKeyPair +KeyMint -> KeyMint: Generate key pair +KeyMint --> Keystore: key\_blob,pubkey +Keystore -> Keystore: Store key\_blob,pubkey +Provisioner -> Server: Get TEEK +Server --> Provisioner: TEEK +Provisioner -> Keystore: genCertReq(N, TEEK) +Keystore -> KeyMint: genCertReq(pubkeys, TEEK) +KeyMint -> KeyMint: Sign pubkeys & encrypt BCC +KeyMint --> Keystore: signature, encrypted BCC +Keystore -> Keystore: Construct cert\_request +Keystore --> Provisioner: cert\_request +Provisioner --> Server: cert\_request +Server -> Server: Validate cert\_request +Server -> Server: Generate certificates +Server --> Provisioner: certificates +Provisioner -> Keystore: certificates +Keystore -> Keystore: Store certificates + +The actors in the above diagram are: + +* **Server** is the backend certificate provisioning server. It has access to + the uploaded device public keys and is responsible for providing encryption + keys, decrypting and validating requests, and generating certificates in + response to requests. +* **Provisioner** is an application that is responsible for communicating with + the server and all of the system components that require key certificates + from the server. It also implements the policy that defines how many key + pairs each client should keep in their pool. +* **Keystore** is the [Android keystore + daemon](https://developer.android.com/training/articles/keystore) (or, more + generally, whatever system component manages communications with a + particular secure aread component). +* **KeyMint** is the secure area component that manages cryptographic keys and + performs attestations (or perhaps some other secure area component). + +### `BCC` + +The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains +DK\_pub as well as other often device-unique certificates. The BCC is +represented as a COSE\_Key containing DK\_pub followed by an array of +COSE\_Sign1 "certificates" containing public keys and optional additional +information, ordered from root to leaf, with each certificate signing the next. +The first certificate in the array is signed by DK\_pub, the last certificate +has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1 +there is only one entry; DK\_pub and KM\_pub are the same key and the +certificate is self-signed. + +Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC +8392](https://tools.ietf.org/html/rfc8392) with additional fields as described +in the Open Profile for DICE. Of these additional fields, only the +_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the +KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the +Open Profile for DICE are expected for other entries (each of which corresponds +to a particular firmware component or boot stage). The CWT fields _iss_ and +_sub_ identify the issuer and subject of the certificate and are consistent +along the BCC entries; the issuer of a given entry matches the subject of the +previous entry. + +The BCC is designed to be constructed using the Open Profile for DICE. In this +case the DK key pair is derived from the UDS as described by that profile and +all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub. +The KM key pair is not part of the derived DICE chain. It is generated (not +derived) by the KeyMint module, certified by the last key in the DICE chain, and +added as the leaf BCC entry. The key usage field in this leaf certificate must +indicate the key is not used to sign certificates. If a UDS certificate is +available on the device it should appear in the certificate request as the leaf +of a DKCertChain in AdditionalDKSignatures (see +[CertificateRequest](#certificaterequest)). + +The Open Profile for DICE allows for an arbitrary configuration descriptor. For +BCC entries, this configuration descriptor is a CBOR map with the following +optional fields. If no fields are relevant, an empty map should be encoded. +Additional implementation-specific fields may be added using key values not in +the range \[-70000, -70999\] (these are reserved for future additions here). + +``` +| Name | Key | Value type | Meaning | +| ----------------- | ------ | ---------- | ----------------------------------| +| Component name | -70002 | tstr | Name of firmware component / boot | +: : : : stage : +| Component version | -70003 | int | Version of firmware component / | +: : : : boot stage : +| Resettable | -70004 | null | If present, key changes on factory| +: : : : reset : +``` + +Please see +[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl) +for a full CDDL definition of the BCC. + +### `CertificateRequest` + +The full CBOR message that will be sent to the server to request certificates +is: + +```cddl +CertificateRequest = [ + DeviceInfo, + challenge : bstr, // Provided by the server + ProtectedData, // See ProtectedData.aidl + MacedKeysToSign // See IRemotelyProvisionedComponent.aidl +] + +DeviceInfo = [ + VerifiedDeviceInfo, // See DeviceInfo.aidl + UnverifiedDeviceInfo +] + +// Unverified info is anything provided by the HLOS. Subject to change out of +// step with the HAL. +UnverifiedDeviceInfo = { + ? "fingerprint" : tstr, +} + +``` + +It will be the responsibility of Keystore and the Provisioner to construct the +`CertificateRequest`. The HAL provides a method to generate the elements that +need to be constructed on the secure side, which are the tag field of +`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of +`ProtectedData`. + +### HAL + +The remote provisioning HAL provides a simple interface that can be implemented +by multiple secure components that require remote provisioning. It would be +slightly simpler to extend the KeyMint API, but that approach would only serve +the needs of KeyMint, this is more general. + +NOTE the data structures defined in this HAL may look a little bloated and +complex. This is because the COSE data structures are fully spelled-out; we +could make it much more compact by not re-specifying the standardized elements +and instead just referencing the standard, but it seems better to fully specify +them. If the apparent complexity seems daunting, consider what the same would +look like if traditional ASN.1 DER-based structures from X.509 and related +standards were used and also fully elaborated. + +Please see the related HAL documentation directly in the source code at the +following links: + +* [IRemotelyProvisionedComponent + HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl) +* [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl) +* [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl) +* [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl) +* [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl) +