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