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