1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Implementation of the `IOpaqueKey` AIDL interface. It is used as a handle to key material
18 
19 use alloc::collections::btree_map::BTreeMap;
20 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
21     AesCipherMode::AesCipherMode, KeyLifetime::KeyLifetime, KeyPermissions::KeyPermissions,
22     KeyType::KeyType, KeyUse::KeyUse, OpaqueKeyToken::OpaqueKeyToken, OperationType::OperationType,
23     ProtectionId::ProtectionId, SymmetricCryptoParameters::SymmetricCryptoParameters,
24     SymmetricOperation::SymmetricOperation,
25 };
26 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{
27     IHwCryptoKey::{
28         DeviceKeyId::DeviceKeyId, DiceBoundDerivationKey::DiceBoundDerivationKey,
29         DiceBoundKeyResult::DiceBoundKeyResult,
30     },
31     IOpaqueKey::{BnOpaqueKey, IOpaqueKey},
32     KeyPolicy::KeyPolicy,
33 };
34 use android_hardware_security_see_hwcrypto::binder;
35 use binder::binder_impl::Binder;
36 use ciborium::Value;
37 use core::fmt;
38 use coset::{AsCborValue, CborSerializable, CoseError};
39 use hwcryptohal_common::{
40     aidl_enum_wrapper, cose_enum_gen,
41     err::HwCryptoError,
42     hwcrypto_err,
43     policy::{
44         self, cbor_policy_to_aidl, cbor_serialize_key_policy, KeyLifetimeSerializable,
45         KeyTypeSerializable, KeyUseSerializable,
46     },
47 };
48 use kmr_common::{
49     crypto::{self, Aes, CurveType, Hkdf, Hmac, KeyMaterial, OpaqueOr, Rng},
50     explicit, FallibleAllocExt,
51 };
52 use kmr_wire::{keymint::EcCurve, AsCborValue as _};
53 use std::sync::{Mutex, OnceLock};
54 use tipc::Uuid;
55 
56 use crate::crypto_provider;
57 use crate::helpers;
58 use crate::hwcrypto_device_key::HwCryptoKey;
59 use crate::service_encryption_key::{EncryptedContent, EncryptionHeader, EncryptionHeaderKey};
60 
61 /// Number of bytes of unique value used to check if a key was created on current HWCrypto boot.
62 const UNIQUE_VALUE_SIZEOF: usize = 32;
63 
64 const SEALING_KEY_DERIVATION_HMAC_256_CTX: &[u8] = b"SEALING_KEY_DERIVATION_HMAC_256_CTX";
65 
66 const HW_CRYPTO_WRAP_KEY_HMAC_256_CTX: &[u8] = b"HW_CRYPTO_WRAP_KEY_HMAC_256_CTX";
67 
68 /// Struct to wrap boot unique counter. It is used to tag objects to the current boot.
69 #[derive(Clone)]
70 struct BootUniqueValue([u8; UNIQUE_VALUE_SIZEOF]);
71 
72 impl fmt::Debug for BootUniqueValue {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result73     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74         write!(f, "[BootUniqueValue size: {}; data redacted]", UNIQUE_VALUE_SIZEOF)
75     }
76 }
77 
78 impl PartialEq for BootUniqueValue {
eq(&self, other: &Self) -> bool79     fn eq(&self, other: &Self) -> bool {
80         openssl::memcmp::eq(&self.0, &other.0)
81     }
82 }
83 
84 impl Eq for BootUniqueValue {}
85 
86 impl BootUniqueValue {
new() -> Result<BootUniqueValue, HwCryptoError>87     fn new() -> Result<BootUniqueValue, HwCryptoError> {
88         get_boot_unique_value()
89     }
90 }
91 
92 // Boot unique value is lazily initialized on the first call to retrieve it
93 static BOOT_UNIQUE_VALUE: OnceLock<BootUniqueValue> = OnceLock::new();
94 
95 /// Retrieves boot unique value used to check if the key material was created on this boot. It
96 /// lazily initializes it.
get_boot_unique_value() -> Result<BootUniqueValue, HwCryptoError>97 fn get_boot_unique_value() -> Result<BootUniqueValue, HwCryptoError> {
98     // The function returns a `Result` even if it is currently infallible to allow replacing its
99     // current implementation with one that can fail when trying to retrieve a random number.
100     // If the RNG changes to a fallible one we could use `get_or_try_init`.
101     let boot_unique_value = BOOT_UNIQUE_VALUE.get_or_init(|| {
102         let mut rng = crypto_provider::RngImpl::default();
103         let mut new_boot_unique_value = BootUniqueValue([0u8; UNIQUE_VALUE_SIZEOF]);
104         rng.fill_bytes(&mut new_boot_unique_value.0[..]);
105         new_boot_unique_value
106     });
107     Ok(boot_unique_value.clone())
108 }
109 
110 #[derive(Copy, Clone)]
111 pub(crate) enum HkdfOperationType {
112     DiceBoundDerivation = 1,
113     ClearKeyDerivation = 3,
114     OpaqueKeyDerivation = 4,
115     InternalSealingKeyDerivation = 5,
116 }
117 
118 pub(crate) struct DerivationContext {
119     context_components: Vec<Value>,
120 }
121 
122 impl DerivationContext {
new(op_type: HkdfOperationType) -> Result<Self, HwCryptoError>123     pub(crate) fn new(op_type: HkdfOperationType) -> Result<Self, HwCryptoError> {
124         let mut context_components = Vec::new();
125         context_components.try_reserve(1)?;
126         context_components.push(Value::Integer((op_type as u8).into()));
127         Ok(Self { context_components })
128     }
129 
add_binary_string(&mut self, binary_string: &[u8]) -> Result<(), HwCryptoError>130     pub(crate) fn add_binary_string(&mut self, binary_string: &[u8]) -> Result<(), HwCryptoError> {
131         self.context_components.try_reserve(1)?;
132         let mut context = Vec::new();
133         context.try_reserve(binary_string.len())?;
134         context.extend_from_slice(binary_string);
135         self.context_components.push(Value::Bytes(context));
136         Ok(())
137     }
138 
add_owned_binary_string( &mut self, binary_string: Vec<u8>, ) -> Result<(), HwCryptoError>139     pub(crate) fn add_owned_binary_string(
140         &mut self,
141         binary_string: Vec<u8>,
142     ) -> Result<(), HwCryptoError> {
143         self.context_components.try_reserve(1)?;
144         self.context_components.push(Value::Bytes(binary_string));
145         Ok(())
146     }
147 
add_unsigned_integer(&mut self, value: u64) -> Result<(), HwCryptoError>148     pub(crate) fn add_unsigned_integer(&mut self, value: u64) -> Result<(), HwCryptoError> {
149         self.context_components.try_reserve(1)?;
150         self.context_components.push(Value::Integer(value.into()));
151         Ok(())
152     }
153 
create_key_derivation_context(self) -> Result<Vec<u8>, HwCryptoError>154     pub(crate) fn create_key_derivation_context(self) -> Result<Vec<u8>, HwCryptoError> {
155         let context = Value::Array(self.context_components);
156         Ok(context.to_vec()?)
157     }
158 }
159 
160 #[derive(Debug)]
161 struct KeyHeaderPolicy {
162     key_lifetime: KeyLifetimeSerializable,
163     key_permissions: Vec<KeyPermissions>,
164     key_usage: KeyUseSerializable,
165     key_type: KeyTypeSerializable,
166     management_key: bool,
167 }
168 
169 impl KeyHeaderPolicy {
new(policy: &KeyPolicy) -> Result<Self, HwCryptoError>170     fn new(policy: &KeyPolicy) -> Result<Self, HwCryptoError> {
171         let mut key_permissions = Vec::new();
172         key_permissions.try_extend_from_slice(&policy.keyPermissions[..])?;
173         Ok(Self {
174             key_lifetime: KeyLifetimeSerializable(policy.keyLifetime),
175             key_permissions,
176             key_usage: KeyUseSerializable(policy.usage),
177             key_type: KeyTypeSerializable(policy.keyType),
178             management_key: policy.keyManagementKey,
179         })
180     }
181 
get_policy(&self) -> Result<KeyPolicy, HwCryptoError>182     fn get_policy(&self) -> Result<KeyPolicy, HwCryptoError> {
183         let mut key_permissions = Vec::new();
184         key_permissions.try_extend_from_slice(&self.key_permissions[..])?;
185         Ok(KeyPolicy {
186             usage: self.key_usage.0,
187             keyLifetime: self.key_lifetime.0,
188             keyPermissions: key_permissions,
189             keyType: self.key_type.0,
190             keyManagementKey: self.management_key,
191         })
192     }
193 
try_clone(&self) -> Result<Self, HwCryptoError>194     fn try_clone(&self) -> Result<Self, HwCryptoError> {
195         let mut key_permissions = Vec::new();
196         key_permissions.try_extend_from_slice(&self.key_permissions[..])?;
197         Ok(Self {
198             key_lifetime: self.key_lifetime,
199             key_permissions,
200             key_usage: self.key_usage,
201             key_type: self.key_type,
202             management_key: self.management_key,
203         })
204     }
205 }
206 
check_protection_id_settings( protection_id: &ProtectionIdSerializable, settings: &ProtectionSetting, ) -> Result<bool, HwCryptoError>207 fn check_protection_id_settings(
208     protection_id: &ProtectionIdSerializable,
209     settings: &ProtectionSetting,
210 ) -> Result<bool, HwCryptoError> {
211     match protection_id.0 {
212         ProtectionId::WIDEVINE_OUTPUT_BUFFER => {
213             // For Widevine buffers we cannot create a key that can read into this area
214             Ok(!settings.read_protection)
215         }
216         _ => Err(hwcrypto_err!(BAD_PARAMETER, "unsupported protection_id {:?}", protection_id,)),
217     }
218 }
219 
220 #[derive(Debug)]
221 struct KeyHeaderMetadata {
222     expiration_time: Option<u64>,
223     protection_id_settings: BTreeMap<ProtectionIdSerializable, ProtectionSetting>,
224 }
225 
226 impl KeyHeaderMetadata {
new() -> Self227     fn new() -> Self {
228         Self { expiration_time: None, protection_id_settings: BTreeMap::new() }
229     }
230 
231     // While the current metadata definition wouldn't fail on this operation, we are doing this
232     // division to add an element to metadata that could fail while ying to clone
try_clone(&self) -> Result<Self, HwCryptoError>233     fn try_clone(&self) -> Result<Self, HwCryptoError> {
234         let mut protection_id_settings = BTreeMap::new();
235         protection_id_settings.extend(self.protection_id_settings.iter());
236         Ok(Self { expiration_time: None, protection_id_settings })
237     }
238 
add_protection_id( &mut self, protection_id: ProtectionId, allowed_operations: &[OperationType], ) -> Result<(), HwCryptoError>239     fn add_protection_id(
240         &mut self,
241         protection_id: ProtectionId,
242         allowed_operations: &[OperationType],
243     ) -> Result<(), HwCryptoError> {
244         if allowed_operations.is_empty() {
245             return Err(hwcrypto_err!(
246                 BAD_PARAMETER,
247                 "didn't receive any allowed operations for add_protection_id",
248             ));
249         }
250         let protection_id = ProtectionIdSerializable::try_from(protection_id)?;
251         if !self.protection_id_settings.contains_key(&protection_id) {
252             return Err(hwcrypto_err!(
253                 BAD_PARAMETER,
254                 "settings for protection id {:?} have already been set",
255                 protection_id
256             ));
257         }
258         let mut protection_setting =
259             ProtectionSetting { write_protection: false, read_protection: false };
260         for operation in allowed_operations {
261             match *operation {
262                 OperationType::READ => protection_setting.read_protection = true,
263                 OperationType::WRITE => protection_setting.write_protection = true,
264                 _ => {
265                     return Err(hwcrypto_err!(
266                         BAD_PARAMETER,
267                         "received unsupported OperationType {:?}",
268                         operation
269                     ))
270                 }
271             }
272         }
273         if !check_protection_id_settings(&protection_id, &protection_setting)? {
274             return Err(hwcrypto_err!(
275                 BAD_PARAMETER,
276                 "unsupported setting for permissions {:?}: {:?}",
277                 protection_id,
278                 protection_setting
279             ));
280         }
281         self.protection_id_settings.insert(protection_id, protection_setting);
282         Ok(())
283     }
284 
get_metadata_as_cbor(&self) -> Result<Value, HwCryptoError>285     fn get_metadata_as_cbor(&self) -> Result<Value, HwCryptoError> {
286         let mut cbor_map = Vec::<(Value, Value)>::new();
287         cbor_map.try_reserve(2)?;
288 
289         // Adding expiration time
290         let expiration_time_value = if let Some(expiration_time) = self.expiration_time {
291             Value::Integer(expiration_time.into())
292         } else {
293             Value::Null
294         };
295         let key = Value::Integer((KeyMetadataCoseLabels::KeyExpirationPeriod as i64).into());
296         cbor_map.push((key, expiration_time_value));
297 
298         // Adding protection IDs
299         let mut protection_id_cbor_map = Vec::<(Value, Value)>::new();
300         protection_id_cbor_map.try_reserve(self.protection_id_settings.len())?;
301         for (protection_id, protection_id_setting) in &self.protection_id_settings {
302             let protection_id_key = ciborium::Value::Integer((*protection_id).into());
303             protection_id_cbor_map.push((
304                 protection_id_key,
305                 protection_id_setting.to_cbor_value().map_err(|_| {
306                     hwcrypto_err!(
307                         BAD_PARAMETER,
308                         "couldn't get cbor representation of protection id setting"
309                     )
310                 })?,
311             ))
312         }
313         let key = Value::Integer((KeyMetadataCoseLabels::ProtectionIdSettings as i64).into());
314         cbor_map.push((key, ciborium::Value::Map(protection_id_cbor_map)));
315         Ok(Value::Map(cbor_map))
316     }
317 
set_metadata_from_cbor(&mut self, metadata_as_cbor: Value) -> Result<(), HwCryptoError>318     fn set_metadata_from_cbor(&mut self, metadata_as_cbor: Value) -> Result<(), HwCryptoError> {
319         let metadata = metadata_as_cbor
320             .into_map()
321             .map_err(|_| hwcrypto_err!(BAD_PARAMETER, "received cbor wasn't a map"))?;
322 
323         let mut protection_id_settings: Option<
324             BTreeMap<ProtectionIdSerializable, ProtectionSetting>,
325         > = None;
326         let mut expiration_time: Option<Option<u64>> = None;
327 
328         for (map_key, map_val) in metadata {
329             let key = map_key
330                 .into_integer()
331                 .map_err(|_| hwcrypto_err!(BAD_PARAMETER, "received map key wasn't an integer"))?;
332             match key.try_into()? {
333                 KeyMetadataCoseLabels::KeyExpirationPeriod => {
334                     expiration_time = if map_val.is_null() {
335                         Some(None)
336                     } else {
337                         let value = map_val
338                             .into_integer()
339                             .map_err(|_| {
340                                 hwcrypto_err!(BAD_PARAMETER, "protection id key wasn't an integer")
341                             })?
342                             .try_into()
343                             .map_err(|_| {
344                                 hwcrypto_err!(BAD_PARAMETER, "couldn't decode expiration time")
345                             })?;
346                         Some(Some(value))
347                     }
348                 }
349                 KeyMetadataCoseLabels::ProtectionIdSettings => {
350                     let mut settings = BTreeMap::new();
351                     for (protection_id, protection_setting) in map_val
352                         .into_map()
353                         .map_err(|_| hwcrypto_err!(BAD_PARAMETER, "received cbor wasn't a map"))?
354                     {
355                         //settings.try_reserve(1).map_err(|_| CoseError::EncodeFailed)?;
356                         let protection_id: ProtectionIdSerializable = protection_id
357                             .into_integer()
358                             .map_err(|_| {
359                                 hwcrypto_err!(BAD_PARAMETER, "protection id key wasn't an integer")
360                             })?
361                             .try_into()
362                             .map_err(|_| {
363                                 hwcrypto_err!(BAD_PARAMETER, "couldn't decode protection ID")
364                             })?;
365                         let protection_setting =
366                             ProtectionSetting::from_cbor_value(protection_setting)?;
367                         if settings.contains_key(&protection_id) {
368                             return Err(hwcrypto_err!(
369                                 BAD_PARAMETER,
370                                 "received duplicated protection ID entry"
371                             ));
372                         }
373                         settings.insert(protection_id, protection_setting);
374                     }
375                     protection_id_settings = Some(settings);
376                 }
377             }
378         }
379         self.expiration_time = expiration_time
380             .ok_or(hwcrypto_err!(BAD_PARAMETER, "didn't find expiration time on metadata"))?;
381         self.protection_id_settings = protection_id_settings.ok_or(hwcrypto_err!(
382             BAD_PARAMETER,
383             "didn't find protection_ id settings on metadata"
384         ))?;
385         Ok(())
386     }
387 }
388 
389 /// Header for a `ClearKey` which contains the key policy along with some data needed to manipulate
390 /// the key.
391 #[derive(Debug)]
392 pub(crate) struct KeyHeader {
393     boot_unique_value: BootUniqueValue,
394     key_policy: KeyHeaderPolicy,
395     key_metadata: Mutex<KeyHeaderMetadata>,
396 }
397 
398 impl KeyHeader {
new(policy: &KeyPolicy) -> Result<Self, HwCryptoError>399     fn new(policy: &KeyPolicy) -> Result<Self, HwCryptoError> {
400         let boot_unique_value = BootUniqueValue::new()?;
401         Self::new_with_boot_value(policy, boot_unique_value)
402     }
403 
new_with_boot_value( policy: &KeyPolicy, boot_unique_value: BootUniqueValue, ) -> Result<Self, HwCryptoError>404     fn new_with_boot_value(
405         policy: &KeyPolicy,
406         boot_unique_value: BootUniqueValue,
407     ) -> Result<Self, HwCryptoError> {
408         let key_policy = KeyHeaderPolicy::new(policy)?;
409         let key_metadata = Mutex::new(KeyHeaderMetadata::new());
410         Ok(Self { boot_unique_value, key_policy, key_metadata })
411     }
412 
get_policy(&self) -> Result<KeyPolicy, HwCryptoError>413     fn get_policy(&self) -> Result<KeyPolicy, HwCryptoError> {
414         self.key_policy.get_policy()
415     }
416 
try_clone(&self) -> Result<Self, HwCryptoError>417     fn try_clone(&self) -> Result<Self, HwCryptoError> {
418         let key_policy = self.key_policy.try_clone()?;
419         let key_metadata = self.key_metadata.lock()?.try_clone()?;
420         Ok(Self {
421             boot_unique_value: self.boot_unique_value.clone(),
422             key_policy,
423             key_metadata: Mutex::new(key_metadata),
424         })
425     }
426 
get_metadata_as_cbor(&self) -> Result<Value, HwCryptoError>427     fn get_metadata_as_cbor(&self) -> Result<Value, HwCryptoError> {
428         self.key_metadata.lock()?.get_metadata_as_cbor()
429     }
430 
set_metadata_from_cbor(&mut self, metadata_as_cbor: Value) -> Result<(), HwCryptoError>431     fn set_metadata_from_cbor(&mut self, metadata_as_cbor: Value) -> Result<(), HwCryptoError> {
432         self.key_metadata.lock()?.set_metadata_from_cbor(metadata_as_cbor)
433     }
434 }
435 
436 cose_enum_gen! {
437     enum OpaqueKeyCoseLabels {
438         KeyMaterial = -66000,
439         KeyPolicy = -66001,
440         BootValue = -66002,
441         KeyMetadata = -66003,
442     }
443 }
444 
445 cose_enum_gen! {
446     enum ProtectionSettingsCoseLabels {
447         WriteProtection = -67000,
448         ReadProtection = -67001,
449     }
450 }
451 
452 cose_enum_gen! {
453     enum KeyMetadataCoseLabels {
454         KeyExpirationPeriod = -68000,
455         ProtectionIdSettings = -68001,
456     }
457 }
458 
459 aidl_enum_wrapper! {
460     aidl_name: ProtectionId,
461     wrapper_name: ProtectionIdSerializable,
462     fields: [WIDEVINE_OUTPUT_BUFFER]
463 }
464 
465 #[derive(Debug, Copy, Clone)]
466 struct ProtectionSetting {
467     write_protection: bool,
468     read_protection: bool,
469 }
470 
471 impl AsCborValue for ProtectionSetting {
to_cbor_value(self) -> Result<Value, CoseError>472     fn to_cbor_value(self) -> Result<Value, CoseError> {
473         let mut cbor_map = Vec::<(Value, Value)>::new();
474         cbor_map.try_reserve(2).map_err(|_| CoseError::EncodeFailed)?;
475 
476         let key = Value::Integer((ProtectionSettingsCoseLabels::WriteProtection as i64).into());
477         let value = Value::Bool(self.write_protection.into());
478         cbor_map.push((key, value));
479 
480         let key = Value::Integer((ProtectionSettingsCoseLabels::ReadProtection as i64).into());
481         let value = Value::Bool(self.read_protection.into());
482         cbor_map.push((key, value));
483 
484         Ok(Value::Map(cbor_map))
485     }
486 
from_cbor_value(value: Value) -> Result<Self, CoseError>487     fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
488         let opaque_key_map = value.into_map().map_err(|_| CoseError::ExtraneousData)?;
489         if opaque_key_map.len() != 2 {
490             return Err(CoseError::ExtraneousData);
491         }
492 
493         let mut write_protection: Option<bool> = None;
494         let mut read_protection: Option<bool> = None;
495         for (map_key, map_val) in opaque_key_map {
496             match map_key {
497                 Value::Integer(key) => match key.try_into()? {
498                     ProtectionSettingsCoseLabels::WriteProtection => {
499                         write_protection = Some(map_val.as_bool().ok_or(CoseError::EncodeFailed)?);
500                     }
501                     ProtectionSettingsCoseLabels::ReadProtection => {
502                         read_protection = Some(map_val.as_bool().ok_or(CoseError::EncodeFailed)?);
503                     }
504                 },
505                 _ => return Err(CoseError::ExtraneousData),
506             }
507         }
508 
509         let write_protection = write_protection.ok_or(CoseError::EncodeFailed)?;
510         let read_protection = read_protection.ok_or(CoseError::EncodeFailed)?;
511 
512         Ok(Self { write_protection, read_protection })
513     }
514 }
515 
get_dice_sealing_key_derivation_context() -> Result<Vec<u8>, HwCryptoError>516 fn get_dice_sealing_key_derivation_context() -> Result<Vec<u8>, HwCryptoError> {
517     let mut context = Vec::<u8>::new();
518 
519     context.try_reserve(SEALING_KEY_DERIVATION_HMAC_256_CTX.len() + UNIQUE_VALUE_SIZEOF)?;
520     context.extend_from_slice(SEALING_KEY_DERIVATION_HMAC_256_CTX);
521     context.extend_from_slice(&get_boot_unique_value()?.0);
522 
523     Ok(context)
524 }
525 
526 /// `IOpaqueKey` implementation.
527 pub struct OpaqueKey {
528     pub(crate) key_header: KeyHeader,
529     pub(crate) key_material: KeyMaterial,
530     pub(crate) key_in_owner_control: bool,
531 }
532 
533 impl From<OpaqueKey> for binder::Strong<dyn IOpaqueKey> {
from(value: OpaqueKey) -> binder::Strong<dyn IOpaqueKey>534     fn from(value: OpaqueKey) -> binder::Strong<dyn IOpaqueKey> {
535         BnOpaqueKey::new_binder(value, binder::BinderFeatures::default())
536     }
537 }
538 
539 impl TryFrom<&binder::Strong<dyn IOpaqueKey>> for OpaqueKey {
540     type Error = HwCryptoError;
541 
try_from(value: &binder::Strong<dyn IOpaqueKey>) -> Result<OpaqueKey, Self::Error>542     fn try_from(value: &binder::Strong<dyn IOpaqueKey>) -> Result<OpaqueKey, Self::Error> {
543         let binder = value.as_binder();
544         let remote = binder.is_remote();
545         if remote {
546             return Err(hwcrypto_err!(UNSUPPORTED, "binder is not local"));
547         }
548         let binder_key: Binder<BnOpaqueKey> =
549             binder.try_into().expect("because binder is local this should not fail");
550         let opaque_key_material = (*binder_key).downcast_binder::<OpaqueKey>();
551         match opaque_key_material {
552             Some(key) => key.try_clone(),
553             None => Err(hwcrypto_err!(UNSUPPORTED, "couldn't cast back key")),
554         }
555     }
556 }
557 
558 impl AsCborValue for OpaqueKey {
to_cbor_value(self) -> Result<Value, CoseError>559     fn to_cbor_value(self) -> Result<Value, CoseError> {
560         let mut cbor_map = Vec::<(Value, Value)>::new();
561         cbor_map.try_reserve(4).map_err(|_| CoseError::EncodeFailed)?;
562         let key = Value::Integer((OpaqueKeyCoseLabels::KeyPolicy as i64).into());
563         let key_policy = self.getKeyPolicy().map_err(|_| CoseError::EncodeFailed)?;
564         let cbor_key_policy =
565             cbor_serialize_key_policy(&key_policy).map_err(|_| CoseError::EncodeFailed)?;
566         cbor_map.push((key, Value::Bytes(cbor_key_policy)));
567 
568         let key = Value::Integer((OpaqueKeyCoseLabels::KeyMaterial as i64).into());
569         cbor_map
570             .push((key, self.key_material.to_cbor_value().map_err(|_| CoseError::EncodeFailed)?));
571 
572         let key = Value::Integer((OpaqueKeyCoseLabels::BootValue as i64).into());
573         let mut boot_value = Vec::new();
574         boot_value
575             .try_reserve(self.key_header.boot_unique_value.0.len())
576             .map_err(|_| CoseError::EncodeFailed)?;
577         boot_value.extend_from_slice(&self.key_header.boot_unique_value.0);
578         cbor_map.push((key, Value::Bytes(boot_value)));
579 
580         let key = Value::Integer((OpaqueKeyCoseLabels::KeyMetadata as i64).into());
581         cbor_map.push((
582             key,
583             self.key_header.get_metadata_as_cbor().map_err(|_| CoseError::EncodeFailed)?,
584         ));
585 
586         Ok(Value::Map(cbor_map))
587     }
588 
from_cbor_value(value: Value) -> Result<Self, CoseError>589     fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
590         let opaque_key_map = value.into_map().map_err(|_| CoseError::ExtraneousData)?;
591         if opaque_key_map.len() != 4 {
592             return Err(CoseError::ExtraneousData);
593         }
594         let mut key_material: Option<KeyMaterial> = None;
595         let mut key_policy: Option<KeyPolicy> = None;
596         let mut boot_value: Option<BootUniqueValue> = None;
597         let mut key_metadata: Option<Value> = None;
598         for (map_key, map_val) in opaque_key_map {
599             match map_key {
600                 Value::Integer(key) => match key.try_into()? {
601                     OpaqueKeyCoseLabels::KeyMaterial => {
602                         key_material = Some(
603                             KeyMaterial::from_cbor_value(map_val)
604                                 .map_err(|_| CoseError::EncodeFailed)?,
605                         )
606                     }
607                     OpaqueKeyCoseLabels::KeyPolicy => {
608                         let policy_bytes = map_val.as_bytes().ok_or(CoseError::EncodeFailed)?;
609                         key_policy = Some(
610                             cbor_policy_to_aidl(policy_bytes.as_slice())
611                                 .map_err(|_| CoseError::EncodeFailed)?,
612                         )
613                     }
614                     OpaqueKeyCoseLabels::BootValue => {
615                         let boot_value_bytes = map_val.as_bytes().ok_or(CoseError::EncodeFailed)?;
616                         boot_value = Some(BootUniqueValue(
617                             (boot_value_bytes.clone())
618                                 .try_into()
619                                 .map_err(|_| CoseError::EncodeFailed)?,
620                         ))
621                     }
622                     OpaqueKeyCoseLabels::KeyMetadata => key_metadata = Some(map_val),
623                 },
624                 _ => return Err(CoseError::ExtraneousData),
625             }
626         }
627         let key_material = key_material.ok_or(CoseError::EncodeFailed)?;
628         let key_policy = key_policy.ok_or(CoseError::EncodeFailed)?;
629         let boot_value = boot_value.ok_or(CoseError::EncodeFailed)?;
630         let mut key_header = KeyHeader::new_with_boot_value(&key_policy, boot_value)
631             .map_err(|_| CoseError::EncodeFailed)?;
632         let key_metadata = key_metadata.ok_or(CoseError::EncodeFailed)?;
633         key_header.set_metadata_from_cbor(key_metadata).map_err(|_| CoseError::EncodeFailed)?;
634         Ok(OpaqueKey { key_material, key_header, key_in_owner_control: false })
635     }
636 }
637 
638 impl OpaqueKey {
new_binder( policy: &KeyPolicy, key_material: KeyMaterial, _connection_info: Uuid, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>639     pub(crate) fn new_binder(
640         policy: &KeyPolicy,
641         key_material: KeyMaterial,
642         _connection_info: Uuid,
643     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
644         let key_header = KeyHeader::new(policy)?;
645         check_key_material_with_policy(&key_material, policy)?;
646         let opaque_key = OpaqueKey { key_header, key_material, key_in_owner_control: true };
647         let opaque_keybinder =
648             BnOpaqueKey::new_binder(opaque_key, binder::BinderFeatures::default());
649         Ok(opaque_keybinder)
650     }
651 
check_clear_import_policy(policy: &KeyPolicy) -> Result<(), HwCryptoError>652     fn check_clear_import_policy(policy: &KeyPolicy) -> Result<(), HwCryptoError> {
653         if policy.keyLifetime != KeyLifetime::PORTABLE {
654             return Err(hwcrypto_err!(
655                 BAD_PARAMETER,
656                 "imported clear keys should have a PORTABLE lifetime"
657             ));
658         }
659         Ok(())
660     }
661 
import_key_material( policy: &KeyPolicy, key_material: KeyMaterial, connection_info: Uuid, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>662     pub(crate) fn import_key_material(
663         policy: &KeyPolicy,
664         key_material: KeyMaterial,
665         connection_info: Uuid,
666     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
667         check_key_material_with_policy(&key_material, policy)?;
668         Self::check_clear_import_policy(policy)?;
669         Self::new_binder(policy, key_material, connection_info)
670     }
671 
check_ownership(&self) -> bool672     fn check_ownership(&self) -> bool {
673         self.key_in_owner_control
674     }
675 
676     // Create a key token sealed using the receiver DICE policy. This means that only the
677     // intended token receiver can import this token. The token has 2 levels of encryption,
678     // the outer layer is provided by a device key bounded to the HwCrypto service and the
679     // outer layer is generated using the receiver DICE policy.
create_token(&self, sealing_dice_policy: &[u8]) -> Result<Vec<u8>, HwCryptoError>680     fn create_token(&self, sealing_dice_policy: &[u8]) -> Result<Vec<u8>, HwCryptoError> {
681         if !self.check_ownership() {
682             // We haven't created this key, so we cannot export it
683             // TODO: Change the error type to UNAUTORIZED
684             return Err(hwcrypto_err!(GENERIC_ERROR, "only the owner of a key can export it"));
685         }
686         let key: OpaqueKey = self.try_clone()?;
687         let token_creator = EncryptionHeader::generate(EncryptedContent::KeyMaterial)?;
688 
689         // This is a temporary workaround to create a DICE bound key because we will move to
690         // using DICE policies and the AuthMgr instead of UUIDs.
691         let hw_device_key = HwCryptoKey {
692             uuid: Uuid::new_from_string("ffffffff-ffff-ffff-ffff-ffffffffffff")
693                 .expect("shouldn't happen, string can be parsed to uuid"),
694         };
695 
696         // Create a DICE key bound to the receiver policy.
697         let DiceBoundKeyResult { diceBoundKey: sealing_dice_key, dicePolicyWasCurrent: _ } =
698             hw_device_key.derive_dice_policy_bound_key(
699                 &DiceBoundDerivationKey::KeyId(DeviceKeyId::DEVICE_BOUND_KEY),
700                 sealing_dice_policy,
701                 false,
702             )?;
703         let sealing_dice_key: OpaqueKey = sealing_dice_key
704             .as_ref()
705             .ok_or(hwcrypto_err!(GENERIC_ERROR, "shouldn't happen, sealing key is local"))?
706             .try_into()?;
707         let context = get_dice_sealing_key_derivation_context()?;
708         let sealing_key = sealing_dice_key
709             .derive_internal_sealing_key(&context, get_key_size_in_bytes(&KeyType::HMAC_SHA256)?)?;
710         // Inner encryption using the DICE policy bound key
711         let inner_content = token_creator.encrypt_content_service_encryption_key(
712             EncryptionHeaderKey::ProvidedHkdfKey(sealing_key),
713             key,
714         )?;
715 
716         // External encryption using the HwCrypto service key
717         let token_creator = EncryptionHeader::generate(EncryptedContent::WrappedKeyMaterial)?;
718         let content = token_creator.encrypt_content_service_encryption_key(
719             EncryptionHeaderKey::KeyGenerationContext(HW_CRYPTO_WRAP_KEY_HMAC_256_CTX),
720             Value::Bytes(inner_content),
721         )?;
722         Ok(content)
723     }
724 
import_token( key_token: &[u8], sealing_dice_key: OpaqueKey, _connection_information: Uuid, ) -> Result<Self, HwCryptoError>725     pub(crate) fn import_token(
726         key_token: &[u8],
727         sealing_dice_key: OpaqueKey,
728         _connection_information: Uuid,
729     ) -> Result<Self, HwCryptoError> {
730         // External encryption layer used a HwCrypto service device key
731         let (_, content) = EncryptionHeader::decrypt_content_service_encryption_key(
732             key_token,
733             EncryptionHeaderKey::KeyGenerationContext(HW_CRYPTO_WRAP_KEY_HMAC_256_CTX),
734             EncryptedContent::WrappedKeyMaterial,
735         )?;
736 
737         let context = get_dice_sealing_key_derivation_context()?;
738         // Preparing internal encryption DICE policy bound key
739         let sealing_key = sealing_dice_key
740             .derive_internal_sealing_key(&context, get_key_size_in_bytes(&KeyType::HMAC_SHA256)?)?;
741 
742         let cbor_bytes = Value::from_slice(content.as_slice())?;
743         let inner_content = cbor_bytes.as_bytes().ok_or(hwcrypto_err!(
744             GENERIC_ERROR,
745             "shouldn't happen, inner content was encrypted by us"
746         ))?;
747 
748         let (_, inner_key) = EncryptionHeader::decrypt_content_service_encryption_key(
749             &inner_content,
750             EncryptionHeaderKey::ProvidedHkdfKey(sealing_key),
751             EncryptedContent::KeyMaterial,
752         )?;
753 
754         let opaque_key = Self::from_cbor_value(Value::from_slice(inner_key.as_slice())?)?;
755         Ok(opaque_key)
756     }
757 
758     #[allow(unused)]
generate_opaque_key( policy: &KeyPolicy, connection_info: Uuid, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>759     pub(crate) fn generate_opaque_key(
760         policy: &KeyPolicy,
761         connection_info: Uuid,
762     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
763         let key_material = generate_key_material(&policy.keyType, None)?;
764         OpaqueKey::new_binder(policy, key_material, connection_info)
765     }
766 
try_clone(&self) -> Result<Self, HwCryptoError>767     fn try_clone(&self) -> Result<Self, HwCryptoError> {
768         let key_header = self.key_header.try_clone()?;
769         let key_material = self.key_material.clone();
770         Ok(OpaqueKey { key_header, key_material, key_in_owner_control: self.key_in_owner_control })
771     }
772 
new_opaque_key_from_raw_bytes( policy: &KeyPolicy, key_material: Vec<u8>, connection_info: Uuid, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>773     pub(crate) fn new_opaque_key_from_raw_bytes(
774         policy: &KeyPolicy,
775         key_material: Vec<u8>,
776         connection_info: Uuid,
777     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
778         let key_material = generate_key_material(&policy.keyType, Some(key_material))?;
779         OpaqueKey::new_binder(policy, key_material, connection_info)
780     }
781 
check_key_derivation_parameters( &self, policy: &KeyPolicy, ) -> Result<(), HwCryptoError>782     pub(crate) fn check_key_derivation_parameters(
783         &self,
784         policy: &KeyPolicy,
785     ) -> Result<(), HwCryptoError> {
786         // Check that we are trying to derive a supported key type
787         check_type_derived_key(policy.keyType)?;
788         // Check that the requested lifetime is compatible with the provided key lifetime
789         if !self.derivation_allowed_lifetime(policy.keyLifetime)? {
790             return Err(hwcrypto_err!(
791                 BAD_PARAMETER,
792                 "requested lifetime cannot be used {:?}",
793                 &policy.keyLifetime
794             ));
795         }
796         // Check that the derivation key can be used to derive keys (KeyPermissions/KeyPolicies)
797         self.key_can_be_used_for_derivation()
798     }
799 
800     // All key derivation functions that uses an `OpaqueKey` as key material should use this
801     // function. If the key derivation do not fit one of the current use cases defined in
802     // `HkdfOperationType`, a new enum value should be added to `HkdfOperationType` for the use
803     // case.
derive_raw_key_material( &self, context: DerivationContext, derived_key_size: usize, ) -> Result<Vec<u8>, HwCryptoError>804     fn derive_raw_key_material(
805         &self,
806         context: DerivationContext,
807         derived_key_size: usize,
808     ) -> Result<Vec<u8>, HwCryptoError> {
809         let context_with_op_type = context.create_key_derivation_context()?;
810         match &self.key_material {
811             KeyMaterial::Hmac(key) => {
812                 let hkdf = crypto_provider::HmacImpl;
813                 let explicit_key = explicit!(key).map_err(|_| {
814                     hwcrypto_err!(BAD_PARAMETER, "only explicit HMAC keys supported")
815                 })?;
816                 let raw_key = hkdf
817                     .hkdf(&[], &explicit_key.0, context_with_op_type.as_slice(), derived_key_size)
818                     .map_err(|e| hwcrypto_err!(GENERIC_ERROR, "couldn't derive key {:?}", e))?;
819                 Ok(raw_key)
820             }
821             _ => Err(hwcrypto_err!(BAD_PARAMETER, "only HMAC keys supported")),
822         }
823     }
824 
derive_clear_key_from_derivation_context( &self, mut op_context: DerivationContext, context: &[u8], derived_key_size: usize, ) -> Result<Vec<u8>, HwCryptoError>825     fn derive_clear_key_from_derivation_context(
826         &self,
827         mut op_context: DerivationContext,
828         context: &[u8],
829         derived_key_size: usize,
830     ) -> Result<Vec<u8>, HwCryptoError> {
831         op_context.add_unsigned_integer(derived_key_size as u64)?;
832         op_context.add_binary_string(context)?;
833         self.derive_raw_key_material(op_context, derived_key_size)
834     }
835 
derive_internal_sealing_key( &self, context: &[u8], derived_key_size: usize, ) -> Result<Vec<u8>, HwCryptoError>836     pub(crate) fn derive_internal_sealing_key(
837         &self,
838         context: &[u8],
839         derived_key_size: usize,
840     ) -> Result<Vec<u8>, HwCryptoError> {
841         let op_context = DerivationContext::new(HkdfOperationType::InternalSealingKeyDerivation)?;
842         self.derive_clear_key_from_derivation_context(op_context, context, derived_key_size)
843     }
844 
derive_clear_key_material( &self, context: &[u8], derived_key_size: usize, ) -> Result<Vec<u8>, HwCryptoError>845     pub(crate) fn derive_clear_key_material(
846         &self,
847         context: &[u8],
848         derived_key_size: usize,
849     ) -> Result<Vec<u8>, HwCryptoError> {
850         let op_context = DerivationContext::new(HkdfOperationType::ClearKeyDerivation)?;
851         self.derive_clear_key_from_derivation_context(op_context, context, derived_key_size)
852     }
853 
derive_opaque_key( &self, policy: &[u8], context: &[u8], connection_info: Uuid, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>854     pub(crate) fn derive_opaque_key(
855         &self,
856         policy: &[u8],
857         context: &[u8],
858         connection_info: Uuid,
859     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
860         let aidl_policy = policy::cbor_policy_to_aidl(policy)?;
861         self.check_key_derivation_parameters(&aidl_policy)?;
862         let derived_key_size = get_key_size_in_bytes(&aidl_policy.keyType)?;
863         let mut op_context = DerivationContext::new(HkdfOperationType::OpaqueKeyDerivation)?;
864         op_context.add_binary_string(policy)?;
865         op_context.add_binary_string(context)?;
866         let raw_key_material = self.derive_raw_key_material(op_context, derived_key_size)?;
867         Self::new_opaque_key_from_raw_bytes(&aidl_policy, raw_key_material, connection_info)
868     }
869 
derivation_allowed_lifetime( &self, derived_key_lifetime: KeyLifetime, ) -> Result<bool, HwCryptoError>870     fn derivation_allowed_lifetime(
871         &self,
872         derived_key_lifetime: KeyLifetime,
873     ) -> Result<bool, HwCryptoError> {
874         validate_lifetime(self.key_header.key_policy.key_lifetime.0)?;
875         validate_lifetime(derived_key_lifetime)?;
876         match self.key_header.key_policy.key_lifetime.0 {
877             //ephemeral keys can be used to derive/wrap any other key
878             KeyLifetime::EPHEMERAL => Ok(true),
879             KeyLifetime::HARDWARE => {
880                 // Hardware keys cannot be used to derive/wrap ephemeral keys
881                 if derived_key_lifetime.0 == KeyLifetime::EPHEMERAL.0 {
882                     Ok(false)
883                 } else {
884                     Ok(true)
885                 }
886             }
887             KeyLifetime::PORTABLE => {
888                 // portable keys can only derive/wrap other portable keys
889                 if derived_key_lifetime.0 == KeyLifetime::PORTABLE.0 {
890                     Ok(true)
891                 } else {
892                     Ok(false)
893                 }
894             }
895             _ => Err(hwcrypto_err!(
896                 UNSUPPORTED,
897                 "unsupported Key lifetime {:?}",
898                 self.key_header.key_policy.key_lifetime
899             )),
900         }
901     }
902 
key_can_be_used_for_derivation(&self) -> Result<(), HwCryptoError>903     fn key_can_be_used_for_derivation(&self) -> Result<(), HwCryptoError> {
904         match self.key_material {
905             KeyMaterial::Hmac(_) => Ok(()),
906             _ => Err(hwcrypto_err!(UNSUPPORTED, "Only HMAC keys can be used for key derivation")),
907         }?;
908         if self.key_header.key_policy.key_usage.0 != KeyUse::DERIVE {
909             return Err(hwcrypto_err!(BAD_PARAMETER, "key was not exclusively a derive key"));
910         }
911         Ok(())
912     }
913 
key_usage_supported(&self, usage: KeyUse) -> bool914     pub(crate) fn key_usage_supported(&self, usage: KeyUse) -> bool {
915         (usage.0 & self.key_header.key_policy.key_usage.0 .0) == usage.0
916     }
917 
get_key_type(&self) -> KeyType918     pub fn get_key_type(&self) -> KeyType {
919         self.key_header.key_policy.key_type.0
920     }
921 
supports_pattern_encryption(&self) -> Result<(), HwCryptoError>922     pub fn supports_pattern_encryption(&self) -> Result<(), HwCryptoError> {
923         match self.key_header.key_policy.key_type.0 {
924             KeyType::AES_128_CBC_NO_PADDING => Ok(()),
925             _ => Err(hwcrypto_err!(BAD_PARAMETER, "only AES CBC supports pattern encryption")),
926         }
927     }
928 
929     /// Checks if the requested operation (encrypt/decrypt) can be done with this key
symmetric_operation_is_compatible( &self, direction: SymmetricOperation, ) -> Result<(), HwCryptoError>930     pub(crate) fn symmetric_operation_is_compatible(
931         &self,
932         direction: SymmetricOperation,
933     ) -> Result<(), HwCryptoError> {
934         let dir = helpers::direction_to_key_usage(&direction)?;
935         if !self.key_usage_supported(dir) {
936             Err(hwcrypto_err!(BAD_PARAMETER, "provided key do not support {:?}", dir))
937         } else {
938             Ok(())
939         }
940     }
941 
942     /// Checks if the requested algorithm parameters are compatible with this key
parameters_are_compatible_symmetric_cipher( &self, parameters: &SymmetricCryptoParameters, ) -> Result<(), HwCryptoError>943     pub(crate) fn parameters_are_compatible_symmetric_cipher(
944         &self,
945         parameters: &SymmetricCryptoParameters,
946     ) -> Result<(), HwCryptoError> {
947         match parameters {
948             SymmetricCryptoParameters::Aes(aes_parameters) => match aes_parameters {
949                 AesCipherMode::Cbc(_) => match self.get_key_type() {
950                     KeyType::AES_128_CBC_NO_PADDING
951                     | KeyType::AES_128_CBC_PKCS7_PADDING
952                     | KeyType::AES_256_CBC_NO_PADDING
953                     | KeyType::AES_256_CBC_PKCS7_PADDING => Ok(()),
954                     _ => Err(hwcrypto_err!(BAD_PARAMETER, "provided incompatible AES key for CBC")),
955                 },
956                 AesCipherMode::Ctr(_) => match self.get_key_type() {
957                     KeyType::AES_128_CTR | KeyType::AES_256_CTR => Ok(()),
958                     _ => Err(hwcrypto_err!(BAD_PARAMETER, "provided incompatible AES key for CTR")),
959                 },
960             },
961         }
962     }
963 
add_protection_id( &self, protection_id: ProtectionId, allowed_operations: &[OperationType], ) -> Result<(), HwCryptoError>964     fn add_protection_id(
965         &self,
966         protection_id: ProtectionId,
967         allowed_operations: &[OperationType],
968     ) -> Result<(), HwCryptoError> {
969         if !self.check_ownership() {
970             // We haven't created this key, so we cannot export it
971             // TODO: Change the error type to UNAUTORIZED
972             return Err(hwcrypto_err!(
973                 GENERIC_ERROR,
974                 "only the owner of a key can modify protection IDs"
975             ));
976         }
977         self.key_header.key_metadata.lock()?.add_protection_id(protection_id, allowed_operations)
978     }
979 }
980 
981 impl binder::Interface for OpaqueKey {}
982 
983 impl IOpaqueKey for OpaqueKey {
exportWrappedKey( &self, _wrapping_key: &binder::Strong<dyn IOpaqueKey>, ) -> binder::Result<Vec<u8>>984     fn exportWrappedKey(
985         &self,
986         _wrapping_key: &binder::Strong<dyn IOpaqueKey>,
987     ) -> binder::Result<Vec<u8>> {
988         Err(binder::Status::new_exception_str(
989             binder::ExceptionCode::UNSUPPORTED_OPERATION,
990             Some("export_wrapped_key has not been implemented yet"),
991         ))
992     }
993 
getKeyPolicy(&self) -> binder::Result<KeyPolicy>994     fn getKeyPolicy(&self) -> binder::Result<KeyPolicy> {
995         Ok(self.key_header.get_policy()?)
996     }
997 
getPublicKey(&self) -> binder::Result<Vec<u8>>998     fn getPublicKey(&self) -> binder::Result<Vec<u8>> {
999         Err(binder::Status::new_exception_str(
1000             binder::ExceptionCode::UNSUPPORTED_OPERATION,
1001             Some("get_public_key has not been implemented yet"),
1002         ))
1003     }
1004 
getShareableToken(&self, sealing_dice_policy: &[u8]) -> binder::Result<OpaqueKeyToken>1005     fn getShareableToken(&self, sealing_dice_policy: &[u8]) -> binder::Result<OpaqueKeyToken> {
1006         Ok(OpaqueKeyToken { keyToken: self.create_token(sealing_dice_policy)? })
1007     }
1008 
setProtectionId( &self, protection_id: ProtectionId, allowed_operations: &[OperationType], ) -> Result<(), binder::Status>1009     fn setProtectionId(
1010         &self,
1011         protection_id: ProtectionId,
1012         allowed_operations: &[OperationType],
1013     ) -> Result<(), binder::Status> {
1014         Ok(self.add_protection_id(protection_id, allowed_operations)?)
1015     }
1016 }
1017 
check_key_material_with_policy( key_material: &KeyMaterial, policy: &KeyPolicy, ) -> Result<(), HwCryptoError>1018 pub(crate) fn check_key_material_with_policy(
1019     key_material: &KeyMaterial,
1020     policy: &KeyPolicy,
1021 ) -> Result<(), HwCryptoError> {
1022     let key_type = &policy.keyType;
1023     // `KeyMaterial` doesn't fully describe the cryptographic algorithm as `KeyType` does, so we can
1024     //  only check if both of them are compatible, not provide a 1:1 mapping
1025     match key_material {
1026         KeyMaterial::Aes(aes_key) => match aes_key {
1027             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque aes key provided")),
1028             OpaqueOr::Explicit(aes_key) => match aes_key {
1029                 crypto::aes::Key::Aes128(km) => match *key_type {
1030                     KeyType::AES_128_CBC_NO_PADDING
1031                     | KeyType::AES_128_CBC_PKCS7_PADDING
1032                     | KeyType::AES_128_CTR
1033                     | KeyType::AES_128_GCM
1034                     | KeyType::AES_128_CMAC => Ok(()),
1035                     _ => Err(hwcrypto_err!(
1036                         BAD_PARAMETER,
1037                         "type mismatch: key material {:?} key type: {:?}",
1038                         km,
1039                         key_type
1040                     )),
1041                 },
1042                 crypto::aes::Key::Aes192(_) => {
1043                     Err(hwcrypto_err!(BAD_PARAMETER, "AES keys of length 192 are not supported"))
1044                 }
1045                 crypto::aes::Key::Aes256(km) => match *key_type {
1046                     KeyType::AES_256_CBC_NO_PADDING
1047                     | KeyType::AES_256_CBC_PKCS7_PADDING
1048                     | KeyType::AES_256_CTR
1049                     | KeyType::AES_256_GCM
1050                     | KeyType::AES_256_CMAC => Ok(()),
1051                     _ => Err(hwcrypto_err!(
1052                         BAD_PARAMETER,
1053                         "type mismatch: key material {:?} key type: {:?}",
1054                         km,
1055                         key_type
1056                     )),
1057                 },
1058             },
1059         },
1060         KeyMaterial::TripleDes(_) => {
1061             Err(hwcrypto_err!(BAD_PARAMETER, "TDES is not currently supported"))
1062         }
1063         KeyMaterial::Hmac(hmac_key) => match hmac_key {
1064             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque HMAC key provided")),
1065             OpaqueOr::Explicit(km) => match *key_type {
1066                 KeyType::HMAC_SHA256 | KeyType::HMAC_SHA512 => {
1067                     let expected_size = get_key_size_in_bytes(key_type)?;
1068                     let km_size = km.0.len();
1069                     match policy.usage {
1070                         KeyUse::SIGN | KeyUse::DERIVE => Ok(()),
1071                         _ => Err(hwcrypto_err!(
1072                             BAD_PARAMETER,
1073                             "wrong key use for hmac key, received {:?}",
1074                             policy.usage
1075                         )),
1076                     }?;
1077                     if km_size == expected_size {
1078                         Ok(())
1079                     } else {
1080                         Err(hwcrypto_err!(
1081                             BAD_PARAMETER,
1082                             "bad len for hmac key received {} bytes, expected {} bytes",
1083                             km_size,
1084                             expected_size
1085                         ))
1086                     }
1087                 }
1088                 _ => Err(hwcrypto_err!(
1089                     BAD_PARAMETER,
1090                     "type mismatch for HMAC key key type: {:?}",
1091                     key_type
1092                 )),
1093             },
1094         },
1095         KeyMaterial::Rsa(rsa_key) => match rsa_key {
1096             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque RSA key provided")),
1097             OpaqueOr::Explicit(rsa_key) => {
1098                 let key_size = rsa_key.size();
1099                 match (key_size, *key_type) {
1100                     (2048, KeyType::RSA2048_PSS_SHA256) => Ok(()),
1101                     (2048, KeyType::RSA2048_PKCS1_5_SHA256) => Ok(()),
1102                     _ => Err(hwcrypto_err!(
1103                         BAD_PARAMETER,
1104                         "type mismatch for RSA key length {} and type: {:?}",
1105                         key_size,
1106                         key_type
1107                     )),
1108                 }
1109             }
1110         },
1111         KeyMaterial::Ec(curve, curve_type, _) => match (curve, *key_type) {
1112             (EcCurve::P256, KeyType::ECC_NIST_P256_SIGN_NO_PADDING) => Ok(()),
1113             (EcCurve::P256, KeyType::ECC_NIST_P256_SIGN_SHA256) => Ok(()),
1114             (EcCurve::P521, KeyType::ECC_NIST_P521_SIGN_NO_PADDING) => Ok(()),
1115             (EcCurve::P521, KeyType::ECC_NIST_P521_SIGN_SHA512) => Ok(()),
1116             (EcCurve::Curve25519, _) => match (curve_type, *key_type) {
1117                 (CurveType::EdDsa, KeyType::ECC_ED25519_SIGN) => Ok(()),
1118                 _ => Err(hwcrypto_err!(
1119                     BAD_PARAMETER,
1120                     "type mismatch for Ec Key curve {:?} and type: {:?}",
1121                     curve,
1122                     key_type
1123                 )),
1124             },
1125             _ => Err(hwcrypto_err!(
1126                 BAD_PARAMETER,
1127                 "type mismatch for Ec Key curve {:?} and type: {:?}",
1128                 curve,
1129                 key_type
1130             )),
1131         },
1132     }
1133 }
1134 
1135 // Get key size given the backend AES key type. Used to check if we received enough bytes from the
1136 // caller for an AES key.
get_aes_variant_key_size(variant: &crypto::aes::Variant) -> usize1137 fn get_aes_variant_key_size(variant: &crypto::aes::Variant) -> usize {
1138     match variant {
1139         crypto::aes::Variant::Aes128 => 16,
1140         crypto::aes::Variant::Aes192 => 24,
1141         crypto::aes::Variant::Aes256 => 32,
1142     }
1143 }
1144 
1145 // Translating a policy AES `KeyType` into the type understood by the cryptographic backend we are
1146 // currently used
1147 // TODO: change this into a `TryFrom` once we refactor `KeyType` to be a newtype.
get_aes_variant(key_type: &KeyType) -> Result<crypto::aes::Variant, HwCryptoError>1148 fn get_aes_variant(key_type: &KeyType) -> Result<crypto::aes::Variant, HwCryptoError> {
1149     match *key_type {
1150         KeyType::AES_128_CBC_NO_PADDING
1151         | KeyType::AES_128_CBC_PKCS7_PADDING
1152         | KeyType::AES_128_CTR
1153         | KeyType::AES_128_GCM
1154         | KeyType::AES_128_CMAC => Ok(crypto::aes::Variant::Aes128),
1155         KeyType::AES_256_CBC_NO_PADDING
1156         | KeyType::AES_256_CBC_PKCS7_PADDING
1157         | KeyType::AES_256_CTR
1158         | KeyType::AES_256_GCM
1159         | KeyType::AES_256_CMAC => Ok(crypto::aes::Variant::Aes256),
1160         _ => Err(hwcrypto_err!(BAD_PARAMETER, "not an AES key type: {:?}", key_type)),
1161     }
1162 }
1163 
1164 // Return a keysize given a `KeyType`. Because HMAC key sizes can be defined by the
1165 // caller, `key_size_bits` is needed to cover all cases.
get_key_size_in_bytes(key_type: &KeyType) -> Result<usize, HwCryptoError>1166 pub(crate) fn get_key_size_in_bytes(key_type: &KeyType) -> Result<usize, HwCryptoError> {
1167     match *key_type {
1168         KeyType::AES_128_CBC_NO_PADDING
1169         | KeyType::AES_128_CBC_PKCS7_PADDING
1170         | KeyType::AES_128_CTR
1171         | KeyType::AES_128_GCM
1172         | KeyType::AES_128_CMAC => Ok(16),
1173         KeyType::AES_256_CBC_NO_PADDING
1174         | KeyType::AES_256_CBC_PKCS7_PADDING
1175         | KeyType::AES_256_CTR
1176         | KeyType::AES_256_GCM
1177         | KeyType::AES_256_CMAC => Ok(32),
1178         KeyType::HMAC_SHA256 => Ok(32),
1179         KeyType::HMAC_SHA512 => Ok(64),
1180         _ => unimplemented!("Only AES and HMAC has been implemented"),
1181     }
1182 }
1183 
validate_lifetime(lifetime: KeyLifetime) -> Result<(), HwCryptoError>1184 fn validate_lifetime(lifetime: KeyLifetime) -> Result<(), HwCryptoError> {
1185     match lifetime {
1186         KeyLifetime::EPHEMERAL | KeyLifetime::HARDWARE | KeyLifetime::PORTABLE => Ok(()),
1187         // AIDL structure have more values added than the ones defined on the AIDL file
1188         _ => Err(hwcrypto_err!(UNSUPPORTED, "unsupported Key lifetime {:?}", lifetime)),
1189     }
1190 }
1191 
check_type_derived_key(key_type: KeyType) -> Result<(), HwCryptoError>1192 fn check_type_derived_key(key_type: KeyType) -> Result<(), HwCryptoError> {
1193     match key_type {
1194         KeyType::AES_128_CBC_NO_PADDING
1195         | KeyType::AES_128_CBC_PKCS7_PADDING
1196         | KeyType::AES_128_CTR
1197         | KeyType::AES_128_GCM
1198         | KeyType::AES_128_CMAC
1199         | KeyType::AES_256_CBC_NO_PADDING
1200         | KeyType::AES_256_CBC_PKCS7_PADDING
1201         | KeyType::AES_256_CTR
1202         | KeyType::AES_256_GCM
1203         | KeyType::AES_256_CMAC
1204         | KeyType::HMAC_SHA256
1205         | KeyType::HMAC_SHA512 => Ok(()),
1206         _ => Err(hwcrypto_err!(BAD_PARAMETER, "Only HMAC and AES keys are supported")),
1207     }
1208 }
1209 
key_vec_to_array<T, U: std::convert::TryInto<T>>(input: U) -> Result<T, HwCryptoError>1210 fn key_vec_to_array<T, U: std::convert::TryInto<T>>(input: U) -> Result<T, HwCryptoError> {
1211     input
1212         .try_into()
1213         .map_err(|_| hwcrypto_err!(BAD_PARAMETER, "couldn't transform vector into array"))
1214 }
1215 
1216 // Create a backend-compatible cryptographic key from either a provided vector of uniform random
1217 // bytes or, if this not provided, use the cryptographic backend to create it. The type is based on
1218 // the policy `KeyType`. Because HMAC keys can have arbitrary sizes, include an optional
1219 // `key_size_bits` for that case.
generate_key_material( key_type: &KeyType, key_random_bytes: Option<Vec<u8>>, ) -> Result<KeyMaterial, HwCryptoError>1220 pub(crate) fn generate_key_material(
1221     key_type: &KeyType,
1222     key_random_bytes: Option<Vec<u8>>,
1223 ) -> Result<KeyMaterial, HwCryptoError> {
1224     let aes = crypto_provider::AesImpl;
1225     let hmac = crypto_provider::HmacImpl;
1226     let mut rng = crypto_provider::RngImpl::default();
1227     match *key_type {
1228         KeyType::AES_128_CBC_NO_PADDING
1229         | KeyType::AES_128_CBC_PKCS7_PADDING
1230         | KeyType::AES_128_CTR
1231         | KeyType::AES_128_GCM
1232         | KeyType::AES_128_CMAC
1233         | KeyType::AES_256_CBC_NO_PADDING
1234         | KeyType::AES_256_CBC_PKCS7_PADDING
1235         | KeyType::AES_256_CTR
1236         | KeyType::AES_256_GCM
1237         | KeyType::AES_256_CMAC => {
1238             let variant = get_aes_variant(key_type)?;
1239             if let Some(key_bytes) = key_random_bytes {
1240                 if key_bytes.len() != get_aes_variant_key_size(&variant) {
1241                     return Err(hwcrypto_err!(
1242                         BAD_PARAMETER,
1243                         "for aes key needed {} bytes, received {}",
1244                         key_bytes.len(),
1245                         get_aes_variant_key_size(&variant)
1246                     ));
1247                 }
1248                 match variant {
1249                     crypto::aes::Variant::Aes128 => Ok(KeyMaterial::Aes(
1250                         crypto::aes::Key::Aes128(key_vec_to_array(key_bytes)?).into(),
1251                     )),
1252                     crypto::aes::Variant::Aes192 => Err(hwcrypto_err!(
1253                         BAD_PARAMETER,
1254                         "AES keys of length 192 are not supported",
1255                     )),
1256                     crypto::aes::Variant::Aes256 => Ok(KeyMaterial::Aes(
1257                         crypto::aes::Key::Aes256(key_vec_to_array(key_bytes)?).into(),
1258                     )),
1259                 }
1260             } else {
1261                 Ok(aes.generate_key(&mut rng, variant, &[])?)
1262             }
1263         }
1264         KeyType::HMAC_SHA256 | KeyType::HMAC_SHA512 => {
1265             let key_size_bytes = get_key_size_in_bytes(key_type)?;
1266             if let Some(key_bytes) = key_random_bytes {
1267                 if key_bytes.len() != key_size_bytes {
1268                     Err(hwcrypto_err!(
1269                         BAD_PARAMETER,
1270                         "for hmac key needed {} bytes, received {}",
1271                         key_bytes.len(),
1272                         key_size_bytes
1273                     ))
1274                 } else {
1275                     Ok(KeyMaterial::Hmac(crypto::hmac::Key::new(key_bytes).into()))
1276                 }
1277             } else {
1278                 Ok(hmac.generate_key(
1279                     &mut rng,
1280                     kmr_wire::KeySizeInBits((key_size_bytes * 8).try_into().map_err(|_| {
1281                         hwcrypto_err!(
1282                             GENERIC_ERROR,
1283                             "shouldn't happen, key_size_bytes * 8 should fit on an u32"
1284                         )
1285                     })?),
1286                     &[],
1287                 )?)
1288             }
1289         }
1290         _ => unimplemented!("key material other than AES and HMAC not implemented yet"),
1291     }
1292 }
1293 
1294 #[cfg(test)]
1295 mod tests {
1296     use super::*;
1297     use test::{expect, expect_eq};
1298 
1299     #[test]
boot_unique_values_match()1300     fn boot_unique_values_match() {
1301         let boot_value = BootUniqueValue::new().expect("couldn't get boot unique value");
1302         let boot_value2 = BootUniqueValue::new().expect("couldn't get boot unique value");
1303         expect_eq!(boot_value, boot_value2, "boot unique values should match");
1304     }
1305 
1306     #[test]
generate_key_material_test()1307     fn generate_key_material_test() {
1308         let usage = KeyUse::ENCRYPT;
1309         let key_type = KeyType::AES_256_GCM;
1310         let policy = KeyPolicy {
1311             usage,
1312             keyLifetime: KeyLifetime::EPHEMERAL,
1313             keyPermissions: Vec::new(),
1314             keyType: key_type,
1315             keyManagementKey: false,
1316         };
1317         let key_material = generate_key_material(&policy.keyType, None);
1318         expect!(key_material.is_ok(), "couldn't retrieve key material");
1319         let key_material = key_material.unwrap();
1320         let check_result = check_key_material_with_policy(&key_material, &policy);
1321         expect!(check_result.is_ok(), "wrong key type");
1322     }
1323 }
1324