blob: e630f7008efb6b2669e3d97a40613d40fca5f2da [file] [log] [blame]
Shawn Willden0cc617c2022-02-11 12:51:53 -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_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
32namespace aidl::android::hardware::security::keymint::test {
33
34using std::array;
35using std::map;
36using std::shared_ptr;
37using std::vector;
38
39class SecureElementProvisioningTest : public testing::Test {
40 protected:
David Drysdale795f7582022-03-01 13:52:15 +000041 static void SetUpTestSuite() {
Shawn Willden0cc617c2022-02-11 12:51:53 -070042 auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
43 for (auto& param : params) {
44 ASSERT_TRUE(AServiceManager_isDeclared(param.c_str()))
45 << "IKeyMintDevice instance " << param << " found but not declared.";
46 ::ndk::SpAIBinder binder(AServiceManager_waitForService(param.c_str()));
47 auto keymint = IKeyMintDevice::fromBinder(binder);
48 ASSERT_NE(keymint, nullptr) << "Failed to get IKeyMintDevice instance " << param;
49
50 KeyMintHardwareInfo info;
51 ASSERT_TRUE(keymint->getHardwareInfo(&info).isOk());
52 ASSERT_EQ(keymints_.count(info.securityLevel), 0)
53 << "There must be exactly one IKeyMintDevice with security level "
54 << info.securityLevel;
55
56 keymints_[info.securityLevel] = std::move(keymint);
57 }
58 }
59
Subrahmanyaman44189842022-04-01 08:13:02 +000060 int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
61 int32_t version = 0;
62 auto status = keymint->getInterfaceVersion(&version);
63 if (!status.isOk()) {
64 ADD_FAILURE() << "Failed to determine interface version";
65 }
66 return version;
67 }
68
Shawn Willden0cc617c2022-02-11 12:51:53 -070069 static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
70};
71
72map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
73
74TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
David Drysdale1585fdc2022-03-08 08:07:02 +000075 if (keymints_.empty()) {
76 GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
77 }
Shawn Willden0cc617c2022-02-11 12:51:53 -070078 // TEE is required
79 ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
80 // StrongBox is optional
81 ASSERT_LE(keymints_.count(SecurityLevel::STRONGBOX), 1);
82}
83
84TEST_F(SecureElementProvisioningTest, TeeOnly) {
Subrahmanyaman44189842022-04-01 08:13:02 +000085 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
86 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
David Drysdale1585fdc2022-03-08 08:07:02 +000087 }
Shawn Willden0cc617c2022-02-11 12:51:53 -070088 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +000089 // Execute the test only for KeyMint version >= 2.
90 if (AidlVersion(tee) < 2) {
91 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
92 }
Shawn Willden0cc617c2022-02-11 12:51:53 -070093
94 array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
95 array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
96
97 vector<uint8_t> rootOfTrust1;
98 Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
99
100 // TODO: Remove the next line to require TEEs to succeed.
101 if (!result.isOk()) return;
102
103 ASSERT_TRUE(result.isOk());
104
105 // TODO: Parse and validate rootOfTrust1 here
106
107 vector<uint8_t> rootOfTrust2;
108 result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
109 ASSERT_TRUE(result.isOk());
110
111 // TODO: Parse and validate rootOfTrust2 here
112
113 ASSERT_NE(rootOfTrust1, rootOfTrust2);
114
115 vector<uint8_t> rootOfTrust3;
116 result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
117 ASSERT_TRUE(result.isOk());
118
119 ASSERT_EQ(rootOfTrust1, rootOfTrust3);
120
121 // TODO: Parse and validate rootOfTrust3 here
122}
123
124TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
Subrahmanyaman44189842022-04-01 08:13:02 +0000125 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
126 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
David Drysdale1585fdc2022-03-08 08:07:02 +0000127 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700128 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000129 // Execute the test only for KeyMint version >= 2.
130 if (AidlVersion(tee) < 2) {
131 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
132 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700133
134 array<uint8_t, 16> challenge;
135 Status result = tee->getRootOfTrustChallenge(&challenge);
136 ASSERT_FALSE(result.isOk());
137 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
138 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
139
140 result = tee->sendRootOfTrust({});
141 ASSERT_FALSE(result.isOk());
142 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
143 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
144}
145
146TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000147 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
148 // Need a StrongBox to provision.
149 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
150 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000151 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700152 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000153 if (AidlVersion(sb) < 2) {
154 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
155 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700156
157 vector<uint8_t> rootOfTrust;
158 Status result = sb->getRootOfTrust({}, &rootOfTrust);
159 ASSERT_FALSE(result.isOk());
160 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
161 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
162}
163
164TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000165 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
166 // Need a StrongBox to provision.
167 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
168 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000169 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700170 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000171 if (AidlVersion(sb) < 2) {
172 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
173 }
174
175 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
176 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
177 }
178 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
179 if (AidlVersion(tee) < 2) {
180 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
181 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700182
183 array<uint8_t, 16> challenge;
184 Status result = sb->getRootOfTrustChallenge(&challenge);
185 if (!result.isOk()) {
186 // Strongbox does not have to implement this feature if it has uses an alternative mechanism
187 // to provision the root of trust. In that case it MUST return UNIMPLEMENTED, both from
188 // getRootOfTrustChallenge() and from sendRootOfTrust().
189 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
190 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
191 ErrorCode::UNIMPLEMENTED);
192
193 result = sb->sendRootOfTrust({});
194 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
195 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
196 ErrorCode::UNIMPLEMENTED);
197
198 SUCCEED() << "This Strongbox implementation does not use late root of trust delivery.";
199 return;
200 }
201}
202
203TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000204 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
205 // Need a StrongBox to provision.
206 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
207 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000208 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700209 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000210 if (AidlVersion(sb) < 2) {
211 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
212 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700213
214 array<uint8_t, 16> challenge1;
215 Status result = sb->getRootOfTrustChallenge(&challenge1);
216 if (!result.isOk()) return;
217
218 array<uint8_t, 16> challenge2;
219 result = sb->getRootOfTrustChallenge(&challenge2);
220 ASSERT_TRUE(result.isOk());
221 ASSERT_NE(challenge1, challenge2);
222
223 // TODO: When we add entropy testing in other relevant places in these tests, add it here, too,
224 // to verify that challenges appear to have adequate entropy.
225}
226
227TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000228 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
229 // Need a StrongBox to provision.
230 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
231 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000232 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700233 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000234 if (AidlVersion(sb) < 2) {
235 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
236 }
237
238 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
239 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
240 }
241 // Execute the test only for KeyMint version >= 2.
242 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
243 if (AidlVersion(tee) < 2) {
244 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
245 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700246
247 array<uint8_t, 16> challenge;
248 Status result = sb->getRootOfTrustChallenge(&challenge);
249 if (!result.isOk()) return;
250
251 vector<uint8_t> rootOfTrust;
252 result = tee->getRootOfTrust(challenge, &rootOfTrust);
253 ASSERT_TRUE(result.isOk());
254
255 // TODO: Verify COSE_Mac0 structure and content here.
256
257 result = sb->sendRootOfTrust(rootOfTrust);
258 ASSERT_TRUE(result.isOk());
259
260 // Sending again must fail, because a new challenge is required.
261 result = sb->sendRootOfTrust(rootOfTrust);
262 ASSERT_FALSE(result.isOk());
263}
264
265TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000266 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
267 // Need a StrongBox to provision.
268 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
269 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000270 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700271 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000272 if (AidlVersion(sb) < 2) {
273 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
274 }
275
276 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
277 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
278 }
279 // Execute the test only for KeyMint version >= 2.
280 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
281 if (AidlVersion(tee) < 2) {
282 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
283 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700284
285 array<uint8_t, 16> challenge;
286 Status result = sb->getRootOfTrustChallenge(&challenge);
287 if (!result.isOk()) return;
288
289 result = sb->sendRootOfTrust({});
290 ASSERT_FALSE(result.isOk());
291 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
292 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
293 ErrorCode::VERIFICATION_FAILED);
294
295 vector<uint8_t> rootOfTrust;
296 result = tee->getRootOfTrust(challenge, &rootOfTrust);
297 ASSERT_TRUE(result.isOk());
298
299 vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
300 corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
301 result = sb->sendRootOfTrust(corruptedRootOfTrust);
302 ASSERT_FALSE(result.isOk());
303 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
304 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
305 ErrorCode::VERIFICATION_FAILED);
306
307 // Now try the correct RoT
308 result = sb->sendRootOfTrust(rootOfTrust);
309 ASSERT_TRUE(result.isOk());
310}
311
312} // namespace aidl::android::hardware::security::keymint::test