blob: 6f2f189ab77eb856fe1dabe0e3c7ba1b33b12b0b [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)
Selene Huang531a72d2021-04-15 01:09:47 -070081 .AttestationChallenge("challenge")
82 .AttestationApplicationId("foo")
83 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
84 &key_blob, &key_characteristics);
85
David Drysdaledb0dcf52021-05-18 11:43:31 +010086 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -070087}
88
89/*
90 * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
91 *
92 * Verifies that non strongbox implementations do not implement Ecdsa device unique
93 * attestation.
94 */
95TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
David Drysdale513bf122021-10-06 11:53:13 +010096 if (SecLevel() == SecurityLevel::STRONGBOX) {
97 GTEST_SKIP() << "Test not applicable to StrongBox device";
98 }
Selene Huang531a72d2021-04-15 01:09:47 -070099
100 vector<uint8_t> key_blob;
101 vector<KeyCharacteristics> key_characteristics;
102
103 // Check Ecdsa implementation
104 auto result = GenerateKey(AuthorizationSetBuilder()
105 .Authorization(TAG_NO_AUTH_REQUIRED)
106 .EcdsaSigningKey(EcCurve::P_256)
107 .Digest(Digest::SHA_2_256)
108 .Authorization(TAG_INCLUDE_UNIQUE_ID)
109 .AttestationChallenge("challenge")
110 .AttestationApplicationId("foo")
111 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
112 &key_blob, &key_characteristics);
113
David Drysdaledb0dcf52021-05-18 11:43:31 +0100114 ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
Selene Huang531a72d2021-04-15 01:09:47 -0700115}
116
117/*
118 * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
119 *
120 * Verifies that strongbox implementations of Rsa implements device unique
121 * attestation correctly, if implemented.
122 */
123TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100124 if (SecLevel() != SecurityLevel::STRONGBOX) {
125 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
126 }
Selene Huang531a72d2021-04-15 01:09:47 -0700127
128 vector<uint8_t> key_blob;
129 vector<KeyCharacteristics> key_characteristics;
130 int key_size = 2048;
131
132 auto result = GenerateKey(AuthorizationSetBuilder()
133 .Authorization(TAG_NO_AUTH_REQUIRED)
134 .RsaSigningKey(key_size, 65537)
135 .Digest(Digest::SHA_2_256)
136 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
137 .Authorization(TAG_INCLUDE_UNIQUE_ID)
Selene Huang531a72d2021-04-15 01:09:47 -0700138 .AttestationChallenge("challenge")
139 .AttestationApplicationId("foo")
140 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
141 &key_blob, &key_characteristics);
142
143 // It is optional for Strong box to support DeviceUniqueAttestation.
144 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
145
146 ASSERT_EQ(ErrorCode::OK, result);
147
David Drysdalea676c3b2021-06-14 14:46:02 +0100148 AuthorizationSetBuilder hw_enforced =
149 AuthorizationSetBuilder()
150 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
151 .Authorization(TAG_NO_AUTH_REQUIRED)
152 .RsaSigningKey(2048, 65537)
153 .Digest(Digest::SHA_2_256)
154 .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
155 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
156 .Authorization(TAG_OS_VERSION, os_version())
157 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
Selene Huang531a72d2021-04-15 01:09:47 -0700158
David Drysdalea676c3b2021-06-14 14:46:02 +0100159 // Any patchlevels attached to the key should also be present in the attestation extension.
160 AuthorizationSet auths;
161 for (const auto& entry : key_characteristics) {
162 auths.push_back(AuthorizationSet(entry.authorizations));
163 }
164 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
165 if (vendor_pl) {
166 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
167 }
168 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
169 if (boot_pl) {
170 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
171 }
172
173 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
Selene Huang531a72d2021-04-15 01:09:47 -0700174}
175
176/*
177 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
178 *
179 * Verifies that strongbox implementations of Rsa implements device unique
180 * attestation correctly, if implemented.
181 */
182TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
David Drysdale513bf122021-10-06 11:53:13 +0100183 if (SecLevel() != SecurityLevel::STRONGBOX) {
184 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
185 }
Selene Huang531a72d2021-04-15 01:09:47 -0700186
187 vector<uint8_t> key_blob;
188 vector<KeyCharacteristics> key_characteristics;
Selene Huang531a72d2021-04-15 01:09:47 -0700189
190 auto result = GenerateKey(AuthorizationSetBuilder()
191 .Authorization(TAG_NO_AUTH_REQUIRED)
David Drysdalea676c3b2021-06-14 14:46:02 +0100192 .EcdsaSigningKey(EcCurve::P_256)
Selene Huang531a72d2021-04-15 01:09:47 -0700193 .Digest(Digest::SHA_2_256)
194 .Authorization(TAG_INCLUDE_UNIQUE_ID)
195 .AttestationChallenge("challenge")
196 .AttestationApplicationId("foo")
197 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
198 &key_blob, &key_characteristics);
199
200 // It is optional for Strong box to support DeviceUniqueAttestation.
201 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
202 ASSERT_EQ(ErrorCode::OK, result);
203
David Drysdalea676c3b2021-06-14 14:46:02 +0100204 AuthorizationSetBuilder hw_enforced =
205 AuthorizationSetBuilder()
206 .Authorization(TAG_NO_AUTH_REQUIRED)
207 .EcdsaSigningKey(EcCurve::P_256)
208 .Digest(Digest::SHA_2_256)
209 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
210 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
211 .Authorization(TAG_OS_VERSION, os_version())
212 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
213 // Any patchlevels attached to the key should also be present in the attestation extension.
214 AuthorizationSet auths;
215 for (const auto& entry : key_characteristics) {
216 auths.push_back(AuthorizationSet(entry.authorizations));
217 }
218 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
219 if (vendor_pl) {
220 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
221 }
222 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
223 if (boot_pl) {
224 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
225 }
Selene Huang531a72d2021-04-15 01:09:47 -0700226
David Drysdalea676c3b2021-06-14 14:46:02 +0100227 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
228}
229
230/*
231 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID
232 *
233 * Verifies that device unique attestation can include IDs that do match the
234 * local device.
235 */
236TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
David Drysdale513bf122021-10-06 11:53:13 +0100237 if (SecLevel() != SecurityLevel::STRONGBOX) {
238 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
239 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100240
241 // Collection of valid attestation ID tags.
242 auto attestation_id_tags = AuthorizationSetBuilder();
243 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
244 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
245 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
246 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
247 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
248 "ro.product.manufacturer");
249 add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
250 vector<uint8_t> key_blob;
251 vector<KeyCharacteristics> key_characteristics;
252
253 for (const KeyParameter& tag : attestation_id_tags) {
254 SCOPED_TRACE(testing::Message() << "+tag-" << tag);
255 AuthorizationSetBuilder builder = AuthorizationSetBuilder()
256 .Authorization(TAG_NO_AUTH_REQUIRED)
257 .EcdsaSigningKey(EcCurve::P_256)
258 .Digest(Digest::SHA_2_256)
259 .Authorization(TAG_INCLUDE_UNIQUE_ID)
260 .AttestationChallenge("challenge")
261 .AttestationApplicationId("foo")
262 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
263 builder.push_back(tag);
264 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
265
266 // It is optional for Strong box to support DeviceUniqueAttestation.
267 if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
268 ASSERT_EQ(ErrorCode::OK, result);
269
270 AuthorizationSetBuilder hw_enforced =
271 AuthorizationSetBuilder()
272 .Authorization(TAG_NO_AUTH_REQUIRED)
273 .EcdsaSigningKey(EcCurve::P_256)
274 .Digest(Digest::SHA_2_256)
275 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
276 .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
277 .Authorization(TAG_OS_VERSION, os_version())
278 .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
279 // Expect the specified tag to be present in the attestation extension.
280 hw_enforced.push_back(tag);
281 // Any patchlevels attached to the key should also be present in the attestation extension.
282 AuthorizationSet auths;
283 for (const auto& entry : key_characteristics) {
284 auths.push_back(AuthorizationSet(entry.authorizations));
285 }
286 auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
287 if (vendor_pl) {
288 hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl);
289 }
290 auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
291 if (boot_pl) {
292 hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl);
293 }
294 CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced);
295 }
296}
297
298/*
299 * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID
300 *
301 * Verifies that device unique attestation rejects attempts to attest to IDs that
302 * don't match the local device.
303 */
304TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
David Drysdale513bf122021-10-06 11:53:13 +0100305 if (SecLevel() != SecurityLevel::STRONGBOX) {
306 GTEST_SKIP() << "Test not applicable to non-StrongBox device";
307 }
David Drysdalea676c3b2021-06-14 14:46:02 +0100308
309 // Collection of invalid attestation ID tags.
310 auto attestation_id_tags =
311 AuthorizationSetBuilder()
312 .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand")
313 .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device")
314 .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product")
315 .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial")
316 .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei")
317 .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
318 .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
319 .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
320 vector<uint8_t> key_blob;
321 vector<KeyCharacteristics> key_characteristics;
322
323 for (const KeyParameter& invalid_tag : attestation_id_tags) {
324 SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag);
325 AuthorizationSetBuilder builder = AuthorizationSetBuilder()
326 .Authorization(TAG_NO_AUTH_REQUIRED)
327 .EcdsaSigningKey(EcCurve::P_256)
328 .Digest(Digest::SHA_2_256)
329 .Authorization(TAG_INCLUDE_UNIQUE_ID)
330 .AttestationChallenge("challenge")
331 .AttestationApplicationId("foo")
332 .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
333 // Add the tag that doesn't match the local device's real ID.
334 builder.push_back(invalid_tag);
335 auto result = GenerateKey(builder, &key_blob, &key_characteristics);
336
337 ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG);
338 }
Selene Huang531a72d2021-04-15 01:09:47 -0700339}
340
341INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
342
343} // namespace aidl::android::hardware::security::keymint::test