xref: /aosp_15_r20/system/keymint/ta/src/device.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker 
15*9860b763SAndroid Build Coastguard Worker //! Traits representing access to device-specific information and functionality.
16*9860b763SAndroid Build Coastguard Worker 
17*9860b763SAndroid Build Coastguard Worker use crate::coset::{iana, AsCborValue, CoseSign1Builder, HeaderBuilder};
18*9860b763SAndroid Build Coastguard Worker use alloc::{boxed::Box, vec::Vec};
19*9860b763SAndroid Build Coastguard Worker use kmr_common::{
20*9860b763SAndroid Build Coastguard Worker     crypto, crypto::aes, crypto::hmac, crypto::KeyMaterial, crypto::OpaqueOr, keyblob, log_unimpl,
21*9860b763SAndroid Build Coastguard Worker     unimpl, Error,
22*9860b763SAndroid Build Coastguard Worker };
23*9860b763SAndroid Build Coastguard Worker use kmr_wire::{keymint, rpc, secureclock::TimeStampToken, CborError};
24*9860b763SAndroid Build Coastguard Worker use log::error;
25*9860b763SAndroid Build Coastguard Worker 
26*9860b763SAndroid Build Coastguard Worker use crate::rkp::serialize_cbor;
27*9860b763SAndroid Build Coastguard Worker 
28*9860b763SAndroid Build Coastguard Worker /// Context used to derive the hardware backed key for computing HMAC in
29*9860b763SAndroid Build Coastguard Worker /// IRemotelyProvisionedComponent.
30*9860b763SAndroid Build Coastguard Worker pub const RPC_HMAC_KEY_CONTEXT: &[u8] = b"Key to MAC public keys";
31*9860b763SAndroid Build Coastguard Worker 
32*9860b763SAndroid Build Coastguard Worker /// Length (in bytes) of the HMAC key used in IRemotelyProvisionedComponent.
33*9860b763SAndroid Build Coastguard Worker pub const RPC_HMAC_KEY_LEN: usize = 32;
34*9860b763SAndroid Build Coastguard Worker 
35*9860b763SAndroid Build Coastguard Worker /// Combined collection of trait implementations that must be provided.
36*9860b763SAndroid Build Coastguard Worker pub struct Implementation {
37*9860b763SAndroid Build Coastguard Worker     /// Retrieval of root key material.
38*9860b763SAndroid Build Coastguard Worker     pub keys: Box<dyn RetrieveKeyMaterial>,
39*9860b763SAndroid Build Coastguard Worker 
40*9860b763SAndroid Build Coastguard Worker     /// Retrieval of attestation certificate signing information.
41*9860b763SAndroid Build Coastguard Worker     pub sign_info: Option<Box<dyn RetrieveCertSigningInfo>>,
42*9860b763SAndroid Build Coastguard Worker 
43*9860b763SAndroid Build Coastguard Worker     /// Retrieval of attestation ID information.
44*9860b763SAndroid Build Coastguard Worker     pub attest_ids: Option<Box<dyn RetrieveAttestationIds>>,
45*9860b763SAndroid Build Coastguard Worker 
46*9860b763SAndroid Build Coastguard Worker     /// Secure deletion secret manager.  If not available, rollback-resistant
47*9860b763SAndroid Build Coastguard Worker     /// keys will not be supported.
48*9860b763SAndroid Build Coastguard Worker     pub sdd_mgr: Option<Box<dyn keyblob::SecureDeletionSecretManager>>,
49*9860b763SAndroid Build Coastguard Worker 
50*9860b763SAndroid Build Coastguard Worker     /// Retrieval of bootloader status.
51*9860b763SAndroid Build Coastguard Worker     pub bootloader: Box<dyn BootloaderStatus>,
52*9860b763SAndroid Build Coastguard Worker 
53*9860b763SAndroid Build Coastguard Worker     /// Storage key wrapping. If not available `convertStorageKeyToEphemeral()` will not be
54*9860b763SAndroid Build Coastguard Worker     /// supported
55*9860b763SAndroid Build Coastguard Worker     pub sk_wrapper: Option<Box<dyn StorageKeyWrapper>>,
56*9860b763SAndroid Build Coastguard Worker 
57*9860b763SAndroid Build Coastguard Worker     /// Trusted user presence indicator.
58*9860b763SAndroid Build Coastguard Worker     pub tup: Box<dyn TrustedUserPresence>,
59*9860b763SAndroid Build Coastguard Worker 
60*9860b763SAndroid Build Coastguard Worker     /// Legacy key conversion handling.
61*9860b763SAndroid Build Coastguard Worker     pub legacy_key: Option<Box<dyn keyblob::LegacyKeyHandler>>,
62*9860b763SAndroid Build Coastguard Worker 
63*9860b763SAndroid Build Coastguard Worker     /// Retrieval of artifacts related to the device implementation of IRemotelyProvisionedComponent
64*9860b763SAndroid Build Coastguard Worker     /// (IRPC) HAL.
65*9860b763SAndroid Build Coastguard Worker     pub rpc: Box<dyn RetrieveRpcArtifacts>,
66*9860b763SAndroid Build Coastguard Worker }
67*9860b763SAndroid Build Coastguard Worker 
68*9860b763SAndroid Build Coastguard Worker /// Functionality related to retrieval of device-specific key material, and its subsequent use.
69*9860b763SAndroid Build Coastguard Worker /// The caller is generally expected to drop the key material as soon as it is done with it.
70*9860b763SAndroid Build Coastguard Worker pub trait RetrieveKeyMaterial {
71*9860b763SAndroid Build Coastguard Worker     /// Retrieve the root key used for derivation of a per-keyblob key encryption key (KEK), passing
72*9860b763SAndroid Build Coastguard Worker     /// in any opaque context.
root_kek(&self, context: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>73*9860b763SAndroid Build Coastguard Worker     fn root_kek(&self, context: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>;
74*9860b763SAndroid Build Coastguard Worker 
75*9860b763SAndroid Build Coastguard Worker     /// Retrieve any opaque (but non-confidential) context needed for future calls to `root_kek`.
76*9860b763SAndroid Build Coastguard Worker     /// Context should not include confidential data (it will be stored in the clear).
kek_context(&self) -> Result<Vec<u8>, Error>77*9860b763SAndroid Build Coastguard Worker     fn kek_context(&self) -> Result<Vec<u8>, Error> {
78*9860b763SAndroid Build Coastguard Worker         // Default implementation is to have an empty KEK retrieval context.
79*9860b763SAndroid Build Coastguard Worker         Ok(Vec::new())
80*9860b763SAndroid Build Coastguard Worker     }
81*9860b763SAndroid Build Coastguard Worker 
82*9860b763SAndroid Build Coastguard Worker     /// Retrieve the key agreement key used for shared secret negotiation.
kak(&self) -> Result<OpaqueOr<aes::Key>, Error>83*9860b763SAndroid Build Coastguard Worker     fn kak(&self) -> Result<OpaqueOr<aes::Key>, Error>;
84*9860b763SAndroid Build Coastguard Worker 
85*9860b763SAndroid Build Coastguard Worker     /// Install the device HMAC agreed by shared secret negotiation into hardware (optional).
hmac_key_agreed(&self, _key: &crypto::hmac::Key) -> Option<Box<dyn DeviceHmac>>86*9860b763SAndroid Build Coastguard Worker     fn hmac_key_agreed(&self, _key: &crypto::hmac::Key) -> Option<Box<dyn DeviceHmac>> {
87*9860b763SAndroid Build Coastguard Worker         // By default, use a software implementation that holds the key in memory.
88*9860b763SAndroid Build Coastguard Worker         None
89*9860b763SAndroid Build Coastguard Worker     }
90*9860b763SAndroid Build Coastguard Worker 
91*9860b763SAndroid Build Coastguard Worker     /// Retrieve the hardware backed secret used for UNIQUE_ID generation.
unique_id_hbk(&self, ckdf: &dyn crypto::Ckdf) -> Result<crypto::hmac::Key, Error>92*9860b763SAndroid Build Coastguard Worker     fn unique_id_hbk(&self, ckdf: &dyn crypto::Ckdf) -> Result<crypto::hmac::Key, Error> {
93*9860b763SAndroid Build Coastguard Worker         // By default, use CKDF on the key agreement secret to derive a key.
94*9860b763SAndroid Build Coastguard Worker         let unique_id_label = b"UniqueID HBK 32B";
95*9860b763SAndroid Build Coastguard Worker         ckdf.ckdf(&self.kak()?, unique_id_label, &[], 32).map(crypto::hmac::Key::new)
96*9860b763SAndroid Build Coastguard Worker     }
97*9860b763SAndroid Build Coastguard Worker 
98*9860b763SAndroid Build Coastguard Worker     /// Build the HMAC input for a [`TimeStampToken`].  The default implementation produces
99*9860b763SAndroid Build Coastguard Worker     /// data that matches the `ISecureClock` AIDL specification; this method should only be
100*9860b763SAndroid Build Coastguard Worker     /// overridden for back-compatibility reasons.
timestamp_token_mac_input(&self, token: &TimeStampToken) -> Result<Vec<u8>, Error>101*9860b763SAndroid Build Coastguard Worker     fn timestamp_token_mac_input(&self, token: &TimeStampToken) -> Result<Vec<u8>, Error> {
102*9860b763SAndroid Build Coastguard Worker         crate::clock::timestamp_token_mac_input(token)
103*9860b763SAndroid Build Coastguard Worker     }
104*9860b763SAndroid Build Coastguard Worker }
105*9860b763SAndroid Build Coastguard Worker 
106*9860b763SAndroid Build Coastguard Worker /// Device HMAC calculation.
107*9860b763SAndroid Build Coastguard Worker pub trait DeviceHmac {
108*9860b763SAndroid Build Coastguard Worker     /// Calculate the HMAC over the data using the agreed device HMAC key.
hmac(&self, imp: &dyn crypto::Hmac, data: &[u8]) -> Result<Vec<u8>, Error>109*9860b763SAndroid Build Coastguard Worker     fn hmac(&self, imp: &dyn crypto::Hmac, data: &[u8]) -> Result<Vec<u8>, Error>;
110*9860b763SAndroid Build Coastguard Worker 
111*9860b763SAndroid Build Coastguard Worker     /// Returns the key used for HMAC'ing data if available
get_hmac_key(&self) -> Option<crypto::hmac::Key>112*9860b763SAndroid Build Coastguard Worker     fn get_hmac_key(&self) -> Option<crypto::hmac::Key> {
113*9860b763SAndroid Build Coastguard Worker         // By default we assume that the implementation cannot return a key
114*9860b763SAndroid Build Coastguard Worker         None
115*9860b763SAndroid Build Coastguard Worker     }
116*9860b763SAndroid Build Coastguard Worker }
117*9860b763SAndroid Build Coastguard Worker 
118*9860b763SAndroid Build Coastguard Worker /// Identification of which attestation signing key is required.
119*9860b763SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
120*9860b763SAndroid Build Coastguard Worker pub enum SigningKey {
121*9860b763SAndroid Build Coastguard Worker     /// Use a batch key that is shared across multiple devices (to prevent the keys being used as
122*9860b763SAndroid Build Coastguard Worker     /// device identifiers).
123*9860b763SAndroid Build Coastguard Worker     Batch,
124*9860b763SAndroid Build Coastguard Worker     /// Use a device-unique key for signing. Only supported for StrongBox.
125*9860b763SAndroid Build Coastguard Worker     DeviceUnique,
126*9860b763SAndroid Build Coastguard Worker }
127*9860b763SAndroid Build Coastguard Worker 
128*9860b763SAndroid Build Coastguard Worker /// Indication of preferred attestation signing algorithm.
129*9860b763SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
130*9860b763SAndroid Build Coastguard Worker pub enum SigningAlgorithm {
131*9860b763SAndroid Build Coastguard Worker     /// Prefer to sign with an elliptic curve key.
132*9860b763SAndroid Build Coastguard Worker     Ec,
133*9860b763SAndroid Build Coastguard Worker     /// Prefer to sign with an RSA key.
134*9860b763SAndroid Build Coastguard Worker     Rsa,
135*9860b763SAndroid Build Coastguard Worker }
136*9860b763SAndroid Build Coastguard Worker 
137*9860b763SAndroid Build Coastguard Worker /// Indication of required signing key.
138*9860b763SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
139*9860b763SAndroid Build Coastguard Worker pub struct SigningKeyType {
140*9860b763SAndroid Build Coastguard Worker     /// Indicates the preferred type of signing key.
141*9860b763SAndroid Build Coastguard Worker     pub which: SigningKey,
142*9860b763SAndroid Build Coastguard Worker     /// Indicates what is going to be signed, to allow implementations to (optionally) use EC / RSA
143*9860b763SAndroid Build Coastguard Worker     /// signing keys for EC / RSA keys respectively.
144*9860b763SAndroid Build Coastguard Worker     pub algo_hint: SigningAlgorithm,
145*9860b763SAndroid Build Coastguard Worker }
146*9860b763SAndroid Build Coastguard Worker 
147*9860b763SAndroid Build Coastguard Worker /// Retrieval of attestation certificate signing information.  The caller is expected to drop key
148*9860b763SAndroid Build Coastguard Worker /// material after use, but may cache public key material.
149*9860b763SAndroid Build Coastguard Worker pub trait RetrieveCertSigningInfo {
150*9860b763SAndroid Build Coastguard Worker     /// Return the signing key material for the specified `key_type`.  The `algo_hint` parameter
151*9860b763SAndroid Build Coastguard Worker     /// indicates what is going to be signed, to allow implementations to (optionally) use EC / RSA
152*9860b763SAndroid Build Coastguard Worker     /// signing keys for EC /RSA keys respectively.
signing_key(&self, key_type: SigningKeyType) -> Result<KeyMaterial, Error>153*9860b763SAndroid Build Coastguard Worker     fn signing_key(&self, key_type: SigningKeyType) -> Result<KeyMaterial, Error>;
154*9860b763SAndroid Build Coastguard Worker 
155*9860b763SAndroid Build Coastguard Worker     /// Return the certificate chain associated with the specified signing key, where:
156*9860b763SAndroid Build Coastguard Worker     /// - `chain[0]` holds the public key that corresponds to `signing_key`, and which is signed
157*9860b763SAndroid Build Coastguard Worker     ///   by...
158*9860b763SAndroid Build Coastguard Worker     /// - the keypair described by the second entry `chain[1]`, which in turn is signed by...
159*9860b763SAndroid Build Coastguard Worker     /// - ...
160*9860b763SAndroid Build Coastguard Worker     /// - the final certificate in the chain should be a self-signed cert holding a Google root.
cert_chain(&self, key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error>161*9860b763SAndroid Build Coastguard Worker     fn cert_chain(&self, key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error>;
162*9860b763SAndroid Build Coastguard Worker }
163*9860b763SAndroid Build Coastguard Worker 
164*9860b763SAndroid Build Coastguard Worker /// Retrieval of attestation ID information.  This information will not change (so the caller can
165*9860b763SAndroid Build Coastguard Worker /// cache this information after first invocation).
166*9860b763SAndroid Build Coastguard Worker pub trait RetrieveAttestationIds {
167*9860b763SAndroid Build Coastguard Worker     /// Return the attestation IDs associated with the device, if available.
get(&self) -> Result<crate::AttestationIdInfo, Error>168*9860b763SAndroid Build Coastguard Worker     fn get(&self) -> Result<crate::AttestationIdInfo, Error>;
169*9860b763SAndroid Build Coastguard Worker 
170*9860b763SAndroid Build Coastguard Worker     /// Destroy all attestation IDs associated with the device.
destroy_all(&mut self) -> Result<(), Error>171*9860b763SAndroid Build Coastguard Worker     fn destroy_all(&mut self) -> Result<(), Error>;
172*9860b763SAndroid Build Coastguard Worker }
173*9860b763SAndroid Build Coastguard Worker 
174*9860b763SAndroid Build Coastguard Worker /// Bootloader status.
175*9860b763SAndroid Build Coastguard Worker pub trait BootloaderStatus {
176*9860b763SAndroid Build Coastguard Worker     /// Indication of whether bootloader processing is complete
done(&self) -> bool177*9860b763SAndroid Build Coastguard Worker     fn done(&self) -> bool {
178*9860b763SAndroid Build Coastguard Worker         // By default assume that the bootloader is done before KeyMint starts.
179*9860b763SAndroid Build Coastguard Worker         true
180*9860b763SAndroid Build Coastguard Worker     }
181*9860b763SAndroid Build Coastguard Worker }
182*9860b763SAndroid Build Coastguard Worker 
183*9860b763SAndroid Build Coastguard Worker /// The trait that represents the device specific integration points required for the
184*9860b763SAndroid Build Coastguard Worker /// implementation of IRemotelyProvisionedComponent (IRPC) HAL.
185*9860b763SAndroid Build Coastguard Worker /// Note: The devices only supporting IRPC V3+ may ignore the optional IRPC V2 specific types in
186*9860b763SAndroid Build Coastguard Worker /// the method signatures.
187*9860b763SAndroid Build Coastguard Worker pub trait RetrieveRpcArtifacts {
188*9860b763SAndroid Build Coastguard Worker     /// Retrieve secret bytes (of the given output length) derived from a hardware backed key.
189*9860b763SAndroid Build Coastguard Worker     /// For a given context, the output is deterministic.
derive_bytes_from_hbk( &self, hkdf: &dyn crypto::Hkdf, context: &[u8], output_len: usize, ) -> Result<Vec<u8>, Error>190*9860b763SAndroid Build Coastguard Worker     fn derive_bytes_from_hbk(
191*9860b763SAndroid Build Coastguard Worker         &self,
192*9860b763SAndroid Build Coastguard Worker         hkdf: &dyn crypto::Hkdf,
193*9860b763SAndroid Build Coastguard Worker         context: &[u8],
194*9860b763SAndroid Build Coastguard Worker         output_len: usize,
195*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error>;
196*9860b763SAndroid Build Coastguard Worker 
197*9860b763SAndroid Build Coastguard Worker     /// Compute HMAC_SHA256 over the given input using a key derived from hardware.
compute_hmac_sha256( &self, hmac: &dyn crypto::Hmac, hkdf: &dyn crypto::Hkdf, input: &[u8], ) -> Result<Vec<u8>, Error>198*9860b763SAndroid Build Coastguard Worker     fn compute_hmac_sha256(
199*9860b763SAndroid Build Coastguard Worker         &self,
200*9860b763SAndroid Build Coastguard Worker         hmac: &dyn crypto::Hmac,
201*9860b763SAndroid Build Coastguard Worker         hkdf: &dyn crypto::Hkdf,
202*9860b763SAndroid Build Coastguard Worker         input: &[u8],
203*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
204*9860b763SAndroid Build Coastguard Worker         let secret = self.derive_bytes_from_hbk(hkdf, RPC_HMAC_KEY_CONTEXT, RPC_HMAC_KEY_LEN)?;
205*9860b763SAndroid Build Coastguard Worker         crypto::hmac_sha256(hmac, &secret, input)
206*9860b763SAndroid Build Coastguard Worker     }
207*9860b763SAndroid Build Coastguard Worker 
208*9860b763SAndroid Build Coastguard Worker     /// Retrieve the information about the DICE chain belonging to the IRPC HAL implementation.
get_dice_info(&self, test_mode: rpc::TestMode) -> Result<DiceInfo, Error>209*9860b763SAndroid Build Coastguard Worker     fn get_dice_info(&self, test_mode: rpc::TestMode) -> Result<DiceInfo, Error>;
210*9860b763SAndroid Build Coastguard Worker 
211*9860b763SAndroid Build Coastguard Worker     /// Sign the input data with the CDI leaf private key of the IRPC HAL implementation. In IRPC V2,
212*9860b763SAndroid Build Coastguard Worker     /// the `data` to be signed is the `SignedMac_structure` in ProtectedData.aidl, when signing
213*9860b763SAndroid Build Coastguard Worker     /// the ephemeral MAC key used to authenticate the public keys. In IRPC V3, the `data` to be
214*9860b763SAndroid Build Coastguard Worker     /// signed is the `SignedDataSigStruct`.
215*9860b763SAndroid Build Coastguard Worker     /// If a particular implementation would like to return the signature in a COSE_Sign1 message,
216*9860b763SAndroid Build Coastguard Worker     /// they can mark this unimplemented and override the default implementation in the
217*9860b763SAndroid Build Coastguard Worker     /// `sign_data_in_cose_sign1` method below.
218*9860b763SAndroid Build Coastguard Worker     ///
219*9860b763SAndroid Build Coastguard Worker     /// The signature produced by this method should be in a format suitable for COSE structures:
220*9860b763SAndroid Build Coastguard Worker     /// - Ed25519 signatures are encoded as-is.
221*9860b763SAndroid Build Coastguard Worker     /// - NIST signatures are encoded as (r||s), with each value left-padded with zeroes to
222*9860b763SAndroid Build Coastguard Worker     ///   the coordinate length.  Note that this is a *different* format than is emitted by
223*9860b763SAndroid Build Coastguard Worker     ///   the `kmr_common::crypto::Ec` trait.
224*9860b763SAndroid Build Coastguard Worker     ///
225*9860b763SAndroid Build Coastguard Worker     /// (The `kmr_common::crypto::ec::to_cose_signature()` function can help with this.)
sign_data( &self, ec: &dyn crypto::Ec, data: &[u8], rpc_v2: Option<RpcV2Req>, ) -> Result<Vec<u8>, Error>226*9860b763SAndroid Build Coastguard Worker     fn sign_data(
227*9860b763SAndroid Build Coastguard Worker         &self,
228*9860b763SAndroid Build Coastguard Worker         ec: &dyn crypto::Ec,
229*9860b763SAndroid Build Coastguard Worker         data: &[u8],
230*9860b763SAndroid Build Coastguard Worker         rpc_v2: Option<RpcV2Req>,
231*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error>;
232*9860b763SAndroid Build Coastguard Worker 
233*9860b763SAndroid Build Coastguard Worker     /// Sign the payload and return a COSE_Sign1 message. In IRPC V2, the `payload` is the MAC Key.
234*9860b763SAndroid Build Coastguard Worker     /// In IRPC V3, the `payload` is the `Data` that the `SignedData` is parameterized with (i.e. a
235*9860b763SAndroid Build Coastguard Worker     /// CBOR array containing `challenge` and `CsrPayload`).
sign_data_in_cose_sign1( &self, ec: &dyn crypto::Ec, signing_algorithm: &CsrSigningAlgorithm, payload: &[u8], _aad: &[u8], _rpc_v2: Option<RpcV2Req>, ) -> Result<Vec<u8>, Error>236*9860b763SAndroid Build Coastguard Worker     fn sign_data_in_cose_sign1(
237*9860b763SAndroid Build Coastguard Worker         &self,
238*9860b763SAndroid Build Coastguard Worker         ec: &dyn crypto::Ec,
239*9860b763SAndroid Build Coastguard Worker         signing_algorithm: &CsrSigningAlgorithm,
240*9860b763SAndroid Build Coastguard Worker         payload: &[u8],
241*9860b763SAndroid Build Coastguard Worker         _aad: &[u8],
242*9860b763SAndroid Build Coastguard Worker         _rpc_v2: Option<RpcV2Req>,
243*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
244*9860b763SAndroid Build Coastguard Worker         let cose_sign_algorithm = match signing_algorithm {
245*9860b763SAndroid Build Coastguard Worker             CsrSigningAlgorithm::ES256 => iana::Algorithm::ES256,
246*9860b763SAndroid Build Coastguard Worker             CsrSigningAlgorithm::ES384 => iana::Algorithm::ES384,
247*9860b763SAndroid Build Coastguard Worker             CsrSigningAlgorithm::EdDSA => iana::Algorithm::EdDSA,
248*9860b763SAndroid Build Coastguard Worker         };
249*9860b763SAndroid Build Coastguard Worker         // Construct `SignedData`
250*9860b763SAndroid Build Coastguard Worker         let protected = HeaderBuilder::new().algorithm(cose_sign_algorithm).build();
251*9860b763SAndroid Build Coastguard Worker         let signed_data = CoseSign1Builder::new()
252*9860b763SAndroid Build Coastguard Worker             .protected(protected)
253*9860b763SAndroid Build Coastguard Worker             .payload(payload.to_vec())
254*9860b763SAndroid Build Coastguard Worker             .try_create_signature(&[], |input| self.sign_data(ec, input, None))?
255*9860b763SAndroid Build Coastguard Worker             .build();
256*9860b763SAndroid Build Coastguard Worker         let signed_data_cbor = signed_data.to_cbor_value().map_err(CborError::from)?;
257*9860b763SAndroid Build Coastguard Worker         serialize_cbor(&signed_data_cbor)
258*9860b763SAndroid Build Coastguard Worker     }
259*9860b763SAndroid Build Coastguard Worker }
260*9860b763SAndroid Build Coastguard Worker 
261*9860b763SAndroid Build Coastguard Worker /// Information about the DICE chain belonging to the implementation of the IRPC HAL.
262*9860b763SAndroid Build Coastguard Worker #[derive(Clone)]
263*9860b763SAndroid Build Coastguard Worker pub struct DiceInfo {
264*9860b763SAndroid Build Coastguard Worker     /// Public dice artifacts.
265*9860b763SAndroid Build Coastguard Worker     pub pub_dice_artifacts: PubDiceArtifacts,
266*9860b763SAndroid Build Coastguard Worker     /// Algorithm used for signing CSRs.
267*9860b763SAndroid Build Coastguard Worker     pub signing_algorithm: CsrSigningAlgorithm,
268*9860b763SAndroid Build Coastguard Worker     /// Test-mode CDI private key.
269*9860b763SAndroid Build Coastguard Worker     ///
270*9860b763SAndroid Build Coastguard Worker     /// This is only relevant for IRPC HAL V2 when `test_mode` is true. This is ignored in all other
271*9860b763SAndroid Build Coastguard Worker     /// cases. The optional test CDI private key may be set here, if the device implementers
272*9860b763SAndroid Build Coastguard Worker     /// do not want to cache the test CDI private key across the calls to the `get_dice_info` and
273*9860b763SAndroid Build Coastguard Worker     ///`sign_data` methods when creating the CSR.
274*9860b763SAndroid Build Coastguard Worker     pub rpc_v2_test_cdi_priv: Option<RpcV2TestCDIPriv>,
275*9860b763SAndroid Build Coastguard Worker }
276*9860b763SAndroid Build Coastguard Worker 
277*9860b763SAndroid Build Coastguard Worker /// Algorithm used to sign with the CDI leaf private key.
278*9860b763SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug)]
279*9860b763SAndroid Build Coastguard Worker pub enum CsrSigningAlgorithm {
280*9860b763SAndroid Build Coastguard Worker     /// Sign with P-256 EC key.
281*9860b763SAndroid Build Coastguard Worker     ES256,
282*9860b763SAndroid Build Coastguard Worker     /// Sign with P-384 EC key.
283*9860b763SAndroid Build Coastguard Worker     ES384,
284*9860b763SAndroid Build Coastguard Worker     /// Sign with Ed25519 key.
285*9860b763SAndroid Build Coastguard Worker     EdDSA,
286*9860b763SAndroid Build Coastguard Worker }
287*9860b763SAndroid Build Coastguard Worker 
288*9860b763SAndroid Build Coastguard Worker /// Public DICE artifacts.
289*9860b763SAndroid Build Coastguard Worker #[derive(Clone, Debug)]
290*9860b763SAndroid Build Coastguard Worker pub struct PubDiceArtifacts {
291*9860b763SAndroid Build Coastguard Worker     /// Certificates for the UDS Pub encoded in CBOR as per `AdditionalDKSignatures` structure in
292*9860b763SAndroid Build Coastguard Worker     /// ProtectedData.aidl for IRPC HAL version 2 and as per `UdsCerts` structure in IRPC HAL
293*9860b763SAndroid Build Coastguard Worker     /// version 3.
294*9860b763SAndroid Build Coastguard Worker     pub uds_certs: Vec<u8>,
295*9860b763SAndroid Build Coastguard Worker     /// UDS Pub and the DICE certificates encoded in CBOR/COSE as per the `Bcc` structure
296*9860b763SAndroid Build Coastguard Worker     /// defined in ProtectedData.aidl for IRPC HAL version 2 and as per `DiceCertChain` structure
297*9860b763SAndroid Build Coastguard Worker     /// in IRPC HAL version 3.
298*9860b763SAndroid Build Coastguard Worker     pub dice_cert_chain: Vec<u8>,
299*9860b763SAndroid Build Coastguard Worker }
300*9860b763SAndroid Build Coastguard Worker 
301*9860b763SAndroid Build Coastguard Worker /// Enum distinguishing the two modes of operation for IRPC HAL V2, allowing an optional context
302*9860b763SAndroid Build Coastguard Worker /// information to be passed in for the test mode.
303*9860b763SAndroid Build Coastguard Worker pub enum RpcV2Req<'a> {
304*9860b763SAndroid Build Coastguard Worker     /// IRPC v2 request in production mode.
305*9860b763SAndroid Build Coastguard Worker     Production,
306*9860b763SAndroid Build Coastguard Worker     /// An opaque blob may be passed in for the test mode, if it was returned by the TA in
307*9860b763SAndroid Build Coastguard Worker     /// `RkpV2TestCDIPriv.context` in order to link the two requests: `get_dice_info` and `sign_data`
308*9860b763SAndroid Build Coastguard Worker     /// related to the same CSR.
309*9860b763SAndroid Build Coastguard Worker     Test(&'a [u8]),
310*9860b763SAndroid Build Coastguard Worker }
311*9860b763SAndroid Build Coastguard Worker 
312*9860b763SAndroid Build Coastguard Worker /// Struct encapsulating the optional CDI private key and the optional opaque context that may be
313*9860b763SAndroid Build Coastguard Worker /// returned with `DiceInfo` in IRPC V2 test mode.
314*9860b763SAndroid Build Coastguard Worker #[derive(Clone)]
315*9860b763SAndroid Build Coastguard Worker pub struct RpcV2TestCDIPriv {
316*9860b763SAndroid Build Coastguard Worker     /// Test-mode CDI private key, if available.
317*9860b763SAndroid Build Coastguard Worker     pub test_cdi_priv: Option<OpaqueOr<crypto::ec::Key>>,
318*9860b763SAndroid Build Coastguard Worker     /// An optional opaque blob set by the TA, if the TA wants a mechanism to relate the
319*9860b763SAndroid Build Coastguard Worker     /// two requests: `get_dice_info` and `sign_data` related to the same CSR.
320*9860b763SAndroid Build Coastguard Worker     pub context: Vec<u8>,
321*9860b763SAndroid Build Coastguard Worker }
322*9860b763SAndroid Build Coastguard Worker 
323*9860b763SAndroid Build Coastguard Worker /// Marker implementation for implementations that do not support `BOOTLOADER_ONLY` keys, which
324*9860b763SAndroid Build Coastguard Worker /// always indicates that bootloader processing is complete.
325*9860b763SAndroid Build Coastguard Worker pub struct BootloaderDone;
326*9860b763SAndroid Build Coastguard Worker impl BootloaderStatus for BootloaderDone {}
327*9860b763SAndroid Build Coastguard Worker 
328*9860b763SAndroid Build Coastguard Worker /// Trusted user presence indicator.
329*9860b763SAndroid Build Coastguard Worker pub trait TrustedUserPresence {
330*9860b763SAndroid Build Coastguard Worker     /// Indication of whether user presence is detected, via a mechanism in the current secure
331*9860b763SAndroid Build Coastguard Worker     /// environment.
available(&self) -> bool332*9860b763SAndroid Build Coastguard Worker     fn available(&self) -> bool {
333*9860b763SAndroid Build Coastguard Worker         // By default assume that trusted user presence is not supported.
334*9860b763SAndroid Build Coastguard Worker         false
335*9860b763SAndroid Build Coastguard Worker     }
336*9860b763SAndroid Build Coastguard Worker }
337*9860b763SAndroid Build Coastguard Worker 
338*9860b763SAndroid Build Coastguard Worker /// Marker implementation to indicate that trusted user presence is not supported.
339*9860b763SAndroid Build Coastguard Worker pub struct TrustedPresenceUnsupported;
340*9860b763SAndroid Build Coastguard Worker impl TrustedUserPresence for TrustedPresenceUnsupported {}
341*9860b763SAndroid Build Coastguard Worker 
342*9860b763SAndroid Build Coastguard Worker /// Storage key wrapping.
343*9860b763SAndroid Build Coastguard Worker pub trait StorageKeyWrapper {
344*9860b763SAndroid Build Coastguard Worker     /// Wrap the provided key material using an ephemeral storage key.
ephemeral_wrap(&self, key_material: &KeyMaterial) -> Result<Vec<u8>, Error>345*9860b763SAndroid Build Coastguard Worker     fn ephemeral_wrap(&self, key_material: &KeyMaterial) -> Result<Vec<u8>, Error>;
346*9860b763SAndroid Build Coastguard Worker }
347*9860b763SAndroid Build Coastguard Worker 
348*9860b763SAndroid Build Coastguard Worker // No-op implementations for the non-optional device traits. These implementations are only
349*9860b763SAndroid Build Coastguard Worker // intended for convenience during the process of porting the KeyMint code to a new environment.
350*9860b763SAndroid Build Coastguard Worker 
351*9860b763SAndroid Build Coastguard Worker /// Stub implementation of [`RetrieveKeyMaterial`].
352*9860b763SAndroid Build Coastguard Worker pub struct NoOpRetrieveKeyMaterial;
353*9860b763SAndroid Build Coastguard Worker impl RetrieveKeyMaterial for NoOpRetrieveKeyMaterial {
root_kek(&self, _context: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error>354*9860b763SAndroid Build Coastguard Worker     fn root_kek(&self, _context: &[u8]) -> Result<OpaqueOr<hmac::Key>, Error> {
355*9860b763SAndroid Build Coastguard Worker         unimpl!();
356*9860b763SAndroid Build Coastguard Worker     }
357*9860b763SAndroid Build Coastguard Worker 
kak(&self) -> Result<OpaqueOr<aes::Key>, Error>358*9860b763SAndroid Build Coastguard Worker     fn kak(&self) -> Result<OpaqueOr<aes::Key>, Error> {
359*9860b763SAndroid Build Coastguard Worker         unimpl!();
360*9860b763SAndroid Build Coastguard Worker     }
361*9860b763SAndroid Build Coastguard Worker }
362*9860b763SAndroid Build Coastguard Worker 
363*9860b763SAndroid Build Coastguard Worker /// Stub implementation of [`RetrieveCertSigningInfo`].
364*9860b763SAndroid Build Coastguard Worker pub struct NoOpRetrieveCertSigningInfo;
365*9860b763SAndroid Build Coastguard Worker impl RetrieveCertSigningInfo for NoOpRetrieveCertSigningInfo {
signing_key(&self, _key_type: SigningKeyType) -> Result<KeyMaterial, Error>366*9860b763SAndroid Build Coastguard Worker     fn signing_key(&self, _key_type: SigningKeyType) -> Result<KeyMaterial, Error> {
367*9860b763SAndroid Build Coastguard Worker         unimpl!();
368*9860b763SAndroid Build Coastguard Worker     }
369*9860b763SAndroid Build Coastguard Worker 
cert_chain(&self, _key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error>370*9860b763SAndroid Build Coastguard Worker     fn cert_chain(&self, _key_type: SigningKeyType) -> Result<Vec<keymint::Certificate>, Error> {
371*9860b763SAndroid Build Coastguard Worker         unimpl!();
372*9860b763SAndroid Build Coastguard Worker     }
373*9860b763SAndroid Build Coastguard Worker }
374*9860b763SAndroid Build Coastguard Worker 
375*9860b763SAndroid Build Coastguard Worker /// Stub implementation of [`RetrieveRpcArtifacts`].
376*9860b763SAndroid Build Coastguard Worker pub struct NoOpRetrieveRpcArtifacts;
377*9860b763SAndroid Build Coastguard Worker impl RetrieveRpcArtifacts for NoOpRetrieveRpcArtifacts {
derive_bytes_from_hbk( &self, _hkdf: &dyn crypto::Hkdf, _context: &[u8], _output_len: usize, ) -> Result<Vec<u8>, Error>378*9860b763SAndroid Build Coastguard Worker     fn derive_bytes_from_hbk(
379*9860b763SAndroid Build Coastguard Worker         &self,
380*9860b763SAndroid Build Coastguard Worker         _hkdf: &dyn crypto::Hkdf,
381*9860b763SAndroid Build Coastguard Worker         _context: &[u8],
382*9860b763SAndroid Build Coastguard Worker         _output_len: usize,
383*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
384*9860b763SAndroid Build Coastguard Worker         unimpl!();
385*9860b763SAndroid Build Coastguard Worker     }
386*9860b763SAndroid Build Coastguard Worker 
get_dice_info<'a>(&self, _test_mode: rpc::TestMode) -> Result<DiceInfo, Error>387*9860b763SAndroid Build Coastguard Worker     fn get_dice_info<'a>(&self, _test_mode: rpc::TestMode) -> Result<DiceInfo, Error> {
388*9860b763SAndroid Build Coastguard Worker         unimpl!();
389*9860b763SAndroid Build Coastguard Worker     }
390*9860b763SAndroid Build Coastguard Worker 
sign_data( &self, _ec: &dyn crypto::Ec, _data: &[u8], _rpc_v2: Option<RpcV2Req>, ) -> Result<Vec<u8>, Error>391*9860b763SAndroid Build Coastguard Worker     fn sign_data(
392*9860b763SAndroid Build Coastguard Worker         &self,
393*9860b763SAndroid Build Coastguard Worker         _ec: &dyn crypto::Ec,
394*9860b763SAndroid Build Coastguard Worker         _data: &[u8],
395*9860b763SAndroid Build Coastguard Worker         _rpc_v2: Option<RpcV2Req>,
396*9860b763SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
397*9860b763SAndroid Build Coastguard Worker         unimpl!();
398*9860b763SAndroid Build Coastguard Worker     }
399*9860b763SAndroid Build Coastguard Worker }
400