blob: c9a156d3e6988a945b82b15935ec4ed64da7ffa5 [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
Shawn Willden4315e132022-03-20 12:49:46 -060039constexpr int kRoTVersion1 = 40001;
40
Shawn Willden0cc617c2022-02-11 12:51:53 -070041class SecureElementProvisioningTest : public testing::Test {
42 protected:
David Drysdale795f7582022-03-01 13:52:15 +000043 static void SetUpTestSuite() {
Shawn Willden0cc617c2022-02-11 12:51:53 -070044 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
Shawn Willden4315e132022-03-20 12:49:46 -060062 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
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
118 const auto& deviceLocked = rot->asArray()->get(pos++);
119 ASSERT_TRUE(deviceLocked);
120 ASSERT_TRUE(deviceLocked->asBool());
121
122 const auto& verifiedBootState = rot->asArray()->get(pos++);
123 ASSERT_TRUE(verifiedBootState);
124 ASSERT_TRUE(verifiedBootState->asInt());
125
126 const auto& verifiedBootHash = rot->asArray()->get(pos++);
127 ASSERT_TRUE(verifiedBootHash);
128 ASSERT_TRUE(verifiedBootHash->asBstr());
129
130 const auto& bootPatchLevel = rot->asArray()->get(pos++);
131 ASSERT_TRUE(bootPatchLevel);
132 ASSERT_TRUE(bootPatchLevel->asInt());
133
134 verify_root_of_trust(vbKey->asBstr()->value(), deviceLocked->asBool()->value(),
135 static_cast<VerifiedBoot>(verifiedBootState->asInt()->value()),
136 verifiedBootHash->asBstr()->value());
137 }
138
Subrahmanyaman44189842022-04-01 08:13:02 +0000139 int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
140 int32_t version = 0;
141 auto status = keymint->getInterfaceVersion(&version);
142 if (!status.isOk()) {
143 ADD_FAILURE() << "Failed to determine interface version";
144 }
145 return version;
146 }
147
Shawn Willden0cc617c2022-02-11 12:51:53 -0700148 static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
149};
150
151map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
152
153TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000154 if (keymints_.empty()) {
155 GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
156 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700157 // TEE is required
158 ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
159 // StrongBox is optional
160 ASSERT_LE(keymints_.count(SecurityLevel::STRONGBOX), 1);
161}
162
163TEST_F(SecureElementProvisioningTest, TeeOnly) {
Subrahmanyaman44189842022-04-01 08:13:02 +0000164 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
165 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
David Drysdale1585fdc2022-03-08 08:07:02 +0000166 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700167 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000168 // Execute the test only for KeyMint version >= 2.
169 if (AidlVersion(tee) < 2) {
170 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
171 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700172
173 array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
174 array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
175
176 vector<uint8_t> rootOfTrust1;
177 Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
Shawn Willden4315e132022-03-20 12:49:46 -0600178 ASSERT_TRUE(result.isOk()) << "getRootOfTrust returned " << result.getServiceSpecificError();
179 validateMacedRootOfTrust(rootOfTrust1);
Shawn Willden0cc617c2022-02-11 12:51:53 -0700180
181 vector<uint8_t> rootOfTrust2;
182 result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
183 ASSERT_TRUE(result.isOk());
Shawn Willden4315e132022-03-20 12:49:46 -0600184 validateMacedRootOfTrust(rootOfTrust2);
Shawn Willden0cc617c2022-02-11 12:51:53 -0700185 ASSERT_NE(rootOfTrust1, rootOfTrust2);
186
187 vector<uint8_t> rootOfTrust3;
188 result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
189 ASSERT_TRUE(result.isOk());
Shawn Willden0cc617c2022-02-11 12:51:53 -0700190 ASSERT_EQ(rootOfTrust1, rootOfTrust3);
Shawn Willden0cc617c2022-02-11 12:51:53 -0700191}
192
193TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
Subrahmanyaman44189842022-04-01 08:13:02 +0000194 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
195 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
David Drysdale1585fdc2022-03-08 08:07:02 +0000196 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700197 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000198 // Execute the test only for KeyMint version >= 2.
199 if (AidlVersion(tee) < 2) {
200 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
201 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700202
203 array<uint8_t, 16> challenge;
204 Status result = tee->getRootOfTrustChallenge(&challenge);
205 ASSERT_FALSE(result.isOk());
206 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
207 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
208
209 result = tee->sendRootOfTrust({});
210 ASSERT_FALSE(result.isOk());
211 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
212 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
213}
214
215TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000216 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
217 // Need a StrongBox to provision.
218 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
219 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000220 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700221 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000222 if (AidlVersion(sb) < 2) {
223 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
224 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700225
226 vector<uint8_t> rootOfTrust;
227 Status result = sb->getRootOfTrust({}, &rootOfTrust);
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
233TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000234 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 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000238 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700239 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000240 if (AidlVersion(sb) < 2) {
241 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
242 }
243
244 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
245 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
246 }
247 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
248 if (AidlVersion(tee) < 2) {
249 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
250 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700251
252 array<uint8_t, 16> challenge;
253 Status result = sb->getRootOfTrustChallenge(&challenge);
254 if (!result.isOk()) {
255 // Strongbox does not have to implement this feature if it has uses an alternative mechanism
256 // to provision the root of trust. In that case it MUST return UNIMPLEMENTED, both from
257 // getRootOfTrustChallenge() and from sendRootOfTrust().
258 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
259 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
260 ErrorCode::UNIMPLEMENTED);
261
262 result = sb->sendRootOfTrust({});
263 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
264 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
265 ErrorCode::UNIMPLEMENTED);
266
267 SUCCEED() << "This Strongbox implementation does not use late root of trust delivery.";
268 return;
269 }
270}
271
272TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000273 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
274 // Need a StrongBox to provision.
275 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
276 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000277 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700278 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000279 if (AidlVersion(sb) < 2) {
280 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
281 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700282
283 array<uint8_t, 16> challenge1;
284 Status result = sb->getRootOfTrustChallenge(&challenge1);
285 if (!result.isOk()) return;
286
287 array<uint8_t, 16> challenge2;
288 result = sb->getRootOfTrustChallenge(&challenge2);
289 ASSERT_TRUE(result.isOk());
290 ASSERT_NE(challenge1, challenge2);
291
292 // TODO: When we add entropy testing in other relevant places in these tests, add it here, too,
293 // to verify that challenges appear to have adequate entropy.
294}
295
296TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000297 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
298 // Need a StrongBox to provision.
299 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
300 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000301 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700302 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000303 if (AidlVersion(sb) < 2) {
304 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
305 }
306
307 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
308 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
309 }
310 // Execute the test only for KeyMint version >= 2.
311 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
312 if (AidlVersion(tee) < 2) {
313 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
314 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700315
316 array<uint8_t, 16> challenge;
317 Status result = sb->getRootOfTrustChallenge(&challenge);
318 if (!result.isOk()) return;
319
320 vector<uint8_t> rootOfTrust;
321 result = tee->getRootOfTrust(challenge, &rootOfTrust);
322 ASSERT_TRUE(result.isOk());
323
Shawn Willden4315e132022-03-20 12:49:46 -0600324 validateMacedRootOfTrust(rootOfTrust);
Shawn Willden0cc617c2022-02-11 12:51:53 -0700325
326 result = sb->sendRootOfTrust(rootOfTrust);
327 ASSERT_TRUE(result.isOk());
328
329 // Sending again must fail, because a new challenge is required.
330 result = sb->sendRootOfTrust(rootOfTrust);
331 ASSERT_FALSE(result.isOk());
332}
333
334TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
David Drysdale1585fdc2022-03-08 08:07:02 +0000335 if (keymints_.count(SecurityLevel::STRONGBOX) == 0) {
336 // Need a StrongBox to provision.
337 GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
338 }
Subrahmanyaman44189842022-04-01 08:13:02 +0000339 // Execute the test only for KeyMint version >= 2.
Shawn Willden0cc617c2022-02-11 12:51:53 -0700340 auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
Subrahmanyaman44189842022-04-01 08:13:02 +0000341 if (AidlVersion(sb) < 2) {
342 GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
343 }
344
345 if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
346 GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
347 }
348 // Execute the test only for KeyMint version >= 2.
349 auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
350 if (AidlVersion(tee) < 2) {
351 GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
352 }
Shawn Willden0cc617c2022-02-11 12:51:53 -0700353
354 array<uint8_t, 16> challenge;
355 Status result = sb->getRootOfTrustChallenge(&challenge);
356 if (!result.isOk()) return;
357
358 result = sb->sendRootOfTrust({});
359 ASSERT_FALSE(result.isOk());
360 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
361 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
362 ErrorCode::VERIFICATION_FAILED);
363
364 vector<uint8_t> rootOfTrust;
365 result = tee->getRootOfTrust(challenge, &rootOfTrust);
366 ASSERT_TRUE(result.isOk());
367
Shawn Willden4315e132022-03-20 12:49:46 -0600368 validateMacedRootOfTrust(rootOfTrust);
369
Shawn Willden0cc617c2022-02-11 12:51:53 -0700370 vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
371 corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
372 result = sb->sendRootOfTrust(corruptedRootOfTrust);
373 ASSERT_FALSE(result.isOk());
374 ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
375 ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
376 ErrorCode::VERIFICATION_FAILED);
377
378 // Now try the correct RoT
379 result = sb->sendRootOfTrust(rootOfTrust);
380 ASSERT_TRUE(result.isOk());
381}
382
383} // namespace aidl::android::hardware::security::keymint::test