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