blob: 3cbffbfb63446e244a18f66961a219008688c870 [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);
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 */
66TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
David Drysdale513bf122021-10-06 11:53:13 +010067 if (SecLevel() == SecurityLevel::STRONGBOX) {
68 GTEST_SKIP() << "Test not applicable to StrongBox device";
69 }
Selene Huang531a72d2021-04-15 01:09:47 -070070
71 vector<uint8_t> key_blob;
72 vector<KeyCharacteristics> key_characteristics;
73
74 // Check RSA implementation
75 auto result = GenerateKey(AuthorizationSetBuilder()
76 .Authorization(TAG_NO_AUTH_REQUIRED)
77 .RsaSigningKey(2048, 65537)
78 .Digest(Digest::SHA_2_256)
79 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
80 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +000081 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -070082 .AttestationChallenge("challenge")
83 .AttestationApplicationId("foo")
84 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
85 &key_blob, &key_characteristics);
86
David Drysdaledb0dcf52021-05-18 11:43:31 +010087 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -070088}
89
90/*
91 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
92 *
93 * Verifies that non strongbox implementations do not implement Ecdsa device unique
94 * attestation.
95 */
96TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
David Drysdale513bf122021-10-06 11:53:13 +010097 if (SecLevel() == SecurityLevel::STRONGBOX) {
98 GTEST_SKIP() << "Test not applicable to StrongBox device";
99 }
Selene Huang531a72d2021-04-15 01:09:47 -0700100
101 vector<uint8_t> key_blob;
102 vector<KeyCharacteristics> key_characteristics;
103
104 // Check Ecdsa implementation
105 auto result = GenerateKey(AuthorizationSetBuilder()
106 .Authorization(TAG_NO_AUTH_REQUIRED)
107 .EcdsaSigningKey(EcCurve::P_256)
108 .Digest(Digest::SHA_2_256)
109 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000110 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700111 .AttestationChallenge("challenge")
112 .AttestationApplicationId("foo")
113 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
114 &key_blob, &key_characteristics);
115
David Drysdaledb0dcf52021-05-18 11:43:31 +0100116 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -0700117}
118
119/*
120 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
121 *
122 * Verifies that strongbox implementations of Rsa implements device unique
123 * attestation correctly, if implemented.
124 */
125TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100126 if (SecLevel() != SecurityLevel::STRONGBOX) {
127 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
128 }
Selene Huang531a72d2021-04-15 01:09:47 -0700129
130 vector<uint8_t> key_blob;
131 vector<KeyCharacteristics> key_characteristics;
132 int key_size = 2048;
133
134 auto result = GenerateKey(AuthorizationSetBuilder()
135 .Authorization(TAG_NO_AUTH_REQUIRED)
136 .RsaSigningKey(key_size, 65537)
137 .Digest(Digest::SHA_2_256)
138 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
139 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000140 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700141 .AttestationChallenge("challenge")
142 .AttestationApplicationId("foo")
143 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
144 &key_blob, &key_characteristics);
145
146 // It is optional for Strong box to support DeviceUniqueAttestation.
147 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
148
149 ASSERT_EQ(ErrorCode::OK, result);
150
David Drysdalea676c3b2021-06-14 14:46:02 +0100151 AuthorizationSetBuilder hw_enforced =
152 AuthorizationSetBuilder()
153 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
154 .Authorization(TAG_NO_AUTH_REQUIRED)
155 .RsaSigningKey(2048, 65537)
156 .Digest(Digest::SHA_2_256)
157 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
158 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
159 .Authorization(TAG_OS_VERSION, os_version())
160 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
Selene Huang531a72d2021-04-15 01:09:47 -0700161
David Drysdalea676c3b2021-06-14 14:46:02 +0100162 // Any patchlevels attached to the key should also be present in the attestation extension.
163 AuthorizationSet auths;
164 for (const auto& entry : key_characteristics) {
165 auths.push_back(AuthorizationSet(entry.authorizations));
166 }
167 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
168 if (vendor_pl) {
169 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
170 }
171 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
172 if (boot_pl) {
173 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
174 }
175
176 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
Selene Huang531a72d2021-04-15 01:09:47 -0700177}
178
179/*
180 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
181 *
182 * Verifies that strongbox implementations of Rsa implements device unique
183 * attestation correctly, if implemented.
184 */
185TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100186 if (SecLevel() != SecurityLevel::STRONGBOX) {
187 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
188 }
Selene Huang531a72d2021-04-15 01:09:47 -0700189
190 vector<uint8_t> key_blob;
191 vector<KeyCharacteristics> key_characteristics;
Selene Huang531a72d2021-04-15 01:09:47 -0700192
193 auto result = GenerateKey(AuthorizationSetBuilder()
194 .Authorization(TAG_NO_AUTH_REQUIRED)
David Drysdalea676c3b2021-06-14 14:46:02 +0100195 .EcdsaSigningKey(EcCurve::P_256)
Selene Huang531a72d2021-04-15 01:09:47 -0700196 .Digest(Digest::SHA_2_256)
197 .Authorization(TAG_INCLUDE_UNIQUE_ID)
David Drysdale13f2a402021-11-01 11:40:08 +0000198 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
Selene Huang531a72d2021-04-15 01:09:47 -0700199 .AttestationChallenge("challenge")
200 .AttestationApplicationId("foo")
201 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
202 &key_blob, &key_characteristics);
203
204 // It is optional for Strong box to support DeviceUniqueAttestation.
205 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
206 ASSERT_EQ(ErrorCode::OK, result);
207
David Drysdalea676c3b2021-06-14 14:46:02 +0100208 AuthorizationSetBuilder hw_enforced =
209 AuthorizationSetBuilder()
210 .Authorization(TAG_NO_AUTH_REQUIRED)
211 .EcdsaSigningKey(EcCurve::P_256)
212 .Digest(Digest::SHA_2_256)
213 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
214 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
215 .Authorization(TAG_OS_VERSION, os_version())
216 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
217 // Any patchlevels attached to the key should also be present in the attestation extension.
218 AuthorizationSet auths;
219 for (const auto& entry : key_characteristics) {
220 auths.push_back(AuthorizationSet(entry.authorizations));
221 }
222 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
223 if (vendor_pl) {
224 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
225 }
226 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
227 if (boot_pl) {
228 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
229 }
Selene Huang531a72d2021-04-15 01:09:47 -0700230
David Drysdalea676c3b2021-06-14 14:46:02 +0100231 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
232}
233
234/*
235 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID
236 *
237 * Verifies that device unique attestation can include IDs that do match the
238 * local device.
239 */
240TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
David Drysdale513bf122021-10-06 11:53:13 +0100241 if (SecLevel() != SecurityLevel::STRONGBOX) {
242 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
243 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100244
245 // Collection of valid attestation ID tags.
246 auto attestation_id_tags = AuthorizationSetBuilder();
247 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
248 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
249 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
250 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
251 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
252 "ro.product.manufacturer");
253 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
254 vector<uint8_t> key_blob;
255 vector<KeyCharacteristics> key_characteristics;
256
257 for (const KeyParameter& tag : attestation_id_tags) {
258 SCOPED_TRACE(testing::Message() << "+tag-" << tag);
David Drysdale13f2a402021-11-01 11:40:08 +0000259 AuthorizationSetBuilder builder =
260 AuthorizationSetBuilder()
261 .Authorization(TAG_NO_AUTH_REQUIRED)
262 .EcdsaSigningKey(EcCurve::P_256)
263 .Digest(Digest::SHA_2_256)
264 .Authorization(TAG_INCLUDE_UNIQUE_ID)
265 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
266 .AttestationChallenge("challenge")
267 .AttestationApplicationId("foo")
268 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
David Drysdalea676c3b2021-06-14 14:46:02 +0100269 builder.push_back(tag);
270 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
271
272 // It is optional for Strong box to support DeviceUniqueAttestation.
273 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
274 ASSERT_EQ(ErrorCode::OK, result);
275
276 AuthorizationSetBuilder hw_enforced =
277 AuthorizationSetBuilder()
278 .Authorization(TAG_NO_AUTH_REQUIRED)
279 .EcdsaSigningKey(EcCurve::P_256)
280 .Digest(Digest::SHA_2_256)
281 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
282 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
283 .Authorization(TAG_OS_VERSION, os_version())
284 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
285 // Expect the specified tag to be present in the attestation extension.
286 hw_enforced.push_back(tag);
287 // Any patchlevels attached to the key should also be present in the attestation extension.
288 AuthorizationSet auths;
289 for (const auto& entry : key_characteristics) {
290 auths.push_back(AuthorizationSet(entry.authorizations));
291 }
292 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
293 if (vendor_pl) {
294 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
295 }
296 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
297 if (boot_pl) {
298 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
299 }
300 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
301 }
302}
303
304/*
305 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID
306 *
307 * Verifies that device unique attestation rejects attempts to attest to IDs that
308 * don't match the local device.
309 */
310TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
David Drysdale513bf122021-10-06 11:53:13 +0100311 if (SecLevel() != SecurityLevel::STRONGBOX) {
312 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
313 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100314
315 // Collection of invalid attestation ID tags.
316 auto attestation_id_tags =
317 AuthorizationSetBuilder()
318 .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand")
319 .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device")
320 .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product")
321 .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial")
322 .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei")
323 .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
324 .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
325 .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
326 vector<uint8_t> key_blob;
327 vector<KeyCharacteristics> key_characteristics;
328
329 for (const KeyParameter& invalid_tag : attestation_id_tags) {
330 SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
David Drysdale13f2a402021-11-01 11:40:08 +0000331 AuthorizationSetBuilder builder =
332 AuthorizationSetBuilder()
333 .Authorization(TAG_NO_AUTH_REQUIRED)
334 .EcdsaSigningKey(EcCurve::P_256)
335 .Digest(Digest::SHA_2_256)
336 .Authorization(TAG_INCLUDE_UNIQUE_ID)
337 .Authorization(TAG_CREATION_DATETIME, 1619621648000)
338 .AttestationChallenge("challenge")
339 .AttestationApplicationId("foo")
340 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
David Drysdalea676c3b2021-06-14 14:46:02 +0100341 // Add the tag that doesn't match the local device's real ID.
342 builder.push_back(invalid_tag);
343 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
344
345 ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
346 }
Selene Huang531a72d2021-04-15 01:09:47 -0700347}
348
349INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
350
351} // namespace aidl::android::hardware::security::keymint::test