1# KeyMint Rust Reference Implementation 2 3This repository holds a reference implementation of the Android 4[KeyMint 5HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl?q=IKeyMintDevice.aidl), 6including closely related HAL interfaces: 7 8- [`IRemotelyProvisionedComponent`](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl) 9- [`ISharedSecret`](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl) 10- [`ISecureClock`](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl) 11 12## Repository Structure 13 14The codebase is divided into a number of interdependent crates, as follows. 15 16- `derive/`: The `kmr-derive` crate holds [proc 17 macros](https://doc.rust-lang.org/reference/procedural-macros.html) used for deriving the 18 `kmr_wire::AsCborValue` trait that is used for message serialization. This crate uses `std`, but 19 is only required for the build process on the host, and does not produce code that runs on the 20 device. 21- `wire/`: The `kmr-wire` crate holds the types that are used for communication between the 22 userspace HAL service and the trusted application code that runs in the secure world, together 23 with code for serializing and deserializing these types as CBOR. This crate is `no_std` but uses 24 `alloc`. 25- `common/`: The `kmr-common` crate holds common code used throughout the KeyMint 26 implementation. This includes metadata processing code, keyblob manipulation code, and also the 27 abstractions used to represent access to underlying cryptographic functionality. This crate is 28 `no_std` but uses `alloc`. 29- `ta/`: The `kmr-ta` crate holds the implementation of the KeyMint trusted application (TA), which 30 is expected to run within the device's secure environment. This crate is `no_std` but uses 31 `alloc`. 32- `hal/`: The `kmr-hal` crate holds the implementation of the HAL service for KeyMint, which is 33 expected to run in the Android userspace and respond to Binder method invocations. This crate uses 34 `std` (as it runs within Android, not within the more restricted secure environment). 35- `boringssl/`: The `kmr-crypto-boring` crate holds a BoringSSL-based implementation of the 36 cryptographic abstractions from `kmr-common`. This crate is `no_std` (but using `alloc`); however, 37 it relies on the Rust [`openssl` crate](https://docs.rs/openssl) for BoringSSL support, and that 38 crate uses `std`. 39- `tests/`: The `kmr-tests` crate holds internal testing code. 40 41| Subdir | Crate Name | `std`? | Description | 42|------------------|---------------------|---------------------|-------------------------------------------------------| 43| **`derive`** | `kmr-derive` | Yes (build-only) | Proc macros for deriving the `AsCborValue` trait | 44| **`wire`** | `kmr-wire` | No | Types for HAL <-> TA communication | 45| **`common`** | `kmr-common` | No | Common code used throughout KeyMint/Rust | 46| **`ta`** | `kmr-ta` | No | TA implementation | 47| **`hal`** | `kmr-hal` | Yes | HAL service implementation | 48| **`boringssl`** | `kmr-crypto-boring` | Yes (via `openssl`) | Boring/OpenSSL-based implementations of crypto traits | 49| `tests` | `kmr-tests` | | Tests and test infrastructure | 50 51## Porting to a Device 52 53To use the Rust reference implementation on an Android device, implementations of various 54abstractions must be provided. This section describes the different areas of functionality that are 55required. 56 57### Rust Toolchain and Heap Allocator 58 59Using the reference implementation requires a Rust toolchain that can target the secure environment. 60This toolchain (and any associated system libraries) must also support heap allocation (or an 61approximation thereof) via the [`alloc` sysroot crate](https://doc.rust-lang.org/alloc/). 62 63If the BoringSSL-based implementation of cryptographic functionality is used (see below), then some 64parts of the Rust `std` library must also be provided, in order to support the compilation of the 65[`openssl`](https://docs.rs/openssl) wrapper crate. 66 67**Checklist:** 68 69- [ ] Rust toolchain that targets secure environment. 70- [ ] Heap allocation support via `alloc`. 71 72### HAL Service 73 74KeyMint appears as a HAL service in userspace, and so an executable that registers for and services 75the KeyMint related HALs must be provided. 76 77The implementation of this service is mostly provided by the `kmr-hal` crate, but a driver program 78must be provided that: 79 80- Performs start-of-day administration (e.g. logging setup, panic handler setup) 81- Creates a communication channel to the KeyMint TA. 82- Registers for the KeyMint HAL services. 83- Starts a thread pool to service requests. 84 85The KeyMint HAL service (which runs in userspace) must communicate with the KeyMint TA (which runs 86in the secure environment). The reference implementation assumes the existence of a reliable, 87message-oriented, bi-directional communication channel for this, as encapsulated in the 88`kmr_hal::SerializedChannel` trait. 89 90This trait has a single method `execute()`, which takes as input a request message (as bytes), and 91returns a response message (as bytes) or an error. 92 93A (shared) instance of this trait must be provided to each of the `kmr_hal::<interface>::Device` 94types, which allows them to service Binder requests for the relevant interface by forwarding the 95requests to the TA as request/response pairs. 96 97**Checklist:** 98 99- [ ] Implementation of HAL service, which registers for all HAL services. 100- [ ] SELinux policy for the HAL service. 101- [ ] init.rc configuration for the HAL service. 102- [ ] Implementation of `SerializedChannel` trait, for reliable HAL <-> TA communication. 103- [ ] Populate userspace environment information at start of day, using `kmr_hal::send_hal_info()`. 104 105The Cuttlefish implementation of the [KeyMint/Rust HAL 106service](https://cs.android.com/android/platform/superproject/+/master:device/google/cuttlefish/guest/hals/keymint/rust/src/keymint_hal_main.rs) 107provides an example of all of the above. 108 109### TA Driver 110 111The `kmr-ta` crate provides the majority of the implementation of the KeyMint TA, but needs a driver 112program that: 113 114- Performs start-of-day administration (e.g. logging setup). 115- Populates initially required information (e.g. `kmr_ta::HardwareInfo`) 116- Creates a `kmr_ta::KeyMintTa` instance. 117- Configures the communication channel with the HAL service. 118- Configures the communication channel with the bootloader, which is required so that the current 119 root-of-trust boot information can be received. 120- Holds the main loop that: 121 - reads request messages from the channel(s) 122 - passes request messages to `kmr_ta::KeyMintTa::process()`, receiving a response 123 - writes response messages back to the relevant channel. 124 125**Checklist:** 126 127- [ ] Implementation of `main` equivalent for TA, handling scheduling of incoming requests. 128- [ ] Implementation of communication channel between HAL service and TA. 129- [ ] Implementation of communication channel from bootloader to TA. 130 - [ ] Trigger call to `kmr_ta::KeyMintTa::set_boot_info` on receipt of boot info. 131 132The Cuttlefish implementation of the [KeyMint/Rust 133TA](https://cs.android.com/android/platform/superproject/+/master:device/google/cuttlefish/host/commands/secure_env_rust/secure_env.rs) 134provides an example of all of the above. 135 136### Bootloader 137 138The bootloader is required to transmit root of trust and boot state information to the TA at start 139of day, so the TA can bind keys to the root of trust appropriately. The bootloader should fill out 140and send a `kmr_wire::SetBootInfoRequest` message to do this. 141 142**Checklist:** 143 144- [ ] Implementation of communication channel from bootloader to TA. 145- [ ] Trigger for and population of `kmr_wire::SetBootInfoRequest` message. 146 147### Cryptographic Abstractions 148 149The KeyMint TA requires implementations for low-level cryptographic primitives to be provided, in 150the form of implementations of the various Rust traits held in 151[`kmr_common::crypto`](common/src/crypto/traits.rs). 152 153Note that some of these traits include methods that have default implementations, which means that 154an external implementation is not required (but can be provided if desired). 155 156**Checklist:** 157 158- [ ] RNG implementation. 159- [ ] Constant time comparison implementation. 160- [ ] AES implementation. 161- [ ] 3-DES implementation. 162- [ ] HMAC implementation. 163- [ ] RSA implementation. 164- [ ] EC implementation (including curve 25519 support). 165- [ ] AES-CMAC or CKDF implementation. 166- [ ] Secure time implementation. 167 168BoringSSL-based implementations are available for all of the above (except for secure time). 169 170### Device Abstractions 171 172The KeyMint TA requires implementations of traits that involve interaction with device-specific 173features or provisioned information, in the form of implementations of the various Rust traits held 174in [`kmr_hal::device`](hal/src/device.rs). 175 176**Checklist:** 177 178- [ ] Root key retrieval implementation. 179- [ ] Attestation key / chain retrieval implementation. 180- [ ] Attestation device ID retrieval implementation. 181- [ ] Retrieval of BCC and DICE artefacts. 182- [ ] Secure storage implementation (optional). 183- [ ] Bootloader status retrieval (optional) 184- [ ] Storage key wrapping integration (optional). 185- [ ] Trusted user presence indication (optional). 186- [ ] Legacy keyblob format converter (optional). 187