1 /*
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_2_se_provisioning_test"
18
19 #include <map>
20 #include <memory>
21 #include <vector>
22
23 #include <android-base/logging.h>
24 #include <android/binder_manager.h>
25
26 #include <cppbor_parse.h>
27 #include <keymaster/cppcose/cppcose.h>
28 #include <keymint_support/key_param_output.h>
29
30 #include "KeyMintAidlTestBase.h"
31
32 namespace aidl::android::hardware::security::keymint::test {
33
34 using std::array;
35 using std::map;
36 using std::shared_ptr;
37 using std::vector;
38
39 constexpr int kRoTVersion1 = 40001;
40
41 class SecureElementProvisioningTest : public testing::Test {
42 protected:
SetUpTestSuite()43 static void SetUpTestSuite() {
44 auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
45 for (auto& param : params) {
46 ASSERT_TRUE(AServiceManager_isDeclared(param.c_str()))
47 << "IKeyMintDevice instance " << param << " found but not declared.";
48 ::ndk::SpAIBinder binder(AServiceManager_waitForService(param.c_str()));
49 auto keymint = IKeyMintDevice::fromBinder(binder);
50 ASSERT_NE(keymint, nullptr) << "Failed to get IKeyMintDevice instance " << param;
51
52 KeyMintHardwareInfo info;
53 ASSERT_TRUE(keymint->getHardwareInfo(&info).isOk());
54 ASSERT_EQ(keymints_.count(info.securityLevel), 0)
55 << "There must be exactly one IKeyMintDevice with security level "
56 << info.securityLevel;
57
58 keymints_[info.securityLevel] = std::move(keymint);
59 }
60 }
61
validateMacedRootOfTrust(const vector<uint8_t> & rootOfTrust)62 void validateMacedRootOfTrust(const vector<uint8_t>& rootOfTrust) {
63 SCOPED_TRACE(testing::Message() << "RoT: " << bin2hex(rootOfTrust));
64
65 const auto [macItem, macEndPos, macErrMsg] = cppbor::parse(rootOfTrust);
66 ASSERT_TRUE(macItem) << "Root of trust parsing failed: " << macErrMsg;
67 ASSERT_EQ(macItem->semanticTagCount(), 1);
68 ASSERT_EQ(macItem->semanticTag(0), cppcose::kCoseMac0SemanticTag);
69 ASSERT_TRUE(macItem->asArray());
70 ASSERT_EQ(macItem->asArray()->size(), cppcose::kCoseMac0EntryCount);
71
72 const auto& protectedItem = macItem->asArray()->get(cppcose::kCoseMac0ProtectedParams);
73 ASSERT_TRUE(protectedItem);
74 ASSERT_TRUE(protectedItem->asBstr());
75 const auto [protMap, protEndPos, protErrMsg] = cppbor::parse(protectedItem->asBstr());
76 ASSERT_TRUE(protMap);
77 ASSERT_TRUE(protMap->asMap());
78 ASSERT_EQ(protMap->asMap()->size(), 1);
79
80 const auto& algorithm = protMap->asMap()->get(cppcose::ALGORITHM);
81 ASSERT_TRUE(algorithm);
82 ASSERT_TRUE(algorithm->asInt());
83 ASSERT_EQ(algorithm->asInt()->value(), cppcose::HMAC_256);
84
85 const auto& unprotItem = macItem->asArray()->get(cppcose::kCoseMac0UnprotectedParams);
86 ASSERT_TRUE(unprotItem);
87 ASSERT_TRUE(unprotItem->asMap());
88 ASSERT_EQ(unprotItem->asMap()->size(), 0);
89
90 const auto& payload = macItem->asArray()->get(cppcose::kCoseMac0Payload);
91 ASSERT_TRUE(payload);
92 ASSERT_TRUE(payload->asBstr());
93 validateRootOfTrust(payload->asBstr()->value());
94
95 const auto& tag = macItem->asArray()->get(cppcose::kCoseMac0Tag);
96 ASSERT_TRUE(tag);
97 ASSERT_TRUE(tag->asBstr());
98 ASSERT_EQ(tag->asBstr()->value().size(), 32);
99 // Cannot validate tag correctness. Only the secure side has the necessary key.
100 }
101
validateRootOfTrust(const vector<uint8_t> & payload)102 void validateRootOfTrust(const vector<uint8_t>& payload) {
103 SCOPED_TRACE(testing::Message() << "RoT payload: " << bin2hex(payload));
104
105 const auto [rot, rotPos, rotErrMsg] = cppbor::parse(payload);
106 ASSERT_TRUE(rot);
107 ASSERT_EQ(rot->semanticTagCount(), 1);
108 ASSERT_EQ(rot->semanticTag(), kRoTVersion1);
109 ASSERT_TRUE(rot->asArray());
110 ASSERT_EQ(rot->asArray()->size(), 5);
111
112 size_t pos = 0;
113
114 const auto& vbKey = rot->asArray()->get(pos++);
115 ASSERT_TRUE(vbKey);
116 ASSERT_TRUE(vbKey->asBstr());
117 if (get_vsr_api_level() >= __ANDROID_API_V__) {
118 // The attestation should contain the SHA-256 hash of the verified boot
119 // key. However, this not was checked for earlier versions of the KeyMint
120 // HAL so only be strict for VSR-V and above.
121 ASSERT_LE(vbKey->asBstr()->value().size(), 32);
122 }
123
124 const auto& deviceLocked = rot->asArray()->get(pos++);
125 ASSERT_TRUE(deviceLocked);
126 ASSERT_TRUE(deviceLocked->asBool());
127
128 const auto& verifiedBootState = rot->asArray()->get(pos++);
129 ASSERT_TRUE(verifiedBootState);
130 ASSERT_TRUE(verifiedBootState->asInt());
131
132 const auto& verifiedBootHash = rot->asArray()->get(pos++);
133 ASSERT_TRUE(verifiedBootHash);
134 ASSERT_TRUE(verifiedBootHash->asBstr());
135
136 const auto& bootPatchLevel = rot->asArray()->get(pos++);
137 ASSERT_TRUE(bootPatchLevel);
138 ASSERT_TRUE(bootPatchLevel->asInt());
139
140 verify_root_of_trust(vbKey->asBstr()->value(), deviceLocked->asBool()->value(),
141 static_cast<VerifiedBoot>(verifiedBootState->asInt()->value()),
142 verifiedBootHash->asBstr()->value());
143 }
144
AidlVersion(shared_ptr<IKeyMintDevice> keymint)145 int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
146 int32_t version = 0;
147 auto status = keymint->getInterfaceVersion(&version);
148 if (!status.isOk()) {
149 ADD_FAILURE() << "Failed to determine interface version";
150 }
151 return version;
152 }
153
154 static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
155 };
156
157 map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
158
TEST_F(SecureElementProvisioningTest,ValidConfigurations)159 TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
160 if (keymints_.empty()) {
161 GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
162 }
163 // TEE is required
164 ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
165 // StrongBox is optional
166 ASSERT_LE(keymints_.count(SecurityLevel::STRONGBOX), 1);
167 }
168
TEST_F(SecureElementProvisioningTest,TeeOnly)169 TEST_F(SecureElementProvisioningTest, TeeOnly) {
170 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
171 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
172 }
173 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
174 // Execute the test only for KeyMint version >= 2.
175 if (AidlVersion(tee) < 2) {
176 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
177 }
178
179 array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
180 array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
181
182 vector<uint8_t> rootOfTrust1;
183 Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
184 ASSERT_TRUE(result.isOk()) << "getRootOfTrust returned " << result.getServiceSpecificError();
185 validateMacedRootOfTrust(rootOfTrust1);
186
187 vector<uint8_t> rootOfTrust2;
188 result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
189 ASSERT_TRUE(result.isOk());
190 validateMacedRootOfTrust(rootOfTrust2);
191 ASSERT_NE(rootOfTrust1, rootOfTrust2);
192
193 vector<uint8_t> rootOfTrust3;
194 result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
195 ASSERT_TRUE(result.isOk());
196 ASSERT_EQ(rootOfTrust1, rootOfTrust3);
197 }
198
TEST_F(SecureElementProvisioningTest,TeeDoesNotImplementStrongBoxMethods)199 TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
200 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
201 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
202 }
203 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
204 // Execute the test only for KeyMint version >= 2.
205 if (AidlVersion(tee) < 2) {
206 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
207 }
208
209 array<uint8_t, 16> challenge;
210 Status result = tee->getRootOfTrustChallenge(&challenge);
211 ASSERT_FALSE(result.isOk());
212 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
213 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
214
215 result = tee->sendRootOfTrust({});
216 ASSERT_FALSE(result.isOk());
217 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
218 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
219 }
220
TEST_F(SecureElementProvisioningTest,StrongBoxDoesNotImplementTeeMethods)221 TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
222 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
223 // Need a StrongBox to provision.
224 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
225 }
226 // Execute the test only for KeyMint version >= 2.
227 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
228 if (AidlVersion(sb) < 2) {
229 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
230 }
231
232 vector<uint8_t> rootOfTrust;
233 Status result = sb->getRootOfTrust({}, &rootOfTrust);
234 ASSERT_FALSE(result.isOk());
235 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
236 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
237 }
238
TEST_F(SecureElementProvisioningTest,UnimplementedTest)239 TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
240 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
241 // Need a StrongBox to provision.
242 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
243 }
244 // Execute the test only for KeyMint version >= 2.
245 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
246 if (AidlVersion(sb) < 2) {
247 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
248 }
249
250 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
251 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
252 }
253 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
254 if (AidlVersion(tee) < 2) {
255 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
256 }
257
258 array<uint8_t, 16> challenge;
259 Status result = sb->getRootOfTrustChallenge(&challenge);
260 if (!result.isOk()) {
261 // Strongbox does not have to implement this feature if it has uses an alternative mechanism
262 // to provision the root of trust. In that case it MUST return UNIMPLEMENTED, both from
263 // getRootOfTrustChallenge() and from sendRootOfTrust().
264 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
265 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
266 ErrorCode::UNIMPLEMENTED);
267
268 result = sb->sendRootOfTrust({});
269 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
270 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
271 ErrorCode::UNIMPLEMENTED);
272
273 SUCCEED() << "This Strongbox implementation does not use late root of trust delivery.";
274 return;
275 }
276 }
277
TEST_F(SecureElementProvisioningTest,ChallengeQualityTest)278 TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
279 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
280 // Need a StrongBox to provision.
281 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
282 }
283 // Execute the test only for KeyMint version >= 2.
284 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
285 if (AidlVersion(sb) < 2) {
286 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
287 }
288
289 array<uint8_t, 16> challenge1;
290 Status result = sb->getRootOfTrustChallenge(&challenge1);
291 if (!result.isOk()) return;
292
293 array<uint8_t, 16> challenge2;
294 result = sb->getRootOfTrustChallenge(&challenge2);
295 ASSERT_TRUE(result.isOk());
296 ASSERT_NE(challenge1, challenge2);
297
298 // TODO: When we add entropy testing in other relevant places in these tests, add it here, too,
299 // to verify that challenges appear to have adequate entropy.
300 }
301
TEST_F(SecureElementProvisioningTest,ProvisioningTest)302 TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
303 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
304 // Need a StrongBox to provision.
305 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
306 }
307 // Execute the test only for KeyMint version >= 2.
308 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
309 if (AidlVersion(sb) < 2) {
310 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
311 }
312
313 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
314 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
315 }
316 // Execute the test only for KeyMint version >= 2.
317 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
318 if (AidlVersion(tee) < 2) {
319 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
320 }
321
322 array<uint8_t, 16> challenge;
323 Status result = sb->getRootOfTrustChallenge(&challenge);
324 if (!result.isOk()) return;
325
326 vector<uint8_t> rootOfTrust;
327 result = tee->getRootOfTrust(challenge, &rootOfTrust);
328 ASSERT_TRUE(result.isOk());
329
330 validateMacedRootOfTrust(rootOfTrust);
331
332 result = sb->sendRootOfTrust(rootOfTrust);
333 ASSERT_TRUE(result.isOk());
334
335 // Sending again must fail, because a new challenge is required.
336 result = sb->sendRootOfTrust(rootOfTrust);
337 ASSERT_FALSE(result.isOk());
338 }
339
TEST_F(SecureElementProvisioningTest,InvalidProvisioningTest)340 TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
341 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
342 // Need a StrongBox to provision.
343 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
344 }
345 // Execute the test only for KeyMint version >= 2.
346 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
347 if (AidlVersion(sb) < 2) {
348 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
349 }
350
351 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
352 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
353 }
354 // Execute the test only for KeyMint version >= 2.
355 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
356 if (AidlVersion(tee) < 2) {
357 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
358 }
359
360 array<uint8_t, 16> challenge;
361 Status result = sb->getRootOfTrustChallenge(&challenge);
362 if (!result.isOk()) return;
363
364 result = sb->sendRootOfTrust({});
365 ASSERT_FALSE(result.isOk());
366 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
367 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
368 ErrorCode::VERIFICATION_FAILED);
369
370 vector<uint8_t> rootOfTrust;
371 result = tee->getRootOfTrust(challenge, &rootOfTrust);
372 ASSERT_TRUE(result.isOk());
373
374 validateMacedRootOfTrust(rootOfTrust);
375
376 vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
377 corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
378 result = sb->sendRootOfTrust(corruptedRootOfTrust);
379 ASSERT_FALSE(result.isOk());
380 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
381 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
382 ErrorCode::VERIFICATION_FAILED);
383
384 // Now try the correct RoT
385 result = sb->sendRootOfTrust(rootOfTrust);
386 ASSERT_TRUE(result.isOk());
387 }
388
389 } // namespace aidl::android::hardware::security::keymint::test
390