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 //! HwCryptoKey tests.
18
19 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::{
20 DerivedKeyParameters::DerivedKeyParameters, DerivedKeyPolicy::DerivedKeyPolicy,
21 DiceBoundDerivationKey::DiceBoundDerivationKey, KeySlot::KeySlot,
22 };
23 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
24 HalErrorCode, AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime, KeyUse::KeyUse,
25 HmacKey::HmacKey, ProtectionId::ProtectionId,
26 };
27 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::KeyPolicy::KeyPolicy;
28 use hwcryptohal_common;
29 use rdroidtest::{ignore_if, rdroidtest};
30
31 #[rdroidtest]
32 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_connection()33 fn test_hwcrypto_key_connection() {
34 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
35 assert!(hw_crypto_key.is_ok(), "Couldn't get back a hwcryptokey binder object");
36 }
37
38 #[rdroidtest]
39 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_key_get_current_dice_policy()40 fn test_hwcrypto_key_get_current_dice_policy() {
41 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
42 .expect("Couldn't get back a hwcryptokey binder object");
43 let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
44 assert!(!dice_policy.is_empty(), "received empty dice policy");
45 }
46
47 #[rdroidtest]
48 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_get_keyslot_data()49 fn test_hwcrypto_get_keyslot_data() {
50 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
51 .expect("Couldn't get back a hwcryptokey binder object");
52 let key = hw_crypto_key.getKeyslotData(KeySlot::KEYMINT_SHARED_HMAC_KEY);
53 assert_eq!(
54 key.err()
55 .expect("should not be able to access this keylost from the host")
56 .service_specific_error(),
57 HalErrorCode::UNAUTHORIZED,
58 "wrong error type received"
59 );
60 }
61
62 #[rdroidtest]
63 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_import_clear_key()64 fn test_hwcrypto_import_clear_key() {
65 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
66 .expect("Couldn't get back a hwcryptokey binder object");
67 let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
68 let mut policy = KeyPolicy {
69 usage: KeyUse::ENCRYPT_DECRYPT,
70 keyLifetime: KeyLifetime::PORTABLE,
71 keyPermissions: Vec::new(),
72 keyManagementKey: false,
73 keyType: KeyType::AES_128_GCM,
74 };
75 let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import key");
76 assert!(key.getPublicKey().is_err(), "symmetric keys don't have a public key");
77 let imported_policy = key.getKeyPolicy().expect("couldn't get key policy");
78 let serialized_policy =
79 hwcryptohal_common::key_policy_to_cbor(&policy).expect("couldn't serialize policy");
80 let serialized_impoorted_policy = hwcryptohal_common::key_policy_to_cbor(&imported_policy)
81 .expect("couldn't serialize policy");
82 assert_eq!(serialized_policy, serialized_impoorted_policy, "policies should match");
83 policy.keyLifetime = KeyLifetime::EPHEMERAL;
84 let key = hw_crypto_key.importClearKey(&clear_key, &policy);
85 assert!(key.is_err(), "imported keys should be of type PORTABLE");
86 policy.keyLifetime = KeyLifetime::HARDWARE;
87 let key = hw_crypto_key.importClearKey(&clear_key, &policy);
88 assert!(key.is_err(), "imported keys should be of type PORTABLE");
89 }
90
91 #[rdroidtest]
92 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_token_export_import()93 fn test_hwcrypto_token_export_import() {
94 // This test is not representative of the complete flow because here the exporter and importer
95 // are the same client, which is not something we would usually do
96 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
97 .expect("Couldn't get back a hwcryptokey binder object");
98 let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
99 let policy = KeyPolicy {
100 usage: KeyUse::DERIVE,
101 keyLifetime: KeyLifetime::PORTABLE,
102 keyPermissions: Vec::new(),
103 keyManagementKey: false,
104 keyType: KeyType::HMAC_SHA256,
105 };
106 let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
107 let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
108 let token =
109 key.getShareableToken(dice_policy.as_slice()).expect("Couldn't get shareable token");
110 let imported_key = hw_crypto_key
111 .keyTokenImport(&token, dice_policy.as_slice());
112 assert!(imported_key.is_ok(), "Couldn't import shareable token");
113 // TODO: Use operations to verify that the keys match
114 }
115
116 #[rdroidtest]
117 #[ignore_if(hwcryptohal_vts_test::ignore_test())]
test_hwcrypto_android_invalid_calls()118 fn test_hwcrypto_android_invalid_calls() {
119 let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
120 .expect("Couldn't get back a hwcryptokey binder object");
121 let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
122 let policy = KeyPolicy {
123 usage: KeyUse::DERIVE,
124 keyLifetime: KeyLifetime::PORTABLE,
125 keyPermissions: Vec::new(),
126 keyManagementKey: false,
127 keyType: KeyType::HMAC_SHA256,
128 };
129 let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
130 let protections = Vec::new();
131 let res = key.setProtectionId(ProtectionId::WIDEVINE_OUTPUT_BUFFER, &protections);
132 assert_eq!(
133 res.err()
134 .expect("should not be call this function from the host")
135 .service_specific_error(),
136 HalErrorCode::UNAUTHORIZED,
137 "wrong error type received"
138 );
139 let derivation_key = DiceBoundDerivationKey::OpaqueKey(Some(key));
140 let res = hw_crypto_key.deriveCurrentDicePolicyBoundKey(&derivation_key);
141 assert_eq!(
142 res.err()
143 .expect("should not be call this function from the host")
144 .service_specific_error(),
145 HalErrorCode::UNAUTHORIZED,
146 "wrong error type received"
147 );
148 let fake_policy = Vec::new();
149 let res = hw_crypto_key.deriveDicePolicyBoundKey(&derivation_key, &fake_policy);
150 assert_eq!(
151 res.err()
152 .expect("should not be call this function from the host")
153 .service_specific_error(),
154 HalErrorCode::UNAUTHORIZED,
155 "wrong error type received"
156 );
157 let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
158 let derived_policy = DerivedKeyPolicy::OpaqueKey(Vec::new());
159 let derived_parameters = DerivedKeyParameters {
160 derivationKey: Some(key),
161 keyPolicy: derived_policy,
162 context: Vec::new(),
163 };
164 let res = hw_crypto_key.deriveKey(&derived_parameters);
165 assert_eq!(
166 res.err()
167 .expect("should not be call this function from the host")
168 .service_specific_error(),
169 HalErrorCode::UNAUTHORIZED,
170 "wrong error type received"
171 );
172 }
173
174 rdroidtest::test_main!();
175