• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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