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