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
38using ::android::hardware::hidl_string;
39using ::android::hardware::hidl_vec;
40using ::android::hardware::gatekeeper::V1_0::IGatekeeper;
41using ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
42using ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
43using ::android::hardware::Return;
44using ::android::hardware::Void;
45using ::android::sp;
46
47struct 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;
53  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"
58static 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.
82class GatekeeperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
83 public:
84  // get the test environment singleton
85  static GatekeeperHidlEnvironment* Instance() {
86    static GatekeeperHidlEnvironment* instance = new GatekeeperHidlEnvironment;
87    return instance;
88  }
89
90  virtual void registerTestServices() override { registerTestService<IGatekeeper>(); }
91 private:
92  GatekeeperHidlEnvironment() {}
93};
94
95// The main test class for Gatekeeper HIDL HAL.
96class GatekeeperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
97 protected:
98  void setUid(uint32_t uid) { uid_ = uid; }
99
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
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
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
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
146  void generatePassword(hidl_vec<uint8_t> &password, uint8_t seed) {
147    password.resize(16);
148    memset(password.data(), seed, password.size());
149  }
150
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
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
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
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:
204  GatekeeperHidlTest() : uid_(0) {}
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
213  virtual void TearDown() override {
214    GatekeeperResponse rsp;
215    doDeleteAllUsers(rsp);
216  }
217};
218
219/**
220 * Ensure we can enroll new password
221 */
222TEST_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 */
234TEST_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 */
245TEST_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 */
261TEST_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 */
300TEST_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 */
330TEST_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 */
344TEST_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 */
371TEST_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 */
403TEST_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
451int 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