密码认证调用过程:
LockPatternChecker.verifyPattern(
utils,
mChosenPattern,
mChallenge,
UserHandle.myUserId(),
new LockPatternChecker.OnVerifyCallback() {
.....
}
}
LockPatternChecker.verifyPattern调到utils.verifyPattern(pattern, challenge,userId); utils即是LockPatternUtils.java
LockPatternUtils.java ---->public byte[]verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId)
其中的VerifyCredentialResponse response =
getLockSettings().verifyPattern(patternToString(pattern),challenge, userId);
getLockSettings其实是返回LockSettingsService服务:这个服务具体代码在LockSettingsService.java文件中:
ILockSettings service =ILockSettings.Stub.asInterface(
ServiceManager.getService("lock_settings"));
ILockSettings service这个服务最后会调到:
GateKeeperResponse gateKeeperResponse =getGateKeeperService()
.verifyChallenge(userId, challenge,storedHash.hash,credential.getBytes());
getGateKeeperService()的service其实是:system/core/gatekeeperd这个守护进程提供的服务。具体文件执行文件是IGateKeeperService.cpp中:
mGateKeeperService =IGateKeeperService.Stub.asInterface(service);
LockSettingsService调到IGateKeeperService.cpp实际是在BnGateKeeperService::onTransact中的VERIFY_CHALLENGE
即:
status_t BnGateKeeperService::onTransact{
case VERIFY_CHALLENGE: {
CHECK_INTERFACE(IGateKeeperService,data, reply);
uint32_t uid = data.readInt32();
uint64_t challenge = data.readInt64();
ssize_t currentPasswordHandleSize =data.readInt32();
const uint8_t *currentPasswordHandle =
static_cast<const uint8_t*>(data.readInplace(currentPasswordHandleSize));
if (!currentPasswordHandle) currentPasswordHandleSize= 0;
ssize_t currentPasswordSize =data.readInt32();
const uint8_t *currentPassword =
static_cast<const uint8_t*>(data.readInplace(currentPasswordSize));
if (!currentPassword) currentPasswordSize =0;
uint8_t *out = NULL;
uint32_t outSize = 0;
bool request_reenroll = false;
int ret = verifyChallenge(uid, challenge,(uint8_t *) currentPasswordHandle,
currentPasswordHandleSize, (uint8_t *)currentPassword, currentPasswordSize,
&out, &outSize,&request_reenroll);
......
return NO_ERROR;
}
verifyChallenge(uid,challenge, (uint8_t *) currentPasswordHandle,
currentPasswordHandleSize,(uint8_t *) currentPassword, currentPasswordSize,
&out, &outSize,&request_reenroll);最后调到gatekeeperd.cpp中的device->verify(device, uid, challenge,
enrolled_password_handle,enrolled_password_handle_length,
provided_password, provided_password_length,auth_token, auth_token_length,
request_reenroll);
virtual int verifyChallenge(uint32_t uid, uint64_tchallenge,
const uint8_t *enrolled_password_handle,uint32_t enrolled_password_handle_length,
const uint8_t *provided_password, uint32_tprovided_password_length,
uint8_t **auth_token, uint32_t*auth_token_length, bool *request_reenroll){
.....
if (device) {
const gatekeeper::password_handle_t *handle =
reinterpret_cast<const gatekeeper::password_handle_t*>(enrolled_password_handle);
// handle version 0 does nothave hardware backed flag, and thus cannot be upgraded to
// a HAL if there was nonebefore
if (handle->version == 0 || handle->hardware_backed) {
ret = device->verify(device, uid,challenge,
enrolled_password_handle,enrolled_password_handle_length,
provided_password,provided_password_length, auth_token, auth_token_length,
request_reenroll);
} else {
// upgrade scenario, a HALhas been added to this device where there was none before
SoftGateKeeperDevice soft_dev;
ret = soft_dev.verify(uid, challenge,
enrolled_password_handle,enrolled_password_handle_length,
provided_password,provided_password_length, auth_token, auth_token_length,
request_reenroll);
.....
}
} else {
ret = soft_device->verify(uid,challenge,
enrolled_password_handle, enrolled_password_handle_length,
provided_password,provided_password_length, auth_token, auth_token_length,
request_reenroll);
}
.....
return ret;
}
而device->verify(device, uid,challenge,
enrolled_password_handle,enrolled_password_handle_length,
provided_password, provided_password_length,auth_token, auth_token_length,
request_reenroll);的实现过程:最后调到了verifyChallenge方法:而这个方法的提供实现是在mtk提供商给我们的vender路径下的库:vender/mediatek/properitary/hardware/ut_gatekeeper中。
ut_gatekeeper.cpp就是一个很重要的实现函数了:
ut_gatekeeper.cpp中建设了device->verify的对应关系:即 dev->verify 直接对应调用ut_gk_verify;
static int ut_gk_open(consthw_module_t* module, const char*name, hw_device_t** device) {
#ifdef GK_DEBUG
LOG_E("====[%s]gatekeeper open====",__func__);
#endif
if (strcmp(name, HARDWARE_GATEKEEPER) != 0)
return -EINVAL;
dev = (gatekeeper_device_t*)malloc(sizeof(gatekeeper_device_t));
if(NULL == dev)
{
LOG_E("[%s]unable to malloc dev",__func__);
return -EFAULT;
}
memset(dev, 0,sizeof(gatekeeper_device_t));
dev->common.tag =HARDWARE_DEVICE_TAG;
dev->common.version = 1;
dev->common.module = (struct hw_module_t*)module;
dev->common.close = ut_gk_close;
dev->enroll = ut_gk_enroll;
dev->verify = ut_gk_verify;
dev->delete_user = NULL;
dev->delete_all_users = NULL;
*device = &dev->common;
return 0;
}
下面就是ut_gk_verify的实现了:
static int ut_gk_verify(conststruct gatekeeper_device *dev, uint32_t uid, uint64_t challenge,
const uint8_t *enrolled_password_handle,uint32_t enrolled_password_handle_length,
const uint8_t *provided_password, uint32_tprovided_password_length,
uint8_t **auth_token, uint32_t*auth_token_length, bool *request_reenroll)
{
LOG_I("====From ree verify!! ====");
if (enrolled_password_handle == NULL||provided_password == NULL) {
return -EINVAL;
}
if (provided_password_length >= 17){
provided_password_length = 17;
//return -EINVAL;
}
#ifdef GK_DEBUG
LOG_E("====[%s][ree] verify variable [in] begin====",__func__);
LOG_E("====[%s]uid is %lu====",__func__, uid);
LOG_E("====[%s]challenge is %llu====",__func__, challenge);
LOG_E("====[%s]enrolled_password_handle_length is %lu====",__func__,enrolled_password_handle_length);
LOG_E("====[%s]provided_password_length is %lu====",__func__,provided_password_length);
LOG_E("====[%s]version is %u====",__func__,((structpassword_handle_t*)(enrolled_password_handle))->version);
LOG_E("====[%s]user_id is %llu====",__func__,((structpassword_handle_t*)(enrolled_password_handle))->user_id);
LOG_E("====[%s]flags is %llu====",__func__,((structpassword_handle_t*)(enrolled_password_handle))->flags);
LOG_E("====[%s]salt is %llu====",__func__,((structpassword_handle_t*)(enrolled_password_handle))->salt);
LOG_E("====[%s]hardware_backed is %u====",__func__,((struct password_handle_t*)(enrolled_password_handle))->hardware_backed);
LOG_E("====[%s][ree] verify variable [in] end ====",__func__);
#endif
uint8_t *position;
uint8_t * gatekeeper_transfer_buffer =(uint8_t *)malloc(GATEKEEPER_BUFF_SIZE);
if(NULL == gatekeeper_transfer_buffer)
{
LOG_E("[%s]unable to malloc gatekeeper_transfer_buffer",__func__);
return -EFAULT;
}
memset(gatekeeper_transfer_buffer, 0, GATEKEEPER_BUFF_SIZE);
ut_gk_struct_t * ut_gk_struct =(ut_gk_struct_t *)malloc (sizeof(ut_gk_struct_t));
if(NULL == ut_gk_struct)
{
LOG_E("[%s]unable to malloc ut_gk_struct",__func__);
free(gatekeeper_transfer_buffer);
return -EFAULT;
}
memset(ut_gk_struct, 0, sizeof(ut_gk_struct_t));
//set ut_gk_struct for constlength parts
ut_gk_struct->cmd = CMD_ID_VARIFY;
ut_gk_struct->uid = uid;
ut_gk_struct->ut_gk_verify.challenge= challenge;
ut_gk_struct->ut_gk_verify.enrolled_password_handle_length= enrolled_password_handle_length;
ut_gk_struct->ut_gk_verify.provided_password_length= provided_password_length;
//copy ut_gk_struct to gatekeeper_transfer_buffer
memcpy((void*)gatekeeper_transfer_buffer,(void*)ut_gk_struct, sizeof(ut_gk_struct_t));
position = (uint8_t*)gatekeeper_transfer_buffer + sizeof(ut_gk_struct_t);
//copy varify length parts togatekeeper_transfer_buffer
memcpy(position,enrolled_password_handle, enrolled_password_handle_length);
position +=enrolled_password_handle_length;
memcpy(position, provided_password,provided_password_length);
//transfer buff to tee
if(ut_gk_transfer_buff(gatekeeper_transfer_buffer))//这个就是进行认证
{
LOG_E("[%s]can't transfer buff to tee",__func__);
free(ut_gk_struct);
free(gatekeeper_transfer_buffer);
return -EFAULT;
}
ut_gk_verify_out_t* ut_gk_verify_out =(ut_gk_verify_out_t *)malloc(sizeof(ut_gk_verify_out_t));
if(NULL == ut_gk_verify_out)
{
LOG_E("[%s]unable to malloc ut_gk_verify_out",__func__);
free(ut_gk_struct);
free(gatekeeper_transfer_buffer);
return -EFAULT;
}
memset(ut_gk_verify_out, 0, sizeof(ut_gk_verify_out_t));
//copy buffer to struct
memcpy(ut_gk_verify_out,gatekeeper_transfer_buffer, sizeof(ut_gk_verify_out_t));
//if there is an error?
if (ut_gk_verify_out->error ==ERROR_RETRY) {
#ifdef GK_DEBUG
LOG_E("====[%s]ut_gk_verify_out->error == ERROR_RETRY ====",__func__);
LOG_E("====[%s]ut_gk_verify_out->retry_timeout is %lu====",__func__,ut_gk_verify_out->retry_timeout);
#endif
uint32_t retry_timeout;
retry_timeout =ut_gk_verify_out->retry_timeout;
free(ut_gk_verify_out);
free(ut_gk_struct);
free(gatekeeper_transfer_buffer);
return retry_timeout;
} else if (ut_gk_verify_out->error!= ERROR_NONE) {
#ifdef GK_DEBUG
LOG_E("====[%s]ut_gk_verify_out->error != ERROR_NONE ====",__func__);
#endif
free(ut_gk_verify_out);
free(ut_gk_struct);
free(gatekeeper_transfer_buffer);
return -EINVAL;
}
//copygatekeeper_transfer_buffer to return variable
*request_reenroll =ut_gk_verify_out->request_reenroll;
*auth_token_length =ut_gk_verify_out->auth_token_length;
*auth_token = (uint8_t *)malloc( *auth_token_length);
memcpy(*auth_token,gatekeeper_transfer_buffer+ sizeof(ut_gk_verify_out_t),* auth_token_length);
#ifdef GK_DEBUG
LOG_E("====[%s]ut_gk_verify_out->error no error ====",__func__);
LOG_E("====[%s][ree] verify variable [out] begin====",__func__);
LOG_E("====[%s]request_reenroll is %u====",__func__,*request_reenroll);
LOG_E("====[%s]auth_token_length is %lu====",__func__,*auth_token_length);
LOG_E("====[%s]version is %u====",__func__,((hw_auth_token_t*)(*auth_token))->version);
LOG_E("====[%s]challenge is %u====",__func__,((hw_auth_token_t*)(*auth_token))->challenge);
LOG_E("====[%s]user_id is %llu====",__func__,((hw_auth_token_t*)(*auth_token))->user_id);
LOG_E("====[%s]authenticator_id is %llu====",__func__,((hw_auth_token_t*)(*auth_token))->authenticator_id);
LOG_E("====[%s]authenticator_type is %lu====",__func__,((hw_auth_token_t*)(*auth_token))->authenticator_type);
LOG_E("====[%s]timestamp is %llu====",__func__,((hw_auth_token_t*)(*auth_token))->timestamp);
LOG_E("====[%s][ree] verify variable [out] end====",__func__);
#endif
free(ut_gk_verify_out);
free(ut_gk_struct);
free(gatekeeper_transfer_buffer);
return 0;
}
static int ut_gk_close(hw_device_t* dev) {
#ifdef GK_DEBUG
LOG_E("====[%s]gatekeeper close====",__func__);
#endif
free(dev);
return 0;
}
那么我们就看一下这个认证过程:ut_gk_transfer_buff(gatekeeper_transfer_buffer)。最后是调到了if(ioctl(fd,CMD_GATEKEEPER_CMD,buff))这个进行处理。即实际传入参数gatekeeper_transfer_buffer,gatekeeper_transfer_buffer这个经过赋值和强转变为ut_gk_verify_out这样就可以通过:ut_gk_verify_out->error与typedef enum {
ERROR_NONE = 0,
ERROR_INVALID = 1,
ERROR_RETRY = 2,
ERROR_UNKNOWN = 3,
} gatekeeper_error_t; 几个值进行对应 ERROR_INVALIDERROR_RETRY ERROR_UNKNOWN 都是认证有问题,只有ERROR_NONE 是表示认证正常,然后继续往下走:
#define DEVICE_NODE "/dev/teei_fp"
#define CMD_GATEKEEPER_CMD _IO(0x775A777E, 0x3)
gatekeeper_device_t * dev = NULL;
static int ut_gk_transfer_buff(void* buff)
{
if(NULL == buff){
LOG_E("[%s]buff is NULL!", __func__);
return -EINVAL;
}
int fd;
fd = open(DEVICE_NODE, O_RDWR);
if(fd <= 0)
{
LOG_E("[%s]can't open DEVICE_NODE!", __func__);
return -EFAULT;
}
#ifdef GK_DEBUG
LOG_E("====[%s]open success====", __func__);
#endif
if(ioctl(fd,CMD_GATEKEEPER_CMD,buff))
{
LOG_E("[%s]can't ioctl DEVICE_NODE!", __func__);
close(fd);
return -EFAULT;
}
close(fd);
return 0;
}
即看到以下log就代表成功了:
#ifdef GK_DEBUG
LOG_E("====[%s]ut_gk_enroll_out->error no error ====",__func__);
LOG_E("====[%s][ree] enroll variable [out] begin====",__func__);
LOG_E("====[%s]sizeof(struct password_handle_t)=%d====",__func__,sizeof(struct password_handle_t));
LOG_E("====[%s]version is %u====",__func__,((structpassword_handle_t*)(*enrolled_password_handle))->version);
LOG_E("====[%s]user_id is %llu====",__func__,((structpassword_handle_t*)(*enrolled_password_handle))->user_id);
LOG_E("====[%s]flags is %llu====",__func__,((structpassword_handle_t*)(*enrolled_password_handle))->flags);
LOG_E("====[%s]salt is %llu====",__func__,((structpassword_handle_t*)(*enrolled_password_handle))->salt);
LOG_E("====[%s]password_length is %lu====",__func__,*enrolled_password_handle_length);
LOG_E("====[%s]hardware_backed is %u====",__func__,((struct password_handle_t*)(*enrolled_password_handle))->hardware_backed);
LOG_E("====[%s][ree] enroll variable [out] end====",__func__);
#endif
"/dev/teei_fp"这个文件的操作出错直接可以导致认证无法通过的。