blob: d4bbd693b8b3b1be68f7d63ad2f7bd6e78d52fd4 [file] [log] [blame]
Selene Huang531a72d2021-04-15 01:09:47 -07001/*
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
26namespace aidl::android::hardware::security::keymint::test {
27
28class DeviceUniqueAttestationTest : public KeyMintAidlTestBase {
29 protected:
30 void CheckUniqueAttestationResults(const vector<uint8_t>& key_blob,
31 const vector<KeyCharacteristics>& key_characteristics,
David Drysdalea676c3b2021-06-14 14:46:02 +010032 const AuthorizationSet& hw_enforced) {
Selene Huang531a72d2021-04-15 01:09:47 -070033 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
Eran Messeri03d7a1a2021-07-06 12:07:57 +010043 // The device-unique attestation chain should contain exactly three certificates:
Eran Messeri90747ad2021-05-27 15:08:03 +010044 // * The leaf with the attestation extension.
Eran Messeri03d7a1a2021-07-06 12:07:57 +010045 // * 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));
Selene Huang531a72d2021-04-15 01:09:47 -070053
54 AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
David Drysdale7dff4fc2021-12-10 10:10:52 +000055 EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
56 hw_enforced, SecLevel(),
57 cert_chain_[0].encodedCertificate));
Selene Huang531a72d2021-04-15 01:09:47 -070058 }
59};
60
61/*
62 * DeviceUniqueAttestationTest.RsaNonStrongBoxUnimplemented
63 *
64 * Verifies that non strongbox implementations do not implement Rsa device unique
65 * attestation.
66 */
67TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
David Drysdale513bf122021-10-06 11:53:13 +010068 if (SecLevel() == SecurityLevel::STRONGBOX) {
69 GTEST_SKIP() << "Test not applicable to StrongBox device";
70 }
Selene Huang531a72d2021-04-15 01:09:47 -070071
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)
David Drysdale13f2a402021-11-01 11:40:08 +000082 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -070083 .AttestationChallenge("challenge")
84 .AttestationApplicationId("foo")
85 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
86 &key_blob, &key_characteristics);
87
David Drysdaledb0dcf52021-05-18 11:43:31 +010088 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -070089}
90
91/*
92 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
93 *
94 * Verifies that non strongbox implementations do not implement Ecdsa device unique
95 * attestation.
96 */
97TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
David Drysdale513bf122021-10-06 11:53:13 +010098 if (SecLevel() == SecurityLevel::STRONGBOX) {
99 GTEST_SKIP() << "Test not applicable to StrongBox device";
100 }
Selene Huang531a72d2021-04-15 01:09:47 -0700101
102 vector<uint8_t> key_blob;
103 vector<KeyCharacteristics> key_characteristics;
104
105 // Check Ecdsa implementation
106 auto result = GenerateKey(AuthorizationSetBuilder()
107 .Authorization(TAG_NO_AUTH_REQUIRED)
108 .EcdsaSigningKey(EcCurve::P_256)
109 .Digest(Digest::SHA_2_256)
110 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000111 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700112 .AttestationChallenge("challenge")
113 .AttestationApplicationId("foo")
114 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
115 &key_blob, &key_characteristics);
116
David Drysdaledb0dcf52021-05-18 11:43:31 +0100117 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -0700118}
119
120/*
121 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
122 *
123 * Verifies that strongbox implementations of Rsa implements device unique
124 * attestation correctly, if implemented.
125 */
126TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100127 if (SecLevel() != SecurityLevel::STRONGBOX) {
128 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
129 }
Selene Huang531a72d2021-04-15 01:09:47 -0700130
131 vector<uint8_t> key_blob;
132 vector<KeyCharacteristics> key_characteristics;
133 int key_size = 2048;
134
135 auto result = GenerateKey(AuthorizationSetBuilder()
136 .Authorization(TAG_NO_AUTH_REQUIRED)
137 .RsaSigningKey(key_size, 65537)
138 .Digest(Digest::SHA_2_256)
139 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
140 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000141 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700142 .AttestationChallenge("challenge")
143 .AttestationApplicationId("foo")
144 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
145 &key_blob, &key_characteristics);
146
147 // It is optional for Strong box to support DeviceUniqueAttestation.
148 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
149
150 ASSERT_EQ(ErrorCode::OK, result);
151
David Drysdalea676c3b2021-06-14 14:46:02 +0100152 AuthorizationSetBuilder hw_enforced =
153 AuthorizationSetBuilder()
154 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
155 .Authorization(TAG_NO_AUTH_REQUIRED)
156 .RsaSigningKey(2048, 65537)
157 .Digest(Digest::SHA_2_256)
158 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
159 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
160 .Authorization(TAG_OS_VERSION, os_version())
161 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
Selene Huang531a72d2021-04-15 01:09:47 -0700162
David Drysdalea676c3b2021-06-14 14:46:02 +0100163 // Any patchlevels attached to the key should also be present in the attestation extension.
164 AuthorizationSet auths;
165 for (const auto& entry : key_characteristics) {
166 auths.push_back(AuthorizationSet(entry.authorizations));
167 }
168 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
169 if (vendor_pl) {
170 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
171 }
172 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
173 if (boot_pl) {
174 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
175 }
176
177 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
Selene Huang531a72d2021-04-15 01:09:47 -0700178}
179
180/*
181 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
182 *
183 * Verifies that strongbox implementations of Rsa implements device unique
184 * attestation correctly, if implemented.
185 */
186TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100187 if (SecLevel() != SecurityLevel::STRONGBOX) {
188 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
189 }
Selene Huang531a72d2021-04-15 01:09:47 -0700190
191 vector<uint8_t> key_blob;
192 vector<KeyCharacteristics> key_characteristics;
Selene Huang531a72d2021-04-15 01:09:47 -0700193
194 auto result = GenerateKey(AuthorizationSetBuilder()
195 .Authorization(TAG_NO_AUTH_REQUIRED)
David Drysdalea676c3b2021-06-14 14:46:02 +0100196 .EcdsaSigningKey(EcCurve::P_256)
Selene Huang531a72d2021-04-15 01:09:47 -0700197 .Digest(Digest::SHA_2_256)
198 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000199 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700200 .AttestationChallenge("challenge")
201 .AttestationApplicationId("foo")
202 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
203 &key_blob, &key_characteristics);
204
205 // It is optional for Strong box to support DeviceUniqueAttestation.
206 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
207 ASSERT_EQ(ErrorCode::OK, result);
208
David Drysdalea676c3b2021-06-14 14:46:02 +0100209 AuthorizationSetBuilder hw_enforced =
210 AuthorizationSetBuilder()
211 .Authorization(TAG_NO_AUTH_REQUIRED)
212 .EcdsaSigningKey(EcCurve::P_256)
213 .Digest(Digest::SHA_2_256)
214 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
215 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
216 .Authorization(TAG_OS_VERSION, os_version())
217 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
218 // Any patchlevels attached to the key should also be present in the attestation extension.
219 AuthorizationSet auths;
220 for (const auto& entry : key_characteristics) {
221 auths.push_back(AuthorizationSet(entry.authorizations));
222 }
223 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
224 if (vendor_pl) {
225 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
226 }
227 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
228 if (boot_pl) {
229 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
230 }
Selene Huang531a72d2021-04-15 01:09:47 -0700231
David Drysdalea676c3b2021-06-14 14:46:02 +0100232 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
233}
234
235/*
236 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID
237 *
238 * Verifies that device unique attestation can include IDs that do match the
239 * local device.
240 */
241TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
David Drysdale513bf122021-10-06 11:53:13 +0100242 if (SecLevel() != SecurityLevel::STRONGBOX) {
243 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
244 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100245
246 // Collection of valid attestation ID tags.
247 auto attestation_id_tags = AuthorizationSetBuilder();
248 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
249 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
250 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
251 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
252 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
253 "ro.product.manufacturer");
254 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
255 vector<uint8_t> key_blob;
256 vector<KeyCharacteristics> key_characteristics;
257
258 for (const KeyParameter& tag : attestation_id_tags) {
259 SCOPED_TRACE(testing::Message() << "+tag-" << tag);
David Drysdale13f2a402021-11-01 11:40:08 +0000260 AuthorizationSetBuilder builder =
261 AuthorizationSetBuilder()
262 .Authorization(TAG_NO_AUTH_REQUIRED)
263 .EcdsaSigningKey(EcCurve::P_256)
264 .Digest(Digest::SHA_2_256)
265 .Authorization(TAG_INCLUDE_UNIQUE_ID)
266 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
267 .AttestationChallenge("challenge")
268 .AttestationApplicationId("foo")
269 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
David Drysdalea676c3b2021-06-14 14:46:02 +0100270 builder.push_back(tag);
271 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
272
273 // It is optional for Strong box to support DeviceUniqueAttestation.
274 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
275 ASSERT_EQ(ErrorCode::OK, result);
276
277 AuthorizationSetBuilder hw_enforced =
278 AuthorizationSetBuilder()
279 .Authorization(TAG_NO_AUTH_REQUIRED)
280 .EcdsaSigningKey(EcCurve::P_256)
281 .Digest(Digest::SHA_2_256)
282 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
283 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
284 .Authorization(TAG_OS_VERSION, os_version())
285 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
286 // Expect the specified tag to be present in the attestation extension.
287 hw_enforced.push_back(tag);
288 // Any patchlevels attached to the key should also be present in the attestation extension.
289 AuthorizationSet auths;
290 for (const auto& entry : key_characteristics) {
291 auths.push_back(AuthorizationSet(entry.authorizations));
292 }
293 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
294 if (vendor_pl) {
295 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
296 }
297 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
298 if (boot_pl) {
299 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
300 }
301 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
302 }
303}
304
305/*
306 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID
307 *
308 * Verifies that device unique attestation rejects attempts to attest to IDs that
309 * don't match the local device.
310 */
311TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
David Drysdale513bf122021-10-06 11:53:13 +0100312 if (SecLevel() != SecurityLevel::STRONGBOX) {
313 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
314 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100315
316 // Collection of invalid attestation ID tags.
317 auto attestation_id_tags =
318 AuthorizationSetBuilder()
319 .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand")
320 .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device")
321 .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product")
322 .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial")
323 .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei")
324 .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
325 .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
326 .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
327 vector<uint8_t> key_blob;
328 vector<KeyCharacteristics> key_characteristics;
329
330 for (const KeyParameter& invalid_tag : attestation_id_tags) {
331 SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
David Drysdale13f2a402021-11-01 11:40:08 +0000332 AuthorizationSetBuilder builder =
333 AuthorizationSetBuilder()
334 .Authorization(TAG_NO_AUTH_REQUIRED)
335 .EcdsaSigningKey(EcCurve::P_256)
336 .Digest(Digest::SHA_2_256)
337 .Authorization(TAG_INCLUDE_UNIQUE_ID)
338 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
339 .AttestationChallenge("challenge")
340 .AttestationApplicationId("foo")
341 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
David Drysdalea676c3b2021-06-14 14:46:02 +0100342 // Add the tag that doesn't match the local device's real ID.
343 builder.push_back(invalid_tag);
344 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
345
346 ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
347 }
Selene Huang531a72d2021-04-15 01:09:47 -0700348}
349
350INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
351
352} // namespace aidl::android::hardware::security::keymint::test