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