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 //! KeyPolicy serialization facilities
18 
19 use alloc::collections::btree_set::BTreeSet;
20 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
21     KeyLifetime::KeyLifetime, KeyPermissions::KeyPermissions, KeyType::KeyType, KeyUse::KeyUse,
22 };
23 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::KeyPolicy::KeyPolicy;
24 use ciborium::Value;
25 use coset::{AsCborValue, CborSerializable, CoseError};
26 
27 use crate::{aidl_enum_wrapper, cose_enum_gen};
28 use crate::{err::HwCryptoError, hwcrypto_err};
29 
30 aidl_enum_wrapper! {
31     aidl_name: KeyUse,
32     wrapper_name: KeyUseSerializable,
33     fields: [ENCRYPT, DECRYPT, ENCRYPT_DECRYPT, SIGN, DERIVE, WRAP]
34 }
35 
36 aidl_enum_wrapper! {
37     aidl_name: KeyLifetime,
38     wrapper_name: KeyLifetimeSerializable,
39     fields: [EPHEMERAL, HARDWARE, PORTABLE]
40 }
41 
42 aidl_enum_wrapper! {
43     aidl_name: KeyType,
44     wrapper_name: KeyTypeSerializable,
45     fields: [AES_128_CBC_NO_PADDING, AES_128_CBC_PKCS7_PADDING, AES_128_CTR, AES_128_GCM, AES_128_CMAC,
46     AES_256_CBC_NO_PADDING, AES_256_CBC_PKCS7_PADDING, AES_256_CTR, AES_256_GCM, AES_256_CMAC,
47     HMAC_SHA256, HMAC_SHA512,
48     RSA2048_PKCS1_5_SHA256, RSA2048_PSS_SHA256, ECC_NIST_P256_SIGN_NO_PADDING, ECC_NIST_P256_SIGN_SHA256,
49     ECC_NIST_P521_SIGN_NO_PADDING, ECC_NIST_P521_SIGN_SHA512,
50     ECC_ED25519_SIGN]
51 }
52 
53 aidl_enum_wrapper! {
54     aidl_name: KeyPermissions,
55     wrapper_name: KeyPermissionsSerializable,
56     fields: [ALLOW_EPHEMERAL_KEY_WRAPPING, ALLOW_HARDWARE_KEY_WRAPPING, ALLOW_PORTABLE_KEY_WRAPPING]
57 }
58 
59 #[derive(Debug, PartialEq)]
60 struct SerializableKeyPolicy {
61     key_lifetime: KeyLifetimeSerializable,
62     key_permissions: BTreeSet<KeyPermissionsSerializable>,
63     key_usage: KeyUseSerializable,
64     key_type: KeyTypeSerializable,
65     management_key: bool,
66 }
67 
68 impl SerializableKeyPolicy {
new(key_policy: &KeyPolicy) -> Result<Self, crate::err::HwCryptoError>69     fn new(key_policy: &KeyPolicy) -> Result<Self, crate::err::HwCryptoError> {
70         let mut key_permissions = BTreeSet::new();
71         for permission in &key_policy.keyPermissions {
72             key_permissions.insert(KeyPermissionsSerializable(*permission));
73         }
74         Ok(Self {
75             key_lifetime: KeyLifetimeSerializable(key_policy.keyLifetime),
76             key_permissions,
77             key_usage: KeyUseSerializable(key_policy.usage),
78             key_type: KeyTypeSerializable(key_policy.keyType),
79             management_key: key_policy.keyManagementKey,
80         })
81     }
82 }
83 
84 impl TryFrom<&KeyPolicy> for SerializableKeyPolicy {
85     type Error = crate::err::HwCryptoError;
86 
try_from(value: &KeyPolicy) -> Result<Self, Self::Error>87     fn try_from(value: &KeyPolicy) -> Result<Self, Self::Error> {
88         Self::new(value)
89     }
90 }
91 
92 impl TryFrom<KeyPolicy> for SerializableKeyPolicy {
93     type Error = crate::err::HwCryptoError;
94 
try_from(value: KeyPolicy) -> Result<Self, Self::Error>95     fn try_from(value: KeyPolicy) -> Result<Self, Self::Error> {
96         (&value).try_into()
97     }
98 }
99 
100 impl TryFrom<&SerializableKeyPolicy> for KeyPolicy {
101     type Error = crate::err::HwCryptoError;
102 
try_from(value: &SerializableKeyPolicy) -> Result<Self, Self::Error>103     fn try_from(value: &SerializableKeyPolicy) -> Result<Self, Self::Error> {
104         let mut key_permissions = Vec::new();
105         key_permissions.try_reserve(value.key_permissions.len())?;
106         // permissions on the returned key policy will be sorted because they are retrieved that
107         // way from the SerializableKeyPolicy
108         for permission in &value.key_permissions {
109             key_permissions.push((*permission).into());
110         }
111         Ok(Self {
112             keyLifetime: value.key_lifetime.into(),
113             keyPermissions: key_permissions,
114             usage: value.key_usage.into(),
115             keyType: value.key_type.into(),
116             keyManagementKey: value.management_key,
117         })
118     }
119 }
120 
121 impl TryFrom<SerializableKeyPolicy> for KeyPolicy {
122     type Error = crate::err::HwCryptoError;
123 
try_from(value: SerializableKeyPolicy) -> Result<Self, Self::Error>124     fn try_from(value: SerializableKeyPolicy) -> Result<Self, Self::Error> {
125         (&value).try_into()
126     }
127 }
128 
129 cose_enum_gen! {
130     enum HeaderCoseLabels {
131         KeyUsage = -65701,
132         KeyLifetime = -65702,
133         KeyPermissions = -65703,
134         KeyType = -65704,
135         ManagementKey = -65705,
136     }
137 }
138 
139 impl AsCborValue for SerializableKeyPolicy {
to_cbor_value(self) -> Result<Value, CoseError>140     fn to_cbor_value(self) -> Result<Value, CoseError> {
141         let mut cbor_map = Vec::<(Value, Value)>::new();
142         let key = Value::Integer((HeaderCoseLabels::KeyLifetime as i64).into());
143         let value = Value::Integer(self.key_lifetime.into());
144         cbor_map.try_reserve_exact(5).map_err(|_| CoseError::EncodeFailed)?;
145         cbor_map.push((key, value));
146 
147         // Creating key permissions array
148         // We need this array to always be sorted so the created CBOR structure will always match
149         // if the input vector has the same permissions, this is currently provided by
150         // `BTreeSet::into_iter` always returning the elements ordered in ascending order.
151         let mut permissions = Vec::new();
152         permissions.try_reserve(self.key_permissions.len()).map_err(|_| CoseError::EncodeFailed)?;
153         for permission in self.key_permissions.into_iter() {
154             permissions.push(Value::Integer(permission.into()));
155         }
156         let key = Value::Integer((HeaderCoseLabels::KeyPermissions as i64).into());
157         let value = Value::Array(permissions);
158         cbor_map.push((key, value));
159 
160         let key = Value::Integer((HeaderCoseLabels::KeyUsage as i64).into());
161         let value = Value::Integer(self.key_usage.into());
162         cbor_map.push((key, value));
163 
164         let key = Value::Integer((HeaderCoseLabels::KeyType as i64).into());
165         let value = Value::Integer(self.key_type.into());
166         cbor_map.push((key, value));
167 
168         let key = Value::Integer((HeaderCoseLabels::ManagementKey as i64).into());
169         let value = Value::Bool(self.management_key.into());
170         cbor_map.push((key, value));
171 
172         Ok(Value::Map(cbor_map))
173     }
174 
from_cbor_value(value: Value) -> Result<Self, CoseError>175     fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
176         let key_policy = value.into_map().map_err(|_| CoseError::ExtraneousData)?;
177 
178         let mut key_lifetime: Option<KeyLifetimeSerializable> = None;
179         let mut key_permissions: Option<BTreeSet<KeyPermissionsSerializable>> = None;
180         let mut key_usage: Option<KeyUseSerializable> = None;
181         let mut key_type: Option<KeyTypeSerializable> = None;
182         let mut management_key: Option<bool> = None;
183 
184         for (map_key, map_val) in key_policy {
185             let key = map_key.into_integer().map_err(|_| CoseError::ExtraneousData)?;
186             match key.try_into()? {
187                 HeaderCoseLabels::KeyLifetime => {
188                     key_lifetime = Some(
189                         map_val
190                             .as_integer()
191                             .ok_or(CoseError::EncodeFailed)?
192                             .try_into()
193                             .map_err(|_| CoseError::EncodeFailed)?,
194                     );
195                 }
196                 HeaderCoseLabels::KeyPermissions => {
197                     let mut permissions = BTreeSet::new();
198                     for permission in map_val.as_array().ok_or(CoseError::EncodeFailed)? {
199                         permissions.insert(
200                             permission
201                                 .as_integer()
202                                 .ok_or(CoseError::EncodeFailed)?
203                                 .try_into()
204                                 .map_err(|_| CoseError::EncodeFailed)?,
205                         );
206                     }
207                     key_permissions = Some(permissions);
208                 }
209                 HeaderCoseLabels::KeyUsage => {
210                     key_usage = Some(
211                         map_val
212                             .as_integer()
213                             .ok_or(CoseError::EncodeFailed)?
214                             .try_into()
215                             .map_err(|_| CoseError::EncodeFailed)?,
216                     );
217                 }
218                 HeaderCoseLabels::KeyType => {
219                     key_type = Some(
220                         map_val
221                             .as_integer()
222                             .ok_or(CoseError::EncodeFailed)?
223                             .try_into()
224                             .map_err(|_| CoseError::EncodeFailed)?,
225                     );
226                 }
227                 HeaderCoseLabels::ManagementKey => {
228                     management_key = Some(map_val.as_bool().ok_or(CoseError::EncodeFailed)?);
229                 }
230             }
231         }
232 
233         let key_lifetime = key_lifetime.ok_or(CoseError::EncodeFailed)?;
234         let key_permissions = key_permissions.ok_or(CoseError::EncodeFailed)?;
235         let key_usage = key_usage.ok_or(CoseError::EncodeFailed)?;
236         let key_type = key_type.ok_or(CoseError::EncodeFailed)?;
237         let management_key = management_key.ok_or(CoseError::EncodeFailed)?;
238 
239         Ok(SerializableKeyPolicy {
240             key_lifetime,
241             key_permissions,
242             key_usage,
243             key_type,
244             management_key,
245         })
246     }
247 }
248 
249 pub static AES_SYMMETRIC_KEY_USES_MASK: i32 = KeyUse::ENCRYPT_DECRYPT.0 | KeyUse::WRAP.0;
250 pub static HMAC_KEY_USES_MASK: i32 = KeyUse::DERIVE.0;
251 
check_key_policy(key_policy: &KeyPolicy) -> Result<(), HwCryptoError>252 pub fn check_key_policy(key_policy: &KeyPolicy) -> Result<(), HwCryptoError> {
253     match key_policy.keyType {
254         KeyType::AES_128_CBC_NO_PADDING
255         | KeyType::AES_128_CBC_PKCS7_PADDING
256         | KeyType::AES_128_CTR
257         | KeyType::AES_128_GCM
258         | KeyType::AES_256_CBC_NO_PADDING
259         | KeyType::AES_256_CBC_PKCS7_PADDING
260         | KeyType::AES_256_CTR
261         | KeyType::AES_256_GCM => {
262             if (key_policy.usage.0 & !AES_SYMMETRIC_KEY_USES_MASK) != 0 {
263                 Err(hwcrypto_err!(
264                     BAD_PARAMETER,
265                     "usage not supported for AES symmetric key: {}",
266                     key_policy.usage.0
267                 ))
268             } else {
269                 Ok(())
270             }
271         }
272         KeyType::HMAC_SHA256 | KeyType::HMAC_SHA512 => {
273             if (key_policy.usage.0 & !HMAC_KEY_USES_MASK) != 0 {
274                 Err(hwcrypto_err!(
275                     BAD_PARAMETER,
276                     "usage not supported for HMAC key: {}",
277                     key_policy.usage.0
278                 ))
279             } else {
280                 Ok(())
281             }
282         }
283         KeyType::AES_128_CMAC
284         | KeyType::AES_256_CMAC
285         | KeyType::RSA2048_PSS_SHA256
286         | KeyType::RSA2048_PKCS1_5_SHA256
287         | KeyType::ECC_NIST_P256_SIGN_NO_PADDING
288         | KeyType::ECC_NIST_P256_SIGN_SHA256
289         | KeyType::ECC_NIST_P521_SIGN_NO_PADDING
290         | KeyType::ECC_NIST_P521_SIGN_SHA512
291         | KeyType::ECC_ED25519_SIGN => {
292             Err(hwcrypto_err!(UNSUPPORTED, "key type not supported yet"))
293         }
294         _ => Err(hwcrypto_err!(BAD_PARAMETER, "unknown keytype provided {:?}", key_policy.keyType)),
295     }
296 }
297 
cbor_serialize_key_policy(key_policy: &KeyPolicy) -> Result<Vec<u8>, HwCryptoError>298 pub fn cbor_serialize_key_policy(key_policy: &KeyPolicy) -> Result<Vec<u8>, HwCryptoError> {
299     let serializable_key_policy: SerializableKeyPolicy = key_policy.try_into()?;
300     serializable_key_policy
301         .to_cbor_value()?
302         .to_vec()
303         .map_err(|_| hwcrypto_err!(SERIALIZATION_ERROR, "couldn't serialize policy"))
304 }
305 
cbor_policy_to_aidl(cbor_key_policy: &[u8]) -> Result<KeyPolicy, HwCryptoError>306 pub fn cbor_policy_to_aidl(cbor_key_policy: &[u8]) -> Result<KeyPolicy, HwCryptoError> {
307     let policy =
308         SerializableKeyPolicy::from_cbor_value(Value::from_slice(cbor_key_policy)?)?.try_into()?;
309     check_key_policy(&policy)?;
310     Ok(policy)
311 }
312 
313 #[cfg(test)]
314 mod tests {
315     use super::*;
316     use test::{expect, expect_eq};
317 
318     #[test]
serialize_policy()319     fn serialize_policy() {
320         let policy = KeyPolicy {
321             usage: KeyUse::ENCRYPT,
322             keyLifetime: KeyLifetime::EPHEMERAL,
323             keyPermissions: Vec::new(),
324             keyType: KeyType::AES_256_GCM,
325             keyManagementKey: false,
326         };
327 
328         let serialize_result = cbor_serialize_key_policy(&policy);
329         expect!(serialize_result.is_ok(), "couldn't serialize policy");
330         let serialized_policy = serialize_result.unwrap();
331         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
332         expect!(deserialization.is_ok(), "couldn't deserialize policy");
333         let deserialized_policy = deserialization.unwrap();
334         let policy: SerializableKeyPolicy = policy.try_into().unwrap();
335         let deserialized_policy: SerializableKeyPolicy = (&deserialized_policy).try_into().unwrap();
336         expect_eq!(policy, deserialized_policy, "policies should match");
337     }
338 
339     #[test]
bad_policies()340     fn bad_policies() {
341         let mut policy = KeyPolicy {
342             usage: KeyUse::SIGN,
343             keyLifetime: KeyLifetime::EPHEMERAL,
344             keyPermissions: Vec::new(),
345             keyType: KeyType::AES_256_GCM,
346             keyManagementKey: false,
347         };
348         let serialize_result = cbor_serialize_key_policy(&policy);
349         expect!(serialize_result.is_ok(), "couldn't serialize policy");
350         let serialized_policy = serialize_result.unwrap();
351         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
352         expect!(deserialization.is_err(), "shouldn't be able to deserailize incorrect policy");
353 
354         policy.usage = KeyUse::DERIVE;
355         let serialize_result = cbor_serialize_key_policy(&policy);
356         expect!(serialize_result.is_ok(), "couldn't serialize policy");
357         let serialized_policy = serialize_result.unwrap();
358         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
359         expect!(deserialization.is_err(), "shouldn't be able to deserailize incorrect policy");
360 
361         policy.keyType = KeyType::HMAC_SHA256;
362         policy.usage = KeyUse::ENCRYPT;
363         let serialize_result = cbor_serialize_key_policy(&policy);
364         expect!(serialize_result.is_ok(), "couldn't serialize policy");
365         let serialized_policy = serialize_result.unwrap();
366         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
367         expect!(deserialization.is_err(), "shouldn't be able to deserailize incorrect policy");
368 
369         policy.usage = KeyUse::DECRYPT;
370         let serialize_result = cbor_serialize_key_policy(&policy);
371         expect!(serialize_result.is_ok(), "couldn't serialize policy");
372         let serialized_policy = serialize_result.unwrap();
373         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
374         expect!(deserialization.is_err(), "shouldn't be able to deserailize incorrect policy");
375 
376         policy.keyType = KeyType::HMAC_SHA512;
377         policy.usage = KeyUse::ENCRYPT_DECRYPT;
378         let serialize_result = cbor_serialize_key_policy(&policy);
379         expect!(serialize_result.is_ok(), "couldn't serialize policy");
380         let serialized_policy = serialize_result.unwrap();
381         let deserialization = cbor_policy_to_aidl(serialized_policy.as_slice());
382         expect!(deserialization.is_err(), "shouldn't be able to deserailize incorrect policy");
383     }
384 }
385