1 /*
2 * Copyright (C) 2021 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 #define LOG_TAG "keymint_1_attest_key_test"
18
19 #include <cutils/log.h>
20 #include <cutils/properties.h>
21 #include <keymint_support/key_param_output.h>
22 #include <keymint_support/openssl_utils.h>
23
24 #include "KeyMintAidlTestBase.h"
25
26 namespace aidl::android::hardware::security::keymint::test {
27
28 class DeviceUniqueAttestationTest : public KeyMintAidlTestBase {
29 protected:
CheckUniqueAttestationResults(const vector<uint8_t> & key_blob,const vector<KeyCharacteristics> & key_characteristics,const AuthorizationSet & hw_enforced)30 void CheckUniqueAttestationResults(const vector<uint8_t>& key_blob,
31 const vector<KeyCharacteristics>& key_characteristics,
32 const AuthorizationSet& hw_enforced) {
33 ASSERT_GT(cert_chain_.size(), 0);
34
35 if (KeyMintAidlTestBase::dump_Attestations) {
36 std::cout << bin2hex(cert_chain_[0].encodedCertificate) << std::endl;
37 }
38
39 ASSERT_GT(key_blob.size(), 0U);
40
41 AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
42
43 // The device-unique attestation chain should contain exactly three certificates:
44 // * The leaf with the attestation extension.
45 // * An intermediate, signing the leaf using the device-unique key.
46 // * A self-signed root, signed using some authority's key, certifying
47 // the device-unique key.
48 const size_t chain_length = cert_chain_.size();
49 ASSERT_TRUE(chain_length == 2 || chain_length == 3);
50 // TODO(b/191361618): Once StrongBox implementations use a correctly-issued
51 // certificate chain, do not skip issuers matching.
52 EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false));
53
54 AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
55 EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
56 hw_enforced, SecLevel(),
57 cert_chain_[0].encodedCertificate));
58 }
59 };
60
61 /*
62 * DeviceUniqueAttestationTest.RsaNonStrongBoxUnimplemented
63 *
64 * Verifies that non strongbox implementations do not implement Rsa device unique
65 * attestation.
66 */
TEST_P(DeviceUniqueAttestationTest,RsaNonStrongBoxUnimplemented)67 TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
68 if (SecLevel() == SecurityLevel::STRONGBOX) {
69 GTEST_SKIP() << "Test not applicable to StrongBox device";
70 }
71
72 vector<uint8_t> key_blob;
73 vector<KeyCharacteristics> key_characteristics;
74
75 // Check RSA implementation
76 auto result = GenerateKey(AuthorizationSetBuilder()
77 .Authorization(TAG_NO_AUTH_REQUIRED)
78 .RsaSigningKey(2048, 65537)
79 .Digest(Digest::SHA_2_256)
80 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
81 .Authorization(TAG_INCLUDE_UNIQUE_ID)
82 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
83 .SetDefaultValidity()
84 .AttestationChallenge("challenge")
85 .AttestationApplicationId("foo")
86 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
87 &key_blob, &key_characteristics);
88
89 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
90 }
91
92 /*
93 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
94 *
95 * Verifies that non strongbox implementations do not implement Ecdsa device unique
96 * attestation.
97 */
TEST_P(DeviceUniqueAttestationTest,EcdsaNonStrongBoxUnimplemented)98 TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
99 if (SecLevel() == SecurityLevel::STRONGBOX) {
100 GTEST_SKIP() << "Test not applicable to StrongBox device";
101 }
102
103 vector<uint8_t> key_blob;
104 vector<KeyCharacteristics> key_characteristics;
105
106 // Check Ecdsa implementation
107 auto result = GenerateKey(AuthorizationSetBuilder()
108 .Authorization(TAG_NO_AUTH_REQUIRED)
109 .EcdsaSigningKey(EcCurve::P_256)
110 .Digest(Digest::SHA_2_256)
111 .Authorization(TAG_INCLUDE_UNIQUE_ID)
112 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
113 .SetDefaultValidity()
114 .AttestationChallenge("challenge")
115 .AttestationApplicationId("foo")
116 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
117 &key_blob, &key_characteristics);
118
119 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
120 }
121
122 /*
123 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
124 *
125 * Verifies that strongbox implementations of Rsa implements device unique
126 * attestation correctly, if implemented.
127 */
TEST_P(DeviceUniqueAttestationTest,RsaDeviceUniqueAttestation)128 TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
129 if (SecLevel() != SecurityLevel::STRONGBOX) {
130 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
131 }
132
133 vector<uint8_t> key_blob;
134 vector<KeyCharacteristics> key_characteristics;
135 int key_size = 2048;
136
137 auto result = GenerateKey(AuthorizationSetBuilder()
138 .Authorization(TAG_NO_AUTH_REQUIRED)
139 .RsaSigningKey(key_size, 65537)
140 .Digest(Digest::SHA_2_256)
141 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
142 .Authorization(TAG_INCLUDE_UNIQUE_ID)
143 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
144 .SetDefaultValidity()
145 .AttestationChallenge("challenge")
146 .AttestationApplicationId("foo")
147 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
148 &key_blob, &key_characteristics);
149
150 // It is optional for Strong box to support DeviceUniqueAttestation.
151 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
152
153 ASSERT_EQ(ErrorCode::OK, result);
154
155 AuthorizationSetBuilder hw_enforced =
156 AuthorizationSetBuilder()
157 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
158 .Authorization(TAG_NO_AUTH_REQUIRED)
159 .RsaSigningKey(2048, 65537)
160 .Digest(Digest::SHA_2_256)
161 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
162 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
163 .Authorization(TAG_OS_VERSION, os_version())
164 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
165
166 // Any patchlevels attached to the key should also be present in the attestation extension.
167 AuthorizationSet auths;
168 for (const auto& entry : key_characteristics) {
169 auths.push_back(AuthorizationSet(entry.authorizations));
170 }
171 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
172 if (vendor_pl) {
173 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
174 }
175 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
176 if (boot_pl) {
177 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
178 }
179
180 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
181 }
182
183 /*
184 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
185 *
186 * Verifies that strongbox implementations of Rsa implements device unique
187 * attestation correctly, if implemented.
188 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestation)189 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
190 if (SecLevel() != SecurityLevel::STRONGBOX) {
191 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
192 }
193
194 vector<uint8_t> key_blob;
195 vector<KeyCharacteristics> key_characteristics;
196
197 auto result = GenerateKey(AuthorizationSetBuilder()
198 .Authorization(TAG_NO_AUTH_REQUIRED)
199 .EcdsaSigningKey(EcCurve::P_256)
200 .Digest(Digest::SHA_2_256)
201 .Authorization(TAG_INCLUDE_UNIQUE_ID)
202 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
203 .SetDefaultValidity()
204 .AttestationChallenge("challenge")
205 .AttestationApplicationId("foo")
206 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
207 &key_blob, &key_characteristics);
208
209 // It is optional for Strong box to support DeviceUniqueAttestation.
210 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
211 ASSERT_EQ(ErrorCode::OK, result);
212
213 AuthorizationSetBuilder hw_enforced =
214 AuthorizationSetBuilder()
215 .Authorization(TAG_NO_AUTH_REQUIRED)
216 .EcdsaSigningKey(EcCurve::P_256)
217 .Digest(Digest::SHA_2_256)
218 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
219 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
220 .Authorization(TAG_OS_VERSION, os_version())
221 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
222 // Any patchlevels attached to the key should also be present in the attestation extension.
223 AuthorizationSet auths;
224 for (const auto& entry : key_characteristics) {
225 auths.push_back(AuthorizationSet(entry.authorizations));
226 }
227 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
228 if (vendor_pl) {
229 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
230 }
231 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
232 if (boot_pl) {
233 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
234 }
235
236 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
237 }
238
239 /*
240 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID
241 *
242 * Verifies that device unique attestation can include IDs that do match the
243 * local device.
244 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestationID)245 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
246 if (SecLevel() != SecurityLevel::STRONGBOX) {
247 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
248 }
249
250 // Collection of valid attestation ID tags.
251 auto attestation_id_tags = AuthorizationSetBuilder();
252 // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
253 // to ro.product.brand
254 std::string prop_value =
255 ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
256 if (!prop_value.empty()) {
257 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
258 "ro.product.brand_for_attestation");
259 } else {
260 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
261 }
262 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
263 // Use ro.product.name_for_attestation property for attestation if it is present else fallback
264 // to ro.product.name
265 prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
266 if (!prop_value.empty()) {
267 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
268 "ro.product.name_for_attestation");
269 } else {
270 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
271 }
272 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
273 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
274 "ro.product.manufacturer");
275 // Use ro.product.model_for_attestation property for attestation if it is present else fallback
276 // to ro.product.model
277 prop_value =
278 ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
279 if (!prop_value.empty()) {
280 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
281 "ro.product.model_for_attestation");
282 } else {
283 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
284 }
285 vector<uint8_t> key_blob;
286 vector<KeyCharacteristics> key_characteristics;
287
288 for (const KeyParameter& tag : attestation_id_tags) {
289 SCOPED_TRACE(testing::Message() << "+tag-" << tag);
290 AuthorizationSetBuilder builder =
291 AuthorizationSetBuilder()
292 .Authorization(TAG_NO_AUTH_REQUIRED)
293 .EcdsaSigningKey(EcCurve::P_256)
294 .Digest(Digest::SHA_2_256)
295 .Authorization(TAG_INCLUDE_UNIQUE_ID)
296 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
297 .SetDefaultValidity()
298 .AttestationChallenge("challenge")
299 .AttestationApplicationId("foo")
300 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
301 builder.push_back(tag);
302 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
303
304 // It is optional for Strong box to support DeviceUniqueAttestation.
305 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
306 ASSERT_EQ(ErrorCode::OK, result);
307
308 AuthorizationSetBuilder hw_enforced =
309 AuthorizationSetBuilder()
310 .Authorization(TAG_NO_AUTH_REQUIRED)
311 .EcdsaSigningKey(EcCurve::P_256)
312 .Digest(Digest::SHA_2_256)
313 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
314 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
315 .Authorization(TAG_OS_VERSION, os_version())
316 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
317 // Expect the specified tag to be present in the attestation extension.
318 hw_enforced.push_back(tag);
319 // Any patchlevels attached to the key should also be present in the attestation extension.
320 AuthorizationSet auths;
321 for (const auto& entry : key_characteristics) {
322 auths.push_back(AuthorizationSet(entry.authorizations));
323 }
324 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
325 if (vendor_pl) {
326 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
327 }
328 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
329 if (boot_pl) {
330 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
331 }
332 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
333 }
334 }
335
336 /*
337 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID
338 *
339 * Verifies that device unique attestation rejects attempts to attest to IDs that
340 * don't match the local device.
341 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestationMismatchID)342 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
343 if (SecLevel() != SecurityLevel::STRONGBOX) {
344 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
345 }
346
347 // Collection of invalid attestation ID tags.
348 auto attestation_id_tags =
349 AuthorizationSetBuilder()
350 .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand")
351 .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device")
352 .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product")
353 .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial")
354 .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei")
355 .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
356 .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
357 .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
358 vector<uint8_t> key_blob;
359 vector<KeyCharacteristics> key_characteristics;
360
361 for (const KeyParameter& invalid_tag : attestation_id_tags) {
362 SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
363 AuthorizationSetBuilder builder =
364 AuthorizationSetBuilder()
365 .Authorization(TAG_NO_AUTH_REQUIRED)
366 .EcdsaSigningKey(EcCurve::P_256)
367 .Digest(Digest::SHA_2_256)
368 .Authorization(TAG_INCLUDE_UNIQUE_ID)
369 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
370 .SetDefaultValidity()
371 .AttestationChallenge("challenge")
372 .AttestationApplicationId("foo")
373 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
374 // Add the tag that doesn't match the local device's real ID.
375 builder.push_back(invalid_tag);
376 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
377
378 device_id_attestation_check_acceptable_error(invalid_tag.tag, result);
379 }
380 }
381
382 INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
383
384 } // namespace aidl::android::hardware::security::keymint::test
385