1 /*
2 * Copyright (C) 2022 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 "gatekeeper_aidl_hal_test"
18
19 #include <inttypes.h>
20 #include <unistd.h>
21
22 #include <algorithm>
23 #include <cmath>
24 #include <string>
25 #include <vector>
26
27 #include <aidl/Gtest.h>
28 #include <aidl/Vintf.h>
29 #include <aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.h>
30 #include <aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.h>
31 #include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
32 #include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
33 #include <android-base/endian.h>
34 #include <android/binder_manager.h>
35 #include <android/binder_process.h>
36 #include <hardware/hw_auth_token.h>
37
38 #include <log/log.h>
39
40 using aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
41 using aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
42 using aidl::android::hardware::gatekeeper::IGatekeeper;
43 using aidl::android::hardware::security::keymint::HardwareAuthToken;
44 using Status = ::ndk::ScopedAStatus;
45
46 struct GatekeeperRequest {
47 uint32_t uid;
48 uint64_t challenge;
49 std::vector<uint8_t> curPwdHandle;
50 std::vector<uint8_t> curPwd;
51 std::vector<uint8_t> newPwd;
GatekeeperRequestGatekeeperRequest52 GatekeeperRequest() : uid(0), challenge(0) {}
53 };
54
55 // ASSERT_* macros generate return "void" internally
56 // we have to use EXPECT_* if we return anything but "void"
verifyAuthToken(GatekeeperVerifyResponse & rsp)57 static void verifyAuthToken(GatekeeperVerifyResponse& rsp) {
58 uint32_t auth_type = static_cast<uint32_t>(rsp.hardwareAuthToken.authenticatorType);
59 uint64_t auth_tstamp = static_cast<uint64_t>(rsp.hardwareAuthToken.timestamp.milliSeconds);
60
61 EXPECT_EQ(HW_AUTH_PASSWORD, auth_type);
62 EXPECT_NE(UINT64_C(~0), auth_tstamp);
63 ALOGI("Authenticator ID: %016" PRIX64, rsp.hardwareAuthToken.authenticatorId);
64 EXPECT_NE(UINT32_C(0), rsp.hardwareAuthToken.userId);
65 }
66
67 // The main test class for Gatekeeper AIDL HAL.
68 class GatekeeperAidlTest : public ::testing::TestWithParam<std::string> {
69 protected:
setUid(uint32_t uid)70 void setUid(uint32_t uid) { uid_ = uid; }
71
doEnroll(GatekeeperRequest & req,GatekeeperEnrollResponse & rsp)72 Status doEnroll(GatekeeperRequest& req, GatekeeperEnrollResponse& rsp) {
73 Status ret;
74 while (true) {
75 ret = gatekeeper_->enroll(uid_, req.curPwdHandle, req.curPwd, req.newPwd, &rsp);
76 if (ret.isOk()) break;
77 if (getReturnStatusCode(ret) != IGatekeeper::ERROR_RETRY_TIMEOUT) break;
78 ALOGI("%s: got retry code; retrying in 1 sec", __func__);
79 sleep(1);
80 }
81 return ret;
82 }
83
doVerify(GatekeeperRequest & req,GatekeeperVerifyResponse & rsp)84 Status doVerify(GatekeeperRequest& req, GatekeeperVerifyResponse& rsp) {
85 Status ret;
86 while (true) {
87 ret = gatekeeper_->verify(uid_, req.challenge, req.curPwdHandle, req.newPwd, &rsp);
88 if (ret.isOk()) break;
89 if (getReturnStatusCode(ret) != IGatekeeper::ERROR_RETRY_TIMEOUT) break;
90 ALOGI("%s: got retry code; retrying in 1 sec", __func__);
91 sleep(1);
92 }
93 return ret;
94 }
95
doDeleteUser()96 Status doDeleteUser() { return gatekeeper_->deleteUser(uid_); }
97
doDeleteAllUsers()98 Status doDeleteAllUsers() { return gatekeeper_->deleteAllUsers(); }
99
generatePassword(std::vector<uint8_t> & password,uint8_t seed)100 void generatePassword(std::vector<uint8_t>& password, uint8_t seed) {
101 password.resize(16);
102 memset(password.data(), seed, password.size());
103 }
104
checkEnroll(GatekeeperEnrollResponse & rsp,Status & ret,bool expectSuccess)105 void checkEnroll(GatekeeperEnrollResponse& rsp, Status& ret, bool expectSuccess) {
106 if (expectSuccess) {
107 EXPECT_TRUE(ret.isOk());
108 EXPECT_EQ(IGatekeeper::STATUS_OK, rsp.statusCode);
109 EXPECT_NE(nullptr, rsp.data.data());
110 EXPECT_GT(rsp.data.size(), UINT32_C(0));
111 EXPECT_NE(UINT32_C(0), rsp.secureUserId);
112 } else {
113 EXPECT_EQ(IGatekeeper::ERROR_GENERAL_FAILURE, getReturnStatusCode(ret));
114 EXPECT_EQ(UINT32_C(0), rsp.data.size());
115 }
116 }
117
checkVerify(GatekeeperVerifyResponse & rsp,Status & ret,uint64_t challenge,bool expectSuccess)118 void checkVerify(GatekeeperVerifyResponse& rsp, Status& ret, uint64_t challenge,
119 bool expectSuccess) {
120 if (expectSuccess) {
121 EXPECT_TRUE(ret.isOk());
122 EXPECT_GE(rsp.statusCode, IGatekeeper::STATUS_OK);
123 EXPECT_LE(rsp.statusCode, IGatekeeper::STATUS_REENROLL);
124
125 verifyAuthToken(rsp);
126 EXPECT_EQ(challenge, rsp.hardwareAuthToken.challenge);
127 } else {
128 EXPECT_EQ(IGatekeeper::ERROR_GENERAL_FAILURE, getReturnStatusCode(ret));
129 }
130 }
131
enrollNewPassword(std::vector<uint8_t> & password,GatekeeperEnrollResponse & rsp,bool expectSuccess)132 void enrollNewPassword(std::vector<uint8_t>& password, GatekeeperEnrollResponse& rsp,
133 bool expectSuccess) {
134 GatekeeperRequest req;
135 req.newPwd = password;
136 Status ret = doEnroll(req, rsp);
137 checkEnroll(rsp, ret, expectSuccess);
138 }
139
verifyPassword(std::vector<uint8_t> & password,std::vector<uint8_t> & passwordHandle,uint64_t challenge,GatekeeperVerifyResponse & verifyRsp,bool expectSuccess)140 void verifyPassword(std::vector<uint8_t>& password, std::vector<uint8_t>& passwordHandle,
141 uint64_t challenge, GatekeeperVerifyResponse& verifyRsp,
142 bool expectSuccess) {
143 GatekeeperRequest verifyReq;
144
145 // build verify request for the same password (we want it to succeed)
146 verifyReq.newPwd = password;
147 // use enrolled password handle we've got
148 verifyReq.curPwdHandle = passwordHandle;
149 verifyReq.challenge = challenge;
150 Status ret = doVerify(verifyReq, verifyRsp);
151 checkVerify(verifyRsp, ret, challenge, expectSuccess);
152 }
153
getReturnStatusCode(const Status & result)154 int32_t getReturnStatusCode(const Status& result) {
155 if (!result.isOk()) {
156 if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
157 return result.getServiceSpecificError();
158 }
159 return IGatekeeper::ERROR_GENERAL_FAILURE;
160 }
161 return IGatekeeper::STATUS_OK;
162 }
163
164 protected:
165 std::shared_ptr<IGatekeeper> gatekeeper_;
166 uint32_t uid_;
167
168 public:
GatekeeperAidlTest()169 GatekeeperAidlTest() : uid_(0) {}
SetUp()170 virtual void SetUp() override {
171 gatekeeper_ = IGatekeeper::fromBinder(
172 ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
173 ASSERT_NE(nullptr, gatekeeper_.get());
174 doDeleteAllUsers();
175 }
176
TearDown()177 virtual void TearDown() override { doDeleteAllUsers(); }
178 };
179
180 /**
181 * Ensure we can enroll new password
182 */
TEST_P(GatekeeperAidlTest,EnrollSuccess)183 TEST_P(GatekeeperAidlTest, EnrollSuccess) {
184 std::vector<uint8_t> password;
185 GatekeeperEnrollResponse rsp;
186 ALOGI("Testing Enroll (expected success)");
187 generatePassword(password, 0);
188 enrollNewPassword(password, rsp, true);
189 ALOGI("Testing Enroll done");
190 }
191
192 /**
193 * Ensure we can not enroll empty password
194 */
TEST_P(GatekeeperAidlTest,EnrollNoPassword)195 TEST_P(GatekeeperAidlTest, EnrollNoPassword) {
196 std::vector<uint8_t> password;
197 GatekeeperEnrollResponse rsp;
198 ALOGI("Testing Enroll (expected failure)");
199 enrollNewPassword(password, rsp, false);
200 ALOGI("Testing Enroll done");
201 }
202
203 /**
204 * Ensure we can successfully verify previously enrolled password
205 */
TEST_P(GatekeeperAidlTest,VerifySuccess)206 TEST_P(GatekeeperAidlTest, VerifySuccess) {
207 GatekeeperEnrollResponse enrollRsp;
208 GatekeeperVerifyResponse verifyRsp;
209 std::vector<uint8_t> password;
210
211 ALOGI("Testing Enroll+Verify (expected success)");
212 generatePassword(password, 0);
213 enrollNewPassword(password, enrollRsp, true);
214 verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
215
216 ALOGI("Testing unenrolled password doesn't verify");
217 verifyRsp = {0, 0, {}};
218 generatePassword(password, 1);
219 verifyPassword(password, enrollRsp.data, 1, verifyRsp, false);
220 ALOGI("Testing Enroll+Verify done");
221 }
222
223 /**
224 * Ensure that passwords containing a NUL byte aren't truncated
225 */
TEST_P(GatekeeperAidlTest,PasswordIsBinaryData)226 TEST_P(GatekeeperAidlTest, PasswordIsBinaryData) {
227 GatekeeperEnrollResponse enrollRsp;
228 GatekeeperVerifyResponse verifyRsp;
229 std::vector<uint8_t> rightPassword = {'A', 'B', 'C', '\0', 'D', 'E', 'F'};
230 std::vector<uint8_t> wrongPassword = {'A', 'B', 'C', '\0', '\0', '\0', '\0'};
231
232 ALOGI("Testing Enroll+Verify of password with embedded NUL (expected success)");
233 enrollNewPassword(rightPassword, enrollRsp, true);
234 verifyPassword(rightPassword, enrollRsp.data, 1, verifyRsp, true);
235
236 ALOGI("Testing Verify of wrong password (expected failure)");
237 verifyPassword(wrongPassword, enrollRsp.data, 1, verifyRsp, false);
238
239 ALOGI("PasswordIsBinaryData test done");
240 }
241
242 /**
243 * Ensure that long passwords aren't truncated
244 */
TEST_P(GatekeeperAidlTest,LongPassword)245 TEST_P(GatekeeperAidlTest, LongPassword) {
246 GatekeeperEnrollResponse enrollRsp;
247 GatekeeperVerifyResponse verifyRsp;
248 std::vector<uint8_t> password;
249
250 password.resize(64); // maximum length used by Android
251 memset(password.data(), 'A', password.size());
252
253 ALOGI("Testing Enroll+Verify of long password (expected success)");
254 enrollNewPassword(password, enrollRsp, true);
255 verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
256
257 ALOGI("Testing Verify of wrong password (expected failure)");
258 password[password.size() - 1] ^= 1;
259 verifyPassword(password, enrollRsp.data, 1, verifyRsp, false);
260
261 ALOGI("LongPassword test done");
262 }
263
264 /**
265 * Ensure we can securely update password (keep the same
266 * secure user_id) if we prove we know old password
267 */
TEST_P(GatekeeperAidlTest,TrustedReenroll)268 TEST_P(GatekeeperAidlTest, TrustedReenroll) {
269 GatekeeperEnrollResponse enrollRsp;
270 GatekeeperRequest reenrollReq;
271 GatekeeperEnrollResponse reenrollRsp;
272 GatekeeperVerifyResponse verifyRsp;
273 GatekeeperVerifyResponse reenrollVerifyRsp;
274 std::vector<uint8_t> password;
275 std::vector<uint8_t> newPassword;
276
277 generatePassword(password, 0);
278
279 ALOGI("Testing Trusted Reenroll (expected success)");
280 enrollNewPassword(password, enrollRsp, true);
281 verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
282 ALOGI("Primary Enroll+Verify done");
283
284 generatePassword(newPassword, 1);
285 reenrollReq.newPwd = newPassword;
286 reenrollReq.curPwd = password;
287 reenrollReq.curPwdHandle = enrollRsp.data;
288
289 Status ret = doEnroll(reenrollReq, reenrollRsp);
290 checkEnroll(reenrollRsp, ret, true);
291 verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
292 ALOGI("Trusted ReEnroll+Verify done");
293
294 verifyAuthToken(verifyRsp);
295 verifyAuthToken(reenrollVerifyRsp);
296 EXPECT_EQ(verifyRsp.hardwareAuthToken.userId, reenrollVerifyRsp.hardwareAuthToken.userId);
297 ALOGI("Testing Trusted Reenroll done");
298 }
299
300 /**
301 * Ensure we can update password (and get new
302 * secure user_id) if we don't know old password
303 */
TEST_P(GatekeeperAidlTest,UntrustedReenroll)304 TEST_P(GatekeeperAidlTest, UntrustedReenroll) {
305 GatekeeperEnrollResponse enrollRsp;
306 GatekeeperEnrollResponse reenrollRsp;
307 GatekeeperVerifyResponse verifyRsp;
308 GatekeeperVerifyResponse reenrollVerifyRsp;
309 std::vector<uint8_t> password;
310 std::vector<uint8_t> newPassword;
311
312 ALOGI("Testing Untrusted Reenroll (expected success)");
313 generatePassword(password, 0);
314 enrollNewPassword(password, enrollRsp, true);
315 verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
316 ALOGI("Primary Enroll+Verify done");
317
318 generatePassword(newPassword, 1);
319 enrollNewPassword(newPassword, reenrollRsp, true);
320 verifyPassword(newPassword, reenrollRsp.data, 0, reenrollVerifyRsp, true);
321 ALOGI("Untrusted ReEnroll+Verify done");
322
323 verifyAuthToken(verifyRsp);
324 verifyAuthToken(reenrollVerifyRsp);
325 EXPECT_NE(verifyRsp.hardwareAuthToken.userId, reenrollVerifyRsp.hardwareAuthToken.userId);
326 ALOGI("Testing Untrusted Reenroll done");
327 }
328
329 /**
330 * Ensure we don't get successful verify with invalid data
331 */
TEST_P(GatekeeperAidlTest,VerifyNoData)332 TEST_P(GatekeeperAidlTest, VerifyNoData) {
333 std::vector<uint8_t> password;
334 std::vector<uint8_t> passwordHandle;
335 GatekeeperVerifyResponse verifyRsp;
336
337 ALOGI("Testing Verify (expected failure)");
338 verifyPassword(password, passwordHandle, 0, verifyRsp, false);
339 ALOGI("Testing Verify done");
340 }
341
342 /**
343 * Ensure we can not verify password after we enrolled it and then deleted user
344 */
TEST_P(GatekeeperAidlTest,DeleteUserTest)345 TEST_P(GatekeeperAidlTest, DeleteUserTest) {
346 std::vector<uint8_t> password;
347 GatekeeperEnrollResponse enrollRsp;
348 GatekeeperVerifyResponse verifyRsp;
349 ALOGI("Testing deleteUser (expected success)");
350 setUid(10001);
351 generatePassword(password, 0);
352 enrollNewPassword(password, enrollRsp, true);
353 verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
354 ALOGI("Enroll+Verify done");
355 auto result = doDeleteUser();
356 EXPECT_TRUE(result.isOk() ||
357 (getReturnStatusCode(result) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
358 ALOGI("DeleteUser done");
359 if (result.isOk()) {
360 verifyRsp = {0, 0, {}};
361 verifyPassword(password, enrollRsp.data, 0, verifyRsp, false);
362 ALOGI("Verify after Delete done (must fail)");
363 }
364 ALOGI("Testing deleteUser done: rsp=%" PRIi32, getReturnStatusCode(result));
365 }
366
367 /**
368 * Ensure we can not delete a user that does not exist
369 */
TEST_P(GatekeeperAidlTest,DeleteInvalidUserTest)370 TEST_P(GatekeeperAidlTest, DeleteInvalidUserTest) {
371 std::vector<uint8_t> password;
372 GatekeeperEnrollResponse enrollRsp;
373 GatekeeperVerifyResponse verifyRsp;
374 ALOGI("Testing deleteUser (expected failure)");
375 setUid(10002);
376 generatePassword(password, 0);
377 enrollNewPassword(password, enrollRsp, true);
378 verifyPassword(password, enrollRsp.data, 0, verifyRsp, true);
379 ALOGI("Enroll+Verify done");
380
381 // Delete the user
382 Status result1 = doDeleteUser();
383 EXPECT_TRUE(result1.isOk() ||
384 (getReturnStatusCode(result1) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
385
386 // Delete the user again
387 Status result2 = doDeleteUser();
388 int32_t retCode2 = getReturnStatusCode(result2);
389 EXPECT_TRUE((retCode2 == IGatekeeper::ERROR_NOT_IMPLEMENTED) ||
390 (retCode2 == IGatekeeper::ERROR_GENERAL_FAILURE));
391 ALOGI("DeleteUser done");
392 ALOGI("Testing deleteUser done: rsp=%" PRIi32, retCode2);
393 }
394
395 /**
396 * Ensure we can not verify passwords after we enrolled them and then deleted
397 * all users
398 */
TEST_P(GatekeeperAidlTest,DeleteAllUsersTest)399 TEST_P(GatekeeperAidlTest, DeleteAllUsersTest) {
400 struct UserData {
401 uint32_t userId;
402 std::vector<uint8_t> password;
403 GatekeeperEnrollResponse enrollRsp;
404 GatekeeperVerifyResponse verifyRsp;
405 UserData(int id) { userId = id; }
406 } users[3]{10001, 10002, 10003};
407 ALOGI("Testing deleteAllUsers (expected success)");
408
409 // enroll multiple users
410 for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
411 setUid(users[i].userId);
412 generatePassword(users[i].password, (i % 255) + 1);
413 enrollNewPassword(users[i].password, users[i].enrollRsp, true);
414 }
415 ALOGI("Multiple users enrolled");
416
417 // verify multiple users
418 for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
419 setUid(users[i].userId);
420 verifyPassword(users[i].password, users[i].enrollRsp.data, 0, users[i].verifyRsp, true);
421 }
422 ALOGI("Multiple users verified");
423
424 Status result = doDeleteAllUsers();
425 EXPECT_TRUE(result.isOk() ||
426 (getReturnStatusCode(result) == IGatekeeper::ERROR_NOT_IMPLEMENTED));
427 ALOGI("All users deleted");
428
429 if (result.isOk()) {
430 // verify multiple users after they are deleted; all must fail
431 for (size_t i = 0; i < sizeof(users) / sizeof(users[0]); ++i) {
432 setUid(users[i].userId);
433 users[i].verifyRsp = {0, 0, {}};
434 verifyPassword(users[i].password, users[i].enrollRsp.data, 0, users[i].verifyRsp,
435 false);
436 }
437 ALOGI("Multiple users verified after delete (all must fail)");
438 }
439
440 ALOGI("Testing deleteAllUsers done: rsp=%" PRIi32, getReturnStatusCode(result));
441 }
442
443 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GatekeeperAidlTest);
444 INSTANTIATE_TEST_SUITE_P(
445 PerInstance, GatekeeperAidlTest,
446 testing::ValuesIn(android::getAidlHalInstanceNames(IGatekeeper::descriptor)),
447 android::PrintInstanceNameToString);
448
main(int argc,char ** argv)449 int main(int argc, char** argv) {
450 ::testing::InitGoogleTest(&argc, argv);
451 ABinderProcess_setThreadPoolMaxThreadCount(1);
452 ABinderProcess_startThreadPool();
453 return RUN_ALL_TESTS();
454 }
455