1 /* 2 * Copyright (C) 2015 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 #include <endian.h> 17 #include <gtest/gtest.h> 18 #include <hardware/gatekeeper.h> 19 #include <gatekeeper/gatekeeper.h> // For password_handle_t 20 #include <unistd.h> 21 22 using ::testing::Test; 23 using ::gatekeeper::password_handle_t; 24 using ::gatekeeper::secure_id_t; 25 26 class GateKeeperDeviceTest : public virtual Test { 27 public: 28 GateKeeperDeviceTest() {} 29 virtual ~GateKeeperDeviceTest() {} 30 31 virtual void SetUp() { 32 gatekeeper_device_initialize(&device); 33 } 34 35 virtual void TearDown() { 36 gatekeeper_close(device); 37 } 38 39 static void gatekeeper_device_initialize(gatekeeper_device_t **dev) { 40 int ret; 41 const hw_module_t *mod; 42 ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &mod); 43 44 ASSERT_EQ(0, ret); 45 46 ret = gatekeeper_open(mod, dev); 47 48 ASSERT_EQ(0, ret); 49 } 50 51 gatekeeper_device_t *device; 52 }; 53 54 TEST_F(GateKeeperDeviceTest, EnrollAndVerifyStress) { 55 uint32_t password_len = 50; 56 uint8_t password_payload[password_len]; 57 uint8_t *password_handle; 58 uint32_t password_handle_length; 59 uint8_t *auth_token; 60 uint32_t auth_token_len; 61 int ret; 62 63 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 64 &password_handle, &password_handle_length); 65 66 ASSERT_EQ(0, ret); 67 68 for (int i = 0; i < 1000; i++) { 69 bool should_reenroll; 70 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 71 password_payload, password_len, &auth_token, &auth_token_len, &should_reenroll); 72 73 ASSERT_EQ(0, ret); 74 } 75 } 76 77 TEST_F(GateKeeperDeviceTest, EnrollAndVerify) { 78 uint32_t password_len = 50; 79 uint8_t password_payload[password_len]; 80 uint8_t *password_handle; 81 uint32_t password_handle_length; 82 uint8_t *auth_token; 83 uint32_t auth_token_len; 84 hw_auth_token_t *hat; 85 int ret; 86 87 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 88 &password_handle, &password_handle_length); 89 90 ASSERT_EQ(0, ret); 91 92 bool should_reenroll; 93 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 94 password_payload, password_len, &auth_token, &auth_token_len, &should_reenroll); 95 ASSERT_EQ(0, should_reenroll); 96 ASSERT_EQ(0, ret); 97 98 hat = reinterpret_cast<hw_auth_token_t *>(auth_token); 99 100 ASSERT_EQ(HW_AUTH_TOKEN_VERSION, hat->version); 101 ASSERT_EQ(htonl(HW_AUTH_PASSWORD), hat->authenticator_type); 102 } 103 104 TEST_F(GateKeeperDeviceTest, EnrollAndVerifyTimeout) { 105 uint32_t password_len = 50; 106 uint8_t password_payload[password_len]; 107 uint8_t *password_handle; 108 uint32_t password_handle_length; 109 uint8_t *auth_token = NULL; 110 uint32_t auth_token_len; 111 bool should_reenroll; 112 int ret; 113 114 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 115 &password_handle, &password_handle_length); 116 117 ASSERT_EQ(0, ret); 118 119 int payload_val = password_payload[0]; 120 password_payload[0] = 4; 121 122 int timeout = 0; 123 for (int i = 0; i < 20; i++) { 124 bool should_reenroll; 125 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 126 password_payload, password_len, &auth_token, &auth_token_len, 127 &should_reenroll); 128 ASSERT_NE(0, ret); 129 ASSERT_EQ(NULL, auth_token); 130 131 if (ret > 0) { 132 timeout = ret; 133 } 134 } 135 136 ASSERT_NE(0, timeout); 137 138 sleep((timeout + 999)/ 1000); 139 140 password_payload[0] = payload_val; 141 142 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 143 password_payload, password_len, &auth_token, &auth_token_len, 144 &should_reenroll); 145 146 ASSERT_EQ(0, ret); 147 } 148 149 TEST_F(GateKeeperDeviceTest, EnrollAndVerifyBadPassword) { 150 uint32_t password_len = 50; 151 uint8_t password_payload[password_len]; 152 uint8_t *password_handle; 153 uint32_t password_handle_length; 154 uint8_t *auth_token = NULL; 155 uint32_t auth_token_len; 156 int ret; 157 158 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 159 &password_handle, &password_handle_length); 160 161 ASSERT_EQ(0, ret); 162 163 password_payload[0] = 4; 164 165 bool should_reenroll; 166 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 167 password_payload, password_len, &auth_token, &auth_token_len, 168 &should_reenroll); 169 170 ASSERT_NE(0, ret); 171 ASSERT_EQ(NULL, auth_token); 172 } 173 174 TEST_F(GateKeeperDeviceTest, MinFailedAttemptsBeforeLockout) { 175 uint32_t password_len = 50; 176 uint8_t password_payload[password_len]; 177 uint8_t *password_handle; 178 uint32_t password_handle_length; 179 uint8_t *auth_token = NULL; 180 uint32_t auth_token_len; 181 int ret; 182 183 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 184 &password_handle, &password_handle_length); 185 186 ASSERT_EQ(0, ret); 187 188 password_payload[0] = 4; 189 190 // User should have at least 4 attempts before being locked out 191 static const int MIN_FAILED_ATTEMPTS = 4; 192 193 bool should_reenroll; 194 for (int i = 0; i < MIN_FAILED_ATTEMPTS; i++) { 195 ret = device->verify(device, 400, 0, password_handle, password_handle_length, 196 password_payload, password_len, &auth_token, &auth_token_len, 197 &should_reenroll); 198 // shoudln't be a timeout 199 ASSERT_LT(ret, 0); 200 } 201 } 202 203 TEST_F(GateKeeperDeviceTest, UntrustedReEnroll) { 204 uint32_t password_len = 50; 205 uint8_t password_payload[password_len]; 206 uint8_t *password_handle; 207 uint32_t password_handle_length; 208 int ret; 209 210 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 211 &password_handle, &password_handle_length); 212 213 ASSERT_EQ(0, ret); 214 215 password_handle_t *handle = reinterpret_cast<password_handle_t *>(password_handle); 216 secure_id_t sid = handle->user_id; 217 218 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 219 &password_handle, &password_handle_length); 220 221 ASSERT_EQ(0, ret); 222 handle = reinterpret_cast<password_handle_t *>(password_handle); 223 ASSERT_NE(sid, handle->user_id); 224 } 225 226 227 TEST_F(GateKeeperDeviceTest, TrustedReEnroll) { 228 uint32_t password_len = 50; 229 uint8_t password_payload[password_len]; 230 uint8_t *password_handle; 231 uint32_t password_handle_length; 232 int ret; 233 234 ret = device->enroll(device, 400, NULL, 0, NULL, 0, password_payload, password_len, 235 &password_handle, &password_handle_length); 236 237 ASSERT_EQ(0, ret); 238 239 password_handle_t *handle = reinterpret_cast<password_handle_t *>(password_handle); 240 secure_id_t sid = handle->user_id; 241 242 ret = device->enroll(device, 400, password_handle, password_handle_length, password_payload, 243 password_len, password_payload, password_len, &password_handle, &password_handle_length); 244 245 ASSERT_EQ(0, ret); 246 handle = reinterpret_cast<password_handle_t *>(password_handle); 247 ASSERT_EQ(sid, handle->user_id); 248 } 249 250