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