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 android_hardware_security_see::aidl::android::hardware::security::see::hwcrypto::types::{
20     KeyLifetime::KeyLifetime, KeyPermissions::KeyPermissions, KeyType::KeyType, KeyUse::KeyUse,
21 };
22 use android_hardware_security_see::aidl::android::hardware::security::see::hwcrypto::{
23     IOpaqueKey::{BnOpaqueKey, IOpaqueKey},
24     KeyPolicy::KeyPolicy,
25 };
26 use android_hardware_security_see::binder;
27 use binder::binder_impl::Binder;
28 use core::fmt;
29 use hwcryptohal_common::{err::HwCryptoError, hwcrypto_err};
30 use kmr_common::{
31     crypto::{self, Aes, CurveType, Hkdf, Hmac, KeyMaterial, OpaqueOr, Rng},
32     explicit, FallibleAllocExt,
33 };
34 use kmr_wire::keymint::EcCurve;
35 use std::sync::OnceLock;
36 
37 use crate::crypto_provider;
38 
39 /// Number of bytes of unique value used to check if a key was created on current HWCrypto boot.
40 const UNIQUE_VALUE_SIZEOF: usize = 32;
41 
42 /// Struct to wrap boot unique counter. It is used to tag objects to the current boot.
43 #[derive(Clone)]
44 struct BootUniqueValue([u8; UNIQUE_VALUE_SIZEOF]);
45 
46 impl fmt::Debug for BootUniqueValue {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result47     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48         write!(f, "[BootUniqueValue size: {}; data redacted]", UNIQUE_VALUE_SIZEOF)
49     }
50 }
51 
52 impl PartialEq for BootUniqueValue {
eq(&self, other: &Self) -> bool53     fn eq(&self, other: &Self) -> bool {
54         openssl::memcmp::eq(&self.0, &other.0)
55     }
56 }
57 
58 impl Eq for BootUniqueValue {}
59 
60 impl BootUniqueValue {
new() -> Result<BootUniqueValue, HwCryptoError>61     fn new() -> Result<BootUniqueValue, HwCryptoError> {
62         get_boot_unique_value()
63     }
64 }
65 
66 // Boot unique value is lazily initialized on the first call to retrieve it
67 static BOOT_UNIQUE_VALUE: OnceLock<BootUniqueValue> = OnceLock::new();
68 
69 /// Retrieves boot unique value used to check if the key material was created on this boot. It
70 /// lazily initializes it.
get_boot_unique_value() -> Result<BootUniqueValue, HwCryptoError>71 fn get_boot_unique_value() -> Result<BootUniqueValue, HwCryptoError> {
72     // The function returns a `Result` even if it is currently infallible to allow replacing its
73     // current implementation with one that can fail when trying to retrieve a random number.
74     // If the RNG changes to a fallible one we could use `get_or_try_init`.
75     let boot_unique_value = BOOT_UNIQUE_VALUE.get_or_init(|| {
76         let mut rng = crypto_provider::RngImpl::default();
77         let mut new_boot_unique_value = BootUniqueValue([0u8; UNIQUE_VALUE_SIZEOF]);
78         rng.fill_bytes(&mut new_boot_unique_value.0[..]);
79         new_boot_unique_value
80     });
81     Ok(boot_unique_value.clone())
82 }
83 
84 /// Header for a `ClearKey` which contains the key policy along with some data needed to manipulate
85 /// the key.
86 #[derive(Debug)]
87 #[allow(dead_code)]
88 pub(crate) struct KeyHeader {
89     boot_unique_value: BootUniqueValue,
90     expiration_time: Option<u64>,
91     key_lifetime: KeyLifetime,
92     key_permissions: Vec<KeyPermissions>,
93     key_usage: KeyUse,
94     key_type: KeyType,
95     management_key: bool,
96 }
97 
98 impl KeyHeader {
new(policy: &KeyPolicy) -> Result<Self, HwCryptoError>99     fn new(policy: &KeyPolicy) -> Result<Self, HwCryptoError> {
100         let mut key_permissions = Vec::new();
101         key_permissions.try_extend_from_slice(&policy.keyPermissions[..])?;
102         Ok(Self {
103             boot_unique_value: BootUniqueValue::new()?,
104             expiration_time: None,
105             key_lifetime: policy.keyLifetime,
106             key_permissions,
107             key_usage: policy.usage,
108             key_type: policy.keyType,
109             management_key: policy.keyManagementKey,
110         })
111     }
112 
get_policy(&self) -> Result<KeyPolicy, HwCryptoError>113     fn get_policy(&self) -> Result<KeyPolicy, HwCryptoError> {
114         let mut key_permissions = Vec::new();
115         key_permissions.try_extend_from_slice(&self.key_permissions[..])?;
116         Ok(KeyPolicy {
117             usage: self.key_usage,
118             keyLifetime: self.key_lifetime,
119             keyPermissions: key_permissions,
120             keyType: self.key_type,
121             keyManagementKey: self.management_key,
122         })
123     }
124 
try_clone(&self) -> Result<Self, HwCryptoError>125     fn try_clone(&self) -> Result<Self, HwCryptoError> {
126         let mut key_permissions = Vec::new();
127         key_permissions.try_extend_from_slice(&self.key_permissions[..])?;
128         Ok(Self {
129             boot_unique_value: self.boot_unique_value.clone(),
130             expiration_time: self.expiration_time,
131             key_lifetime: self.key_lifetime,
132             key_permissions,
133             key_usage: self.key_usage,
134             key_type: self.key_type,
135             management_key: self.management_key,
136         })
137     }
138 }
139 
140 /// `IOpaqueKey` implementation.
141 #[allow(dead_code)]
142 pub struct OpaqueKey {
143     pub(crate) key_header: KeyHeader,
144     pub(crate) key_material: KeyMaterial,
145 }
146 
147 impl TryFrom<&binder::Strong<dyn IOpaqueKey>> for OpaqueKey {
148     type Error = HwCryptoError;
149 
try_from(value: &binder::Strong<dyn IOpaqueKey>) -> Result<OpaqueKey, Self::Error>150     fn try_from(value: &binder::Strong<dyn IOpaqueKey>) -> Result<OpaqueKey, Self::Error> {
151         let binder = value.as_binder();
152         let remote = binder.is_remote();
153         if remote {
154             return Err(hwcrypto_err!(UNSUPPORTED, "binder is not local"));
155         }
156         let binder_key: Binder<BnOpaqueKey> =
157             binder.try_into().expect("because binder is local this should not fail");
158         let opaque_key_material = (*binder_key).downcast_binder::<OpaqueKey>();
159         match opaque_key_material {
160             Some(key) => key.try_clone(),
161             None => Err(hwcrypto_err!(UNSUPPORTED, "couldn't cast back key")),
162         }
163     }
164 }
165 
166 impl OpaqueKey {
new_binder( policy: &KeyPolicy, key_material: KeyMaterial, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>167     pub(crate) fn new_binder(
168         policy: &KeyPolicy,
169         key_material: KeyMaterial,
170     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
171         let key_header = KeyHeader::new(policy)?;
172         check_key_material_with_policy(&key_material, policy)?;
173         let opaque_key = OpaqueKey { key_header, key_material };
174         let opaque_keybinder =
175             BnOpaqueKey::new_binder(opaque_key, binder::BinderFeatures::default());
176         Ok(opaque_keybinder)
177     }
178 
try_clone(&self) -> Result<Self, HwCryptoError>179     fn try_clone(&self) -> Result<Self, HwCryptoError> {
180         let key_header = self.key_header.try_clone()?;
181         let key_material = self.key_material.clone();
182         Ok(OpaqueKey { key_header, key_material })
183     }
184 
new_opaque_key_from_raw_bytes( policy: &KeyPolicy, key_material: Vec<u8>, ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>185     fn new_opaque_key_from_raw_bytes(
186         policy: &KeyPolicy,
187         key_material: Vec<u8>,
188     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
189         let key_material = generate_key_material(&policy.keyType, Some(key_material))?;
190         OpaqueKey::new_binder(policy, key_material)
191     }
192 
check_key_derivation_parameters( &self, policy: &KeyPolicy, ) -> Result<(), HwCryptoError>193     pub(crate) fn check_key_derivation_parameters(
194         &self,
195         policy: &KeyPolicy,
196     ) -> Result<(), HwCryptoError> {
197         // Check that we are trying to derive a supported key type
198         check_type_derived_key(policy.keyType)?;
199         // Check that the requested lifetime is compatible with the provided key lifetime
200         if !self.derivation_allowed_lifetime(policy.keyLifetime)? {
201             return Err(hwcrypto_err!(
202                 BAD_PARAMETER,
203                 "requested lifetime cannot be used {:?}",
204                 &policy.keyLifetime
205             ));
206         }
207         // Check that the derivation key can be used to derive keys (KeyPermissions/KeyPolicies)
208         self.key_can_be_used_for_derivation()
209     }
210 
derive_raw_key_material( &self, context: &[u8], derived_key_size: usize, ) -> Result<Vec<u8>, HwCryptoError>211     pub(crate) fn derive_raw_key_material(
212         &self,
213         context: &[u8],
214         derived_key_size: usize,
215     ) -> Result<Vec<u8>, HwCryptoError> {
216         match &self.key_material {
217             KeyMaterial::Hmac(key) => {
218                 let hkdf = crypto_provider::HmacImpl;
219                 let explicit_key = explicit!(key).map_err(|_| {
220                     hwcrypto_err!(BAD_PARAMETER, "only explicit HMAC keys supported")
221                 })?;
222                 let raw_key = hkdf
223                     .hkdf(&[], &explicit_key.0, context, derived_key_size)
224                     .map_err(|e| hwcrypto_err!(GENERIC_ERROR, "couldn't derive key {:?}", e))?;
225                 Ok(raw_key)
226             }
227             _ => Err(hwcrypto_err!(BAD_PARAMETER, "only HMAC keys supported")),
228         }
229     }
230 
derive_key( &self, policy: &KeyPolicy, context: &[u8], ) -> binder::Result<binder::Strong<dyn IOpaqueKey>>231     pub(crate) fn derive_key(
232         &self,
233         policy: &KeyPolicy,
234         context: &[u8],
235     ) -> binder::Result<binder::Strong<dyn IOpaqueKey>> {
236         self.check_key_derivation_parameters(policy)?;
237         let derived_key_size = get_key_size_in_bytes(&policy.keyType)?;
238         let raw_key_material = self.derive_raw_key_material(context, derived_key_size)?;
239         Self::new_opaque_key_from_raw_bytes(policy, raw_key_material)
240     }
241 
derivation_allowed_lifetime( &self, derived_key_lifetime: KeyLifetime, ) -> Result<bool, HwCryptoError>242     fn derivation_allowed_lifetime(
243         &self,
244         derived_key_lifetime: KeyLifetime,
245     ) -> Result<bool, HwCryptoError> {
246         validate_lifetime(self.key_header.key_lifetime)?;
247         validate_lifetime(derived_key_lifetime)?;
248         match self.key_header.key_lifetime {
249             //ephemeral keys can be used to derive/wrap any other key
250             KeyLifetime::EPHEMERAL => Ok(true),
251             KeyLifetime::HARDWARE => {
252                 // Hardware keys cannot be used to derive/wrap ephemeral keys
253                 if derived_key_lifetime.0 == KeyLifetime::EPHEMERAL.0 {
254                     Ok(false)
255                 } else {
256                     Ok(true)
257                 }
258             }
259             KeyLifetime::PORTABLE => {
260                 // portable keys can only derive/wrap other portable keys
261                 if derived_key_lifetime.0 == KeyLifetime::PORTABLE.0 {
262                     Ok(true)
263                 } else {
264                     Ok(false)
265                 }
266             }
267             _ => Err(hwcrypto_err!(
268                 UNSUPPORTED,
269                 "unsupported Key lifetime {:?}",
270                 self.key_header.key_lifetime
271             )),
272         }
273     }
274 
key_can_be_used_for_derivation(&self) -> Result<(), HwCryptoError>275     fn key_can_be_used_for_derivation(&self) -> Result<(), HwCryptoError> {
276         match self.key_material {
277             KeyMaterial::Hmac(_) => Ok(()),
278             _ => Err(hwcrypto_err!(UNSUPPORTED, "Only HMAC keys can be used for key derivation")),
279         }?;
280         if self.key_header.key_usage != KeyUse::DERIVE {
281             return Err(hwcrypto_err!(BAD_PARAMETER, "key was not exclusively a derive key"));
282         }
283         Ok(())
284     }
285 }
286 
287 impl binder::Interface for OpaqueKey {}
288 
289 impl IOpaqueKey for OpaqueKey {
exportWrappedKey( &self, _wrapping_key: &binder::Strong<dyn IOpaqueKey>, ) -> binder::Result<Vec<u8>>290     fn exportWrappedKey(
291         &self,
292         _wrapping_key: &binder::Strong<dyn IOpaqueKey>,
293     ) -> binder::Result<Vec<u8>> {
294         Err(binder::Status::new_exception_str(
295             binder::ExceptionCode::UNSUPPORTED_OPERATION,
296             Some("export_wrapped_key has not been implemented yet"),
297         ))
298     }
299 
getKeyPolicy(&self) -> binder::Result<KeyPolicy>300     fn getKeyPolicy(&self) -> binder::Result<KeyPolicy> {
301         Ok(self.key_header.get_policy()?)
302     }
303 
getPublicKey(&self) -> binder::Result<Vec<u8>>304     fn getPublicKey(&self) -> binder::Result<Vec<u8>> {
305         Err(binder::Status::new_exception_str(
306             binder::ExceptionCode::UNSUPPORTED_OPERATION,
307             Some("get_public_key has not been implemented yet"),
308         ))
309     }
310 }
311 
check_key_material_with_policy( key_material: &KeyMaterial, policy: &KeyPolicy, ) -> Result<(), HwCryptoError>312 pub(crate) fn check_key_material_with_policy(
313     key_material: &KeyMaterial,
314     policy: &KeyPolicy,
315 ) -> Result<(), HwCryptoError> {
316     let key_type = &policy.keyType;
317     // `KeyMaterial` doesn't fully describe the cryptographic algorithm as `KeyType` does, so we can
318     //  only check if both of them are compatible, not provide a 1:1 mapping
319     match key_material {
320         KeyMaterial::Aes(aes_key) => match aes_key {
321             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque aes key provided")),
322             OpaqueOr::Explicit(aes_key) => match aes_key {
323                 crypto::aes::Key::Aes128(km) => match *key_type {
324                     KeyType::AES_128_CBC_NO_PADDING
325                     | KeyType::AES_128_CBC_PKCS7_PADDING
326                     | KeyType::AES_128_CTR
327                     | KeyType::AES_128_GCM
328                     | KeyType::AES_128_CMAC => Ok(()),
329                     _ => Err(hwcrypto_err!(
330                         BAD_PARAMETER,
331                         "type mismatch: key material {:?} key type: {:?}",
332                         km,
333                         key_type
334                     )),
335                 },
336                 crypto::aes::Key::Aes192(_) => {
337                     Err(hwcrypto_err!(BAD_PARAMETER, "AES keys of length 192 are not supported"))
338                 }
339                 crypto::aes::Key::Aes256(km) => match *key_type {
340                     KeyType::AES_256_CBC_NO_PADDING
341                     | KeyType::AES_256_CBC_PKCS7_PADDING
342                     | KeyType::AES_256_CTR
343                     | KeyType::AES_256_GCM
344                     | KeyType::AES_256_CMAC => Ok(()),
345                     _ => Err(hwcrypto_err!(
346                         BAD_PARAMETER,
347                         "type mismatch: key material {:?} key type: {:?}",
348                         km,
349                         key_type
350                     )),
351                 },
352             },
353         },
354         KeyMaterial::TripleDes(_) => {
355             Err(hwcrypto_err!(BAD_PARAMETER, "TDES is not currently supported"))
356         }
357         KeyMaterial::Hmac(hmac_key) => match hmac_key {
358             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque HMAC key provided")),
359             OpaqueOr::Explicit(_) => match *key_type {
360                 KeyType::HMAC_SHA256 => Ok(()),
361                 KeyType::HMAC_SHA512 => Ok(()),
362                 _ => Err(hwcrypto_err!(
363                     BAD_PARAMETER,
364                     "type mismatch for HMAC key key type: {:?}",
365                     key_type
366                 )),
367             },
368         },
369         KeyMaterial::Rsa(rsa_key) => match rsa_key {
370             OpaqueOr::Opaque(_) => Err(hwcrypto_err!(BAD_PARAMETER, "opaque RSA key provided")),
371             OpaqueOr::Explicit(rsa_key) => {
372                 let key_size = rsa_key.size();
373                 match (key_size, *key_type) {
374                     (2048, KeyType::RSA2048_PSS_SHA256) => Ok(()),
375                     (2048, KeyType::RSA2048_PKCS1_5_SHA256) => Ok(()),
376                     _ => Err(hwcrypto_err!(
377                         BAD_PARAMETER,
378                         "type mismatch for RSA key length {} and type: {:?}",
379                         key_size,
380                         key_type
381                     )),
382                 }
383             }
384         },
385         KeyMaterial::Ec(curve, curve_type, _) => match (curve, *key_type) {
386             (EcCurve::P256, KeyType::ECC_NIST_P256_SIGN_NO_PADDING) => Ok(()),
387             (EcCurve::P256, KeyType::ECC_NIST_P256_SIGN_SHA256) => Ok(()),
388             (EcCurve::P521, KeyType::ECC_NIST_P521_SIGN_NO_PADDING) => Ok(()),
389             (EcCurve::P521, KeyType::ECC_NIST_P521_SIGN_SHA512) => Ok(()),
390             (EcCurve::Curve25519, _) => match (curve_type, *key_type) {
391                 (CurveType::EdDsa, KeyType::ECC_ED25519_SIGN) => Ok(()),
392                 _ => Err(hwcrypto_err!(
393                     BAD_PARAMETER,
394                     "type mismatch for Ec Key curve {:?} and type: {:?}",
395                     curve,
396                     key_type
397                 )),
398             },
399             _ => Err(hwcrypto_err!(
400                 BAD_PARAMETER,
401                 "type mismatch for Ec Key curve {:?} and type: {:?}",
402                 curve,
403                 key_type
404             )),
405         },
406     }
407 }
408 
409 // Get key size in bytesgiven the backend AES key type. Used to check if we received enough bytes
410 // from the caller for an AES key.
get_aes_variant_key_size(variant: &crypto::aes::Variant) -> usize411 fn get_aes_variant_key_size(variant: &crypto::aes::Variant) -> usize {
412     match variant {
413         crypto::aes::Variant::Aes128 => 16,
414         crypto::aes::Variant::Aes192 => 24,
415         crypto::aes::Variant::Aes256 => 32,
416     }
417 }
418 
419 // Translating a policy AES `KeyType` into the type understood by the cryptographic backend we are
420 // currently used
421 // 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>422 fn get_aes_variant(key_type: &KeyType) -> Result<crypto::aes::Variant, HwCryptoError> {
423     match *key_type {
424         KeyType::AES_128_CBC_NO_PADDING
425         | KeyType::AES_128_CBC_PKCS7_PADDING
426         | KeyType::AES_128_CTR
427         | KeyType::AES_128_GCM
428         | KeyType::AES_128_CMAC => Ok(crypto::aes::Variant::Aes128),
429         KeyType::AES_256_CBC_NO_PADDING
430         | KeyType::AES_256_CBC_PKCS7_PADDING
431         | KeyType::AES_256_CTR
432         | KeyType::AES_256_GCM
433         | KeyType::AES_256_CMAC => Ok(crypto::aes::Variant::Aes256),
434         _ => Err(hwcrypto_err!(BAD_PARAMETER, "not an AES key type: {:?}", key_type)),
435     }
436 }
437 
438 // Return a keysize given a `KeyType`. Because HMAC key sizes can be defined by the
439 // caller, `key_size_bits` is needed to cover all cases.
get_key_size_in_bytes(key_type: &KeyType) -> Result<usize, HwCryptoError>440 pub(crate) fn get_key_size_in_bytes(key_type: &KeyType) -> Result<usize, HwCryptoError> {
441     match *key_type {
442         KeyType::AES_128_CBC_NO_PADDING
443         | KeyType::AES_128_CBC_PKCS7_PADDING
444         | KeyType::AES_128_CTR
445         | KeyType::AES_128_GCM
446         | KeyType::AES_128_CMAC => Ok(16),
447         KeyType::AES_256_CBC_NO_PADDING
448         | KeyType::AES_256_CBC_PKCS7_PADDING
449         | KeyType::AES_256_CTR
450         | KeyType::AES_256_GCM
451         | KeyType::AES_256_CMAC => Ok(32),
452         KeyType::HMAC_SHA256 => Ok(32),
453         KeyType::HMAC_SHA512 => Ok(64),
454         _ => unimplemented!("Only AES and HMAC has been implemented"),
455     }
456 }
457 
validate_lifetime(lifetime: KeyLifetime) -> Result<(), HwCryptoError>458 fn validate_lifetime(lifetime: KeyLifetime) -> Result<(), HwCryptoError> {
459     match lifetime {
460         KeyLifetime::EPHEMERAL | KeyLifetime::HARDWARE | KeyLifetime::PORTABLE => Ok(()),
461         // AIDL structure have more values added than the ones defined on the AIDL file
462         _ => Err(hwcrypto_err!(UNSUPPORTED, "unsupported Key lifetime {:?}", lifetime)),
463     }
464 }
465 
check_type_derived_key(key_type: KeyType) -> Result<(), HwCryptoError>466 fn check_type_derived_key(key_type: KeyType) -> Result<(), HwCryptoError> {
467     match key_type {
468         KeyType::AES_128_CBC_NO_PADDING
469         | KeyType::AES_128_CBC_PKCS7_PADDING
470         | KeyType::AES_128_CTR
471         | KeyType::AES_128_GCM
472         | KeyType::AES_128_CMAC
473         | KeyType::AES_256_CBC_NO_PADDING
474         | KeyType::AES_256_CBC_PKCS7_PADDING
475         | KeyType::AES_256_CTR
476         | KeyType::AES_256_GCM
477         | KeyType::AES_256_CMAC
478         | KeyType::HMAC_SHA256
479         | KeyType::HMAC_SHA512 => Ok(()),
480         _ => Err(hwcrypto_err!(BAD_PARAMETER, "Only HMAC and AES keys are supported")),
481     }
482 }
483 
key_vec_to_array<T, U: std::convert::TryInto<T>>(input: U) -> Result<T, HwCryptoError>484 fn key_vec_to_array<T, U: std::convert::TryInto<T>>(input: U) -> Result<T, HwCryptoError> {
485     input
486         .try_into()
487         .map_err(|_| hwcrypto_err!(BAD_PARAMETER, "couldn't transform vector into array"))
488 }
489 
490 // Create a backend-compatible cryptographic key from either a provided vector of uniform random
491 // bytes or, if this not provided, use the cryptographic backend to create it. The type is based on
492 // the policy `KeyType`. Because HMAC keys can have arbitrary sizes, include an optional
493 // `key_size_bits` for that case.
generate_key_material( key_type: &KeyType, key_random_bytes: Option<Vec<u8>>, ) -> Result<KeyMaterial, HwCryptoError>494 pub(crate) fn generate_key_material(
495     key_type: &KeyType,
496     key_random_bytes: Option<Vec<u8>>,
497 ) -> Result<KeyMaterial, HwCryptoError> {
498     let aes = crypto_provider::AesImpl;
499     let hmac = crypto_provider::HmacImpl;
500     let mut rng = crypto_provider::RngImpl::default();
501     match *key_type {
502         KeyType::AES_128_CBC_NO_PADDING
503         | KeyType::AES_128_CBC_PKCS7_PADDING
504         | KeyType::AES_128_CTR
505         | KeyType::AES_128_GCM
506         | KeyType::AES_128_CMAC
507         | KeyType::AES_256_CBC_NO_PADDING
508         | KeyType::AES_256_CBC_PKCS7_PADDING
509         | KeyType::AES_256_CTR
510         | KeyType::AES_256_GCM
511         | KeyType::AES_256_CMAC => {
512             let variant = get_aes_variant(key_type)?;
513             if let Some(key_bytes) = key_random_bytes {
514                 if key_bytes.len() != get_aes_variant_key_size(&variant) {
515                     return Err(hwcrypto_err!(
516                         BAD_PARAMETER,
517                         "for aes key needed {} bytes, received {}",
518                         key_bytes.len(),
519                         get_aes_variant_key_size(&variant)
520                     ));
521                 }
522                 match variant {
523                     crypto::aes::Variant::Aes128 => Ok(KeyMaterial::Aes(
524                         crypto::aes::Key::Aes128(key_vec_to_array(key_bytes)?).into(),
525                     )),
526                     crypto::aes::Variant::Aes192 => Err(hwcrypto_err!(
527                         BAD_PARAMETER,
528                         "AES keys of length 192 are not supported",
529                     )),
530                     crypto::aes::Variant::Aes256 => Ok(KeyMaterial::Aes(
531                         crypto::aes::Key::Aes256(key_vec_to_array(key_bytes)?).into(),
532                     )),
533                 }
534             } else {
535                 Ok(aes.generate_key(&mut rng, variant, &[])?)
536             }
537         }
538         KeyType::HMAC_SHA256 | KeyType::HMAC_SHA512 => {
539             let key_size_bytes = get_key_size_in_bytes(key_type)?;
540             if let Some(key_bytes) = key_random_bytes {
541                 if key_bytes.len() != key_size_bytes {
542                     Err(hwcrypto_err!(
543                         BAD_PARAMETER,
544                         "for hmac key needed {} bytes, received {}",
545                         key_bytes.len(),
546                         key_size_bytes
547                     ))
548                 } else {
549                     Ok(KeyMaterial::Hmac(crypto::hmac::Key::new(key_bytes).into()))
550                 }
551             } else {
552                 Ok(hmac.generate_key(
553                     &mut rng,
554                     kmr_wire::KeySizeInBits((key_size_bytes * 8).try_into().map_err(|_| {
555                         hwcrypto_err!(
556                             GENERIC_ERROR,
557                             "shouldn't happen, key_size_bytes * 8 should fit on an u32"
558                         )
559                     })?),
560                     &[],
561                 )?)
562             }
563         }
564         _ => unimplemented!("key material other than AES and HMAC not implemented yet"),
565     }
566 }
567 
568 #[cfg(test)]
569 mod tests {
570     use super::*;
571     use test::{expect, expect_eq};
572 
573     #[test]
boot_unique_values_match()574     fn boot_unique_values_match() {
575         let boot_value = BootUniqueValue::new().expect("couldn't get boot unique value");
576         let boot_value2 = BootUniqueValue::new().expect("couldn't get boot unique value");
577         expect_eq!(boot_value, boot_value2, "boot unique values should match");
578     }
579 
580     #[test]
generate_key_material_test()581     fn generate_key_material_test() {
582         let usage = KeyUse::ENCRYPT;
583         let key_type = KeyType::AES_256_GCM;
584         let policy = KeyPolicy {
585             usage,
586             keyLifetime: KeyLifetime::EPHEMERAL,
587             keyPermissions: Vec::new(),
588             keyType: key_type,
589             keyManagementKey: false,
590         };
591         let key_material = generate_key_material(&policy.keyType, None);
592         expect!(key_material.is_ok(), "couldn't retrieve key material");
593         let key_material = key_material.unwrap();
594         let check_result = check_key_material_with_policy(&key_material, &policy);
595         expect!(check_result.is_ok(), "wrong key type");
596     }
597 }
598