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("challenge", "foo", sw_enforced, hw_enforced,
56 SecLevel(), cert_chain_[0].encodedCertificate));
57 }
58 };
59
60 /*
61 * DeviceUniqueAttestationTest.RsaNonStrongBoxUnimplemented
62 *
63 * Verifies that non strongbox implementations do not implement Rsa device unique
64 * attestation.
65 */
TEST_P(DeviceUniqueAttestationTest,RsaNonStrongBoxUnimplemented)66 TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
67 if (SecLevel() == SecurityLevel::STRONGBOX) return;
68
69 vector<uint8_t> key_blob;
70 vector<KeyCharacteristics> key_characteristics;
71
72 // Check RSA implementation
73 auto result = GenerateKey(AuthorizationSetBuilder()
74 .Authorization(TAG_NO_AUTH_REQUIRED)
75 .RsaSigningKey(2048, 65537)
76 .Digest(Digest::SHA_2_256)
77 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
78 .Authorization(TAG_INCLUDE_UNIQUE_ID)
79 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
80 .AttestationChallenge("challenge")
81 .AttestationApplicationId("foo")
82 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
83 &key_blob, &key_characteristics);
84
85 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
86 }
87
88 /*
89 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
90 *
91 * Verifies that non strongbox implementations do not implement Ecdsa device unique
92 * attestation.
93 */
TEST_P(DeviceUniqueAttestationTest,EcdsaNonStrongBoxUnimplemented)94 TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
95 if (SecLevel() == SecurityLevel::STRONGBOX) return;
96
97 vector<uint8_t> key_blob;
98 vector<KeyCharacteristics> key_characteristics;
99
100 // Check Ecdsa implementation
101 auto result = GenerateKey(AuthorizationSetBuilder()
102 .Authorization(TAG_NO_AUTH_REQUIRED)
103 .EcdsaSigningKey(EcCurve::P_256)
104 .Digest(Digest::SHA_2_256)
105 .Authorization(TAG_INCLUDE_UNIQUE_ID)
106 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
107 .AttestationChallenge("challenge")
108 .AttestationApplicationId("foo")
109 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
110 &key_blob, &key_characteristics);
111
112 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
113 }
114
115 /*
116 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
117 *
118 * Verifies that strongbox implementations of Rsa implements device unique
119 * attestation correctly, if implemented.
120 */
TEST_P(DeviceUniqueAttestationTest,RsaDeviceUniqueAttestation)121 TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
122 if (SecLevel() != SecurityLevel::STRONGBOX) return;
123
124 vector<uint8_t> key_blob;
125 vector<KeyCharacteristics> key_characteristics;
126 int key_size = 2048;
127
128 auto result = GenerateKey(AuthorizationSetBuilder()
129 .Authorization(TAG_NO_AUTH_REQUIRED)
130 .RsaSigningKey(key_size, 65537)
131 .Digest(Digest::SHA_2_256)
132 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
133 .Authorization(TAG_INCLUDE_UNIQUE_ID)
134 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
135 .AttestationChallenge("challenge")
136 .AttestationApplicationId("foo")
137 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
138 &key_blob, &key_characteristics);
139
140 // It is optional for Strong box to support DeviceUniqueAttestation.
141 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
142
143 ASSERT_EQ(ErrorCode::OK, result);
144
145 AuthorizationSetBuilder hw_enforced =
146 AuthorizationSetBuilder()
147 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
148 .Authorization(TAG_NO_AUTH_REQUIRED)
149 .RsaSigningKey(2048, 65537)
150 .Digest(Digest::SHA_2_256)
151 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
152 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
153 .Authorization(TAG_OS_VERSION, os_version())
154 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
155
156 // Any patchlevels attached to the key should also be present in the attestation extension.
157 AuthorizationSet auths;
158 for (const auto& entry : key_characteristics) {
159 auths.push_back(AuthorizationSet(entry.authorizations));
160 }
161 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
162 if (vendor_pl) {
163 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
164 }
165 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
166 if (boot_pl) {
167 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
168 }
169
170 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
171 }
172
173 /*
174 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
175 *
176 * Verifies that strongbox implementations of Rsa implements device unique
177 * attestation correctly, if implemented.
178 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestation)179 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
180 if (SecLevel() != SecurityLevel::STRONGBOX) return;
181
182 vector<uint8_t> key_blob;
183 vector<KeyCharacteristics> key_characteristics;
184
185 auto result = GenerateKey(AuthorizationSetBuilder()
186 .Authorization(TAG_NO_AUTH_REQUIRED)
187 .EcdsaSigningKey(EcCurve::P_256)
188 .Digest(Digest::SHA_2_256)
189 .Authorization(TAG_INCLUDE_UNIQUE_ID)
190 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
191 .AttestationChallenge("challenge")
192 .AttestationApplicationId("foo")
193 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
194 &key_blob, &key_characteristics);
195
196 // It is optional for Strong box to support DeviceUniqueAttestation.
197 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
198 ASSERT_EQ(ErrorCode::OK, result);
199
200 AuthorizationSetBuilder hw_enforced =
201 AuthorizationSetBuilder()
202 .Authorization(TAG_NO_AUTH_REQUIRED)
203 .EcdsaSigningKey(EcCurve::P_256)
204 .Digest(Digest::SHA_2_256)
205 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
206 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
207 .Authorization(TAG_OS_VERSION, os_version())
208 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
209 // Any patchlevels attached to the key should also be present in the attestation extension.
210 AuthorizationSet auths;
211 for (const auto& entry : key_characteristics) {
212 auths.push_back(AuthorizationSet(entry.authorizations));
213 }
214 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
215 if (vendor_pl) {
216 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
217 }
218 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
219 if (boot_pl) {
220 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
221 }
222
223 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
224 }
225
226 /*
227 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID
228 *
229 * Verifies that device unique attestation can include IDs that do match the
230 * local device.
231 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestationID)232 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
233 if (SecLevel() != SecurityLevel::STRONGBOX) return;
234
235 // Collection of valid attestation ID tags.
236 auto attestation_id_tags = AuthorizationSetBuilder();
237 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
238 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
239 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
240 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
241 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
242 "ro.product.manufacturer");
243 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
244 vector<uint8_t> key_blob;
245 vector<KeyCharacteristics> key_characteristics;
246
247 for (const KeyParameter& tag : attestation_id_tags) {
248 SCOPED_TRACE(testing::Message() << "+tag-" << tag);
249 AuthorizationSetBuilder builder =
250 AuthorizationSetBuilder()
251 .Authorization(TAG_NO_AUTH_REQUIRED)
252 .EcdsaSigningKey(EcCurve::P_256)
253 .Digest(Digest::SHA_2_256)
254 .Authorization(TAG_INCLUDE_UNIQUE_ID)
255 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
256 .AttestationChallenge("challenge")
257 .AttestationApplicationId("foo")
258 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
259 builder.push_back(tag);
260 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
261
262 // It is optional for Strong box to support DeviceUniqueAttestation.
263 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
264 ASSERT_EQ(ErrorCode::OK, result);
265
266 AuthorizationSetBuilder hw_enforced =
267 AuthorizationSetBuilder()
268 .Authorization(TAG_NO_AUTH_REQUIRED)
269 .EcdsaSigningKey(EcCurve::P_256)
270 .Digest(Digest::SHA_2_256)
271 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
272 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
273 .Authorization(TAG_OS_VERSION, os_version())
274 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
275 // Expect the specified tag to be present in the attestation extension.
276 hw_enforced.push_back(tag);
277 // Any patchlevels attached to the key should also be present in the attestation extension.
278 AuthorizationSet auths;
279 for (const auto& entry : key_characteristics) {
280 auths.push_back(AuthorizationSet(entry.authorizations));
281 }
282 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
283 if (vendor_pl) {
284 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
285 }
286 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
287 if (boot_pl) {
288 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
289 }
290 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
291 }
292 }
293
294 /*
295 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID
296 *
297 * Verifies that device unique attestation rejects attempts to attest to IDs that
298 * don't match the local device.
299 */
TEST_P(DeviceUniqueAttestationTest,EcdsaDeviceUniqueAttestationMismatchID)300 TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
301 if (SecLevel() != SecurityLevel::STRONGBOX) return;
302
303 // Collection of invalid attestation ID tags.
304 auto attestation_id_tags =
305 AuthorizationSetBuilder()
306 .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand")
307 .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device")
308 .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product")
309 .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial")
310 .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei")
311 .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
312 .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
313 .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
314 vector<uint8_t> key_blob;
315 vector<KeyCharacteristics> key_characteristics;
316
317 for (const KeyParameter& invalid_tag : attestation_id_tags) {
318 SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
319 AuthorizationSetBuilder builder =
320 AuthorizationSetBuilder()
321 .Authorization(TAG_NO_AUTH_REQUIRED)
322 .EcdsaSigningKey(EcCurve::P_256)
323 .Digest(Digest::SHA_2_256)
324 .Authorization(TAG_INCLUDE_UNIQUE_ID)
325 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
326 .AttestationChallenge("challenge")
327 .AttestationApplicationId("foo")
328 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
329 // Add the tag that doesn't match the local device's real ID.
330 builder.push_back(invalid_tag);
331 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
332
333 ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
334 }
335 }
336
337 INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
338
339 } // namespace aidl::android::hardware::security::keymint::test
340