README.md
1# Secretkeeper
2
3Secretkeeper provides secure storage of secrets on behalf of other components in Android.
4It is specified as [a HAL][secretkeeperhal] and must be implemented in an environment with
5privilege higher than any of its clients. Typically this will be a trusted execution environment
6such as ARM TrustZone.
7
8The core SecretManagement API is a [CBOR based protocol][secretmanagement_cddl] and can be used to
9store (& get) 32 bytes of secret data. Secretkeeper supports establishing a secure channel with
10clients as well as deletion of some or all data.
11
12## AuthGraph key exchange
13
14The requests (from the client) & responses (from Secretkeeper) must be encrypted using symmetric
15keys agreed between the client & service. For this, Secretkeeper (& client) must implement the
16[AuthGraph key exchange protocol][authgraphke] to establish a secure channel between them.
17
18In the key exchange protocol, the client acts as P1 (source) and Secretkeeper as P2 (sink). The
19interface returned by [getAuthGraphKe()][getauthgraphke] can be used to invoke methods on the sink.
20
21## Policy Gated Storage
22
23The storage layer of Secretkeeper, in addition to conventional storage, provides DICE
24policy based access control. A client can restrict the access to its stored entry.
25
26### Storage
27
28The underlying storage of Secretkeeper should offer the following security guarantees:
29
301. Confidentiality: No entity (of security privilege lower than Secretkeeper) should be able to get
31 a client's data in the clear.
322. Integrity: The data is protected against malicious Android OS tampering with database. i.e., if
33 Android (userspace & kernel) tampers with the client's secret, the Secretkeeper service must be
34 able to detect it & return an error when clients requests for their secrets.
35 **The integrity requirements also include rollback protection i.e., reverting the database
36 into an old state should be detected.**
373. Persistence: The data is persistent across device boot.
38 Note: Denial of service is not in scope. A malicious Android may be able to delete data.
39 In ideal situation, the data should be persistent.
40
41### Access control
42
43Secretkeeper uses [DICE policy][DicePolicyCDDL] based access control. Each secret is associated
44with a sealing policy, which is a DICE policy. This is a required input while storing a secret.
45Further access to this secret is restricted to clients whose DICE chain adheres to the
46corresponding sealing policy.
47
48## Reference Implementation
49
50Android provides a reference implementation of Secretkeeper as well as the required AuthGraph Key
51exchange HAL. The implementation is modular and easily configurable. For example,
52partners can plug in their implementation of AES-GCM, RNG instead of using the BoringSSL
53implementations.
54
55Navigating this project:
56
571. [./core/][sk_core_dir]: Contains the reference implementation of Secretkeeper TA.
582. [./hal/][sk_hal_dir]: Contains the reference implementation of Secretkeeper HAL.
593. [./client/][sk_client_dir]: A client library for Secretkeeper, which can be used for managing
60 sessions with Secretkeeper, sending requests etc.
614. [./comm/][sk_comm_dir]: Secretkeeper is a CBOR heavy protocol, the Rust definition
62 of Requests/Response/Arguments/Errors is contained in this directory.
63 Additionally, Rust types for supporting the CBOR based communication between the TA and HAL is
64 also exported here. This is used by secretkeeper_core, secretkeeper_hal and secretkeeper_client.
655. [./dice_policy/][dice_policy_dir]: Contains code for building dice_policies as well
66 as well as matching them against Dice chain. As explained [here](#Policy-Gated-Storage), this
67 forms the foundation of Policy Gated Storage in Secretkeeper.
68
69Outside this directory:
70
711. Secretkeeper HAL Spec: [hardware/interfaces/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl][secretkeeperhal]
722. [Vendor Test Suite for Secretkeeper][secretkeeper_vts]
733. [HAL Integration for Trusty][sk_hal_trusty]
744. [TA Integration for Trusty][sk_ta_trusty]
755. [Command line test tool for interacting with Secretkeeper][secretkeeper_cli]
766. [AuthGraph HAL Spec & Test Suite][authgraphhal_dir]
777. AuthGraph Reference implementation: [system/authgraph/][authgraph_ref]
78
79[sk_core_dir]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/core/
80[sk_hal_dir]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/hal/
81[sk_client_dir]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/client/
82[sk_comm_dir]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/comm/
83[dice_policy_dir]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/dice_policy/
84[secretkeeper_vts]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
85[sk_hal_trusty]: https://cs.android.com/android/platform/superproject/main/+/main:system/core/trusty/secretkeeper/src/hal_main.rs
86[sk_ta_trusty]: https://android.googlesource.com/trusty/app/secretkeeper/+/refs/heads/master/lib.rs
87[secretkeeper_cli]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
88[authgraphhal_dir]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/authgraph/aidl/
89[authgraph_ref]: https://cs.android.com/android/platform/superproject/main/+/main:system/authgraph/
90
91### Porting to a Device
92
93To use the Rust reference implementation on an Android device, device-specific implementations of
94various abstractions must be provided. This section describes the different areas of functionality
95that are required.
96
97#### Rust Toolchain and Heap Allocator
98
99Using the reference implementation requires a Rust toolchain that can target the secure environment.
100This toolchain (and any associated system libraries) must also support heap allocation (or an
101approximation thereof) via the [`alloc` sysroot crate](https://doc.rust-lang.org/alloc/).
102
103If the BoringSSL-based implementation of cryptographic functionality is used (see below), then some
104parts of the Rust `std` library must also be provided, in order to support the compilation of the
105[`openssl`](https://docs.rs/openssl) wrapper crate.
106
107**Checklist:**
108
109- [ ] Rust toolchain that targets secure environment.
110- [ ] Heap allocation support via `alloc`.
111
112#### HAL Service
113
114Secretkeeper appears as a HAL service in userspace, and so an executable that registers for and
115services the Secretkeeper HAL must be provided.
116
117The implementation of this service is mostly provided by the [`secretkeeper_hal` crate][sk_hal_dir]
118(and by the associated [`authgraph_hal`
119crate](https://cs.android.com/android/platform/superproject/main/+/main:system/authgraph/hal/)),
120but a driver program must be provided that:
121
122- Performs start-of-day administration (e.g. logging setup, panic handler setup).
123- Creates communication channels to the Secretkeeper TA.
124- Registers for the Secretkeeper HAL service.
125- Starts a thread pool to service requests.
126
127The Secretkeeper HAL service (which runs in userspace) must communicate with the Secretkeeper TA
128(which runs in the secure environment). The reference implementation assumes the existence of two
129reliable, message-oriented, bi-directional communication channels for this (one for Secretkeeper,
130one for AuthGraph), as encapsulated in the `authgraph_hal::channel::SerializedChannel` trait.
131
132This trait has a single method `execute()`, which takes as input a request message (as bytes), and
133returns a response message (as bytes) or an error.
134
135Two instances of this trait must be provided to the `secretkeeper_hal::SecretkeeperService` type,
136which allows it to service Binder requests by forwarding the requests to the TA as request/response
137pairs.
138
139**Checklist:**
140
141- [ ] Implementation of HAL service, which registers the Secretkeeper HAL service with Binder.
142- [ ] SELinux policy for the HAL service.
143- [ ] `init.rc` configuration for the HAL service.
144- [ ] Implementation of `SerializedChannel` trait, for reliable HAL <-> TA communication.
145
146The [Trusty implementation of the Secretkeeper
147HAL](https://cs.android.com/android/platform/superproject/+/main:system/core/trusty/secretkeeper/src/hal_main.rs)
148provides an example of all of the above.
149
150#### TA Driver
151
152The `secretkeeper_core::ta` module provides the majority of the implementation of the Secretkeeper
153TA, but needs a driver program that:
154
155- Performs start-of-day administration (e.g. logging setup).
156- Creates an `authgraph_core::ta::AuthGraphTa` instance.
157- Creates a `secretkeeper_core_ta::SecretkeeperTa` instance.
158- Configures the pair of communication channels that communicate with the HAL service (one for
159 Secretkeeper, one for AuthGraph).
160- Configures the communication channel with the bootloader, which is required so that the current
161 Secretkeeper identity information can be retrieved at start-of-day.
162- Holds the main loop that:
163 - reads request messages from the channel(s)
164 - passes request messages to `SecretkeeperTa::process()` or `AuthGraphTa::process()`, receiving
165 a response
166 - writes response messages back to the relevant channel.
167
168**Checklist:**
169
170- [ ] Implementation of `main` equivalent for TA, handling scheduling of incoming requests.
171- [ ] Implementation of communication channels between HAL service and TA.
172- [ ] Implementation of communication channel between bootloader and TA.
173
174The [Trusty implementation of the Secretkeeper
175TA](https://android.googlesource.com/trusty/app/secretkeeper/+/refs/heads/main/lib.rs)
176provides an example of all of the above.
177
178#### Bootloader
179
180If Secretkeeper is used to store secrets on behalf of protected virtual machines (pVMs), then the
181bootloader is required to retrieve the identity of Secretkeeper (expressed as a public key) at boot
182time so that the identity can be (securely) provided to pVM instances, as described
183[below](#secretkeeper-public-key). The bootloader should use the
184[`secretkeeper_core::ta::bootloader::GetIdentityKey`
185message](https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/core/src/ta/bootloader.rs?q=GetIdentityKey)
186to do this.
187
188**Checklist:**
189
190- [ ] Implementation of communication channel from bootloader to TA.
191- [ ] Send `GetIdentityKey` request at boot time.
192- [ ] Populate the relevant device tree property.
193
194#### Cryptographic Abstractions
195
196The Secretkeeper TA requires implementations for low-level cryptographic primitives to be provided,
197in the form of implementations of the various Rust traits held in
198[`authgraph_core::traits`](https://cs.android.com/android/platform/superproject/main/+/main:system/authgraph/core/src/traits.rs).
199
200Note that some of these traits include methods that have default implementations, which means that
201an external implementation is not required (but can be provided if desired).
202
203**Checklist:**
204
205- [ ] RNG implementation.
206- [ ] AES-GCM implementation.
207- [ ] HMAC implementation.
208- [ ] ECDH implementation with P-256.
209- [ ] ECDSA implementation (P-256, P-384, Ed25519).
210
211BoringSSL-based implementations are
212[available](https://cs.android.com/android/platform/superproject/main/+/main:system/authgraph/boringssl/src/lib.rs)
213for all of the above.
214
215#### Device-Specific Abstractions
216
217The Secretkeeper requires an implementation of the [`secretkeeper_core::store::KeyValueStore`
218trait](https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/core/src/store.rs?q=%22trait%20KeyValueStore%22)
219that abstracts away access to secure storage.
220
221The Trusty implementation of the Secretkeeper TA includes an [example
222implementation](https://android.googlesource.com/trusty/app/secretkeeper/+/refs/heads/main/store.rs).
223
224**Checklist:**
225
226- [ ] `KeyValueStore` implementation.
227
228## Example usage: Rollback protected secrets of Microdroid based pVMs
229
230Microdroid instances use Secretkeeper to store their secrets while protecting against the Rollback
231attacks on the boot images & packages. Such secrets (and data protected by the secrets) are
232accessible on updates but not on downgrades of boot images and apks.
233
234[authgraphke]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl
235[getauthgraphke]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl?q=getAuthGraphKe
236[secretkeeperhal]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
237[secretmanagement_cddl]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
238[DicePolicyCDDL]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl
239
240### Secretkeeper public key
241
242As described [above](#authgraph-key-exchange), Microdroid as a Secretkeeper
243client establishes a secure channel with the Secretkeeper implementation using
244the AuthGraph key exchange protocol. As part of this Microdroid needs to verify
245that it is communicating with the real Secretkeeper.
246
247To achieve this the Secretkeeper implementation should generate a per-boot key
248pair and use that as its identity in the AuthGraph protocol. The public key from
249the pair then needs to be securely communicated to the Microdroid VM which uses
250it to verify the identity of Secretkeeper.
251
252The public key is transported as a CBOR-encoded COSE_key, as a PubKeyEd25519 /
253PubKeyECDSA256 / PubKeyECDSA384 as defined in
254[generateCertificateRequestV2.cddl][pubkeycddl].
255
256Microdroid expects the public key to be present in the Linux device tree as the
257value of the `secretkeeper_public_key` property of the `/avf` node - exposed to
258userspace at `/proc/device-tree/avf/secretkeeper_public_key`.
259
260When a protected VM is started, AVF populates this property in the VM DT `/avf`
261node from the corresponding property in the `/avf/reference/avf` node in the
262host DT. pvmfw verifies that the value is correct using the VM reference DT that
263is included in the pvmfw [configuration data][pvmfwconfig].
264
265The [Android bootloader][androidbootloader] should request the public key from
266the Secretkeeper implementation at boot time and populate it in both the host
267Android DT and the VM Reference DT for pvmfw.
268
269The reference code for Secretkeeper defines a protocol that can be used by the
270bootloader to retrieve the public key; see
271[core/src/ta/bootloader.rs][skbootloader].
272
273[pubkeycddl]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl;l=143
274[pvmfwconfig]: https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/pvmfw/README.md#configuration-data-format
275[androidbootloader]: https://source.android.com/docs/core/architecture/bootloader
276[skbootloader]: https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/core/src/ta/bootloader.rs
277