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 Verified Boot key field should be exactly 32 bytes since it
119             // contains the SHA-256 hash of the key on locked devices or 32 bytes
120             // of zeroes on unlocked devices. This wasn't checked for earlier
121             // versions of the KeyMint HAL, so only only be strict for VSR-16+.
122             ASSERT_EQ(vbKey->asBstr()->value().size(), 32);
123         } else if (get_vsr_api_level() == __ANDROID_API_V__) {
124             // The Verified Boot key field should be:
125             //   - Exactly 32 bytes on locked devices since it should contain
126             //     the SHA-256 hash of the key, or
127             //   - Up to 32 bytes of zeroes on unlocked devices (behaviour on
128             //     unlocked devices isn't specified in the HAL interface
129             //     specification).
130             // Thus, we can't check for strict equality in case unlocked devices
131             // report values with less than 32 bytes. This wasn't checked for
132             // earlier versions of the KeyMint HAL, so only check on VSR-15.
133             ASSERT_LE(vbKey->asBstr()->value().size(), 32);
134         }
135 
136         const auto& deviceLocked = rot->asArray()->get(pos++);
137         ASSERT_TRUE(deviceLocked);
138         ASSERT_TRUE(deviceLocked->asBool());
139 
140         const auto& verifiedBootState = rot->asArray()->get(pos++);
141         ASSERT_TRUE(verifiedBootState);
142         ASSERT_TRUE(verifiedBootState->asInt());
143 
144         const auto& verifiedBootHash = rot->asArray()->get(pos++);
145         ASSERT_TRUE(verifiedBootHash);
146         ASSERT_TRUE(verifiedBootHash->asBstr());
147 
148         const auto& bootPatchLevel = rot->asArray()->get(pos++);
149         ASSERT_TRUE(bootPatchLevel);
150         ASSERT_TRUE(bootPatchLevel->asInt());
151 
152         verify_root_of_trust(vbKey->asBstr()->value(), deviceLocked->asBool()->value(),
153                              static_cast<VerifiedBoot>(verifiedBootState->asInt()->value()),
154                              verifiedBootHash->asBstr()->value());
155     }
156 
AidlVersion(shared_ptr<IKeyMintDevice> keymint)157     int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
158         int32_t version = 0;
159         auto status = keymint->getInterfaceVersion(&version);
160         if (!status.isOk()) {
161             ADD_FAILURE() << "Failed to determine interface version";
162         }
163         return version;
164     }
165 
166     static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
167 };
168 
169 map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
170 
TEST_F(SecureElementProvisioningTest,ValidConfigurations)171 TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
172     if (keymints_.empty()) {
173         GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
174     }
175     // TEE is required
176     ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
177     // StrongBox is optional
178     ASSERT_LE(keymints_.count(SecurityLevel::STRONGBOX), 1);
179 }
180 
TEST_F(SecureElementProvisioningTest,TeeOnly)181 TEST_F(SecureElementProvisioningTest, TeeOnly) {
182     if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
183         GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
184     }
185     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
186     // Execute the test only for KeyMint version >= 2.
187     if (AidlVersion(tee) < 2) {
188         GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
189     }
190 
191     array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
192     array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
193 
194     vector<uint8_t> rootOfTrust1;
195     Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
196     ASSERT_TRUE(result.isOk()) << "getRootOfTrust returned " << result.getServiceSpecificError();
197     validateMacedRootOfTrust(rootOfTrust1);
198 
199     vector<uint8_t> rootOfTrust2;
200     result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
201     ASSERT_TRUE(result.isOk());
202     validateMacedRootOfTrust(rootOfTrust2);
203     ASSERT_NE(rootOfTrust1, rootOfTrust2);
204 
205     vector<uint8_t> rootOfTrust3;
206     result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
207     ASSERT_TRUE(result.isOk());
208     ASSERT_EQ(rootOfTrust1, rootOfTrust3);
209 }
210 
TEST_F(SecureElementProvisioningTest,TeeDoesNotImplementStrongBoxMethods)211 TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
212     if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
213         GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
214     }
215     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
216     // Execute the test only for KeyMint version >= 2.
217     if (AidlVersion(tee) < 2) {
218         GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
219     }
220 
221     array<uint8_t, 16> challenge;
222     Status result = tee->getRootOfTrustChallenge(&challenge);
223     ASSERT_FALSE(result.isOk());
224     ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
225     ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
226 
227     result = tee->sendRootOfTrust({});
228     ASSERT_FALSE(result.isOk());
229     ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
230     ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
231 }
232 
TEST_F(SecureElementProvisioningTest,StrongBoxDoesNotImplementTeeMethods)233 TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
234     if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
235         // Need a StrongBox to provision.
236         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
237     }
238     // Execute the test only for KeyMint version >= 2.
239     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
240     if (AidlVersion(sb) < 2) {
241         GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
242     }
243 
244     vector<uint8_t> rootOfTrust;
245     Status result = sb->getRootOfTrust({}, &rootOfTrust);
246     ASSERT_FALSE(result.isOk());
247     ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
248     ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
249 }
250 
TEST_F(SecureElementProvisioningTest,UnimplementedTest)251 TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
252     if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
253         // Need a StrongBox to provision.
254         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
255     }
256     // Execute the test only for KeyMint version >= 2.
257     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
258     if (AidlVersion(sb) < 2) {
259         GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
260     }
261 
262     if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
263         GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
264     }
265     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
266     if (AidlVersion(tee) < 2) {
267         GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
268     }
269 
270     array<uint8_t, 16> challenge;
271     Status result = sb->getRootOfTrustChallenge(&challenge);
272     if (!result.isOk()) {
273         // Strongbox does not have to implement this feature if it has uses an alternative mechanism
274         // to provision the root of trust.  In that case it MUST return UNIMPLEMENTED, both from
275         // getRootOfTrustChallenge() and from sendRootOfTrust().
276         ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
277         ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
278                   ErrorCode::UNIMPLEMENTED);
279 
280         result = sb->sendRootOfTrust({});
281         ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
282         ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
283                   ErrorCode::UNIMPLEMENTED);
284 
285         SUCCEED() << "This Strongbox implementation does not use late root of trust delivery.";
286         return;
287     }
288 }
289 
TEST_F(SecureElementProvisioningTest,ChallengeQualityTest)290 TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
291     if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
292         // Need a StrongBox to provision.
293         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
294     }
295     // Execute the test only for KeyMint version >= 2.
296     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
297     if (AidlVersion(sb) < 2) {
298         GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
299     }
300 
301     array<uint8_t, 16> challenge1;
302     Status result = sb->getRootOfTrustChallenge(&challenge1);
303     if (!result.isOk()) return;
304 
305     array<uint8_t, 16> challenge2;
306     result = sb->getRootOfTrustChallenge(&challenge2);
307     ASSERT_TRUE(result.isOk());
308     ASSERT_NE(challenge1, challenge2);
309 
310     // TODO: When we add entropy testing in other relevant places in these tests, add it here, too,
311     // to verify that challenges appear to have adequate entropy.
312 }
313 
TEST_F(SecureElementProvisioningTest,ProvisioningTest)314 TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
315     if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
316         // Need a StrongBox to provision.
317         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
318     }
319     // Execute the test only for KeyMint version >= 2.
320     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
321     if (AidlVersion(sb) < 2) {
322         GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
323     }
324 
325     if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
326         GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
327     }
328     // Execute the test only for KeyMint version >= 2.
329     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
330     if (AidlVersion(tee) < 2) {
331         GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
332     }
333 
334     array<uint8_t, 16> challenge;
335     Status result = sb->getRootOfTrustChallenge(&challenge);
336     if (!result.isOk()) return;
337 
338     vector<uint8_t> rootOfTrust;
339     result = tee->getRootOfTrust(challenge, &rootOfTrust);
340     ASSERT_TRUE(result.isOk());
341 
342     validateMacedRootOfTrust(rootOfTrust);
343 
344     result = sb->sendRootOfTrust(rootOfTrust);
345     ASSERT_TRUE(result.isOk());
346 
347     // Sending again must fail, because a new challenge is required.
348     result = sb->sendRootOfTrust(rootOfTrust);
349     ASSERT_FALSE(result.isOk());
350 }
351 
TEST_F(SecureElementProvisioningTest,InvalidProvisioningTest)352 TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
353     if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
354         // Need a StrongBox to provision.
355         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
356     }
357     // Execute the test only for KeyMint version >= 2.
358     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
359     if (AidlVersion(sb) < 2) {
360         GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
361     }
362 
363     if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
364         GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
365     }
366     // Execute the test only for KeyMint version >= 2.
367     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
368     if (AidlVersion(tee) < 2) {
369         GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
370     }
371 
372     array<uint8_t, 16> challenge;
373     Status result = sb->getRootOfTrustChallenge(&challenge);
374     if (!result.isOk()) return;
375 
376     result = sb->sendRootOfTrust({});
377     ASSERT_FALSE(result.isOk());
378     ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
379     ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
380               ErrorCode::VERIFICATION_FAILED);
381 
382     vector<uint8_t> rootOfTrust;
383     result = tee->getRootOfTrust(challenge, &rootOfTrust);
384     ASSERT_TRUE(result.isOk());
385 
386     validateMacedRootOfTrust(rootOfTrust);
387 
388     vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
389     corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
390     result = sb->sendRootOfTrust(corruptedRootOfTrust);
391     ASSERT_FALSE(result.isOk());
392     ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
393     ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
394               ErrorCode::VERIFICATION_FAILED);
395 
396     // Now try the correct RoT
397     result = sb->sendRootOfTrust(rootOfTrust);
398     ASSERT_TRUE(result.isOk());
399 }
400 
401 }  // namespace aidl::android::hardware::security::keymint::test
402