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