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