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