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