快速链接:
.
个人博客笔记导读目录(全部)
说明: 本文已抛弃,请移步到Android Gatekeeper流程深度解剖查看
gatekeeper的代码共有7部分:
(1)、locksettings : 就是密码锁/图案锁的APP,该程序直接调用IGateKeeperService的aidl
(frameworks/base/services/core/java/com/android/server/locksettings/)
例如在createPasswordBasedSyntheticPassword方法中,调用了IGateKeeperService gatekeeper的gatekeeper.enroll方法;
public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
byte[] credential, int credentialType, AuthenticationToken authToken,
int requestedQuality, int userId)
throws RemoteException {
if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
credential = DEFAULT_PASSWORD;
}
long handle = generateHandle();
PasswordData pwd = PasswordData.create(credentialType);
byte[] pwdToken = computePasswordToken(credential, pwd);
final long sid;
final byte[] applicationId;
if (isWeaverAvailable()) {
// Weaver based user password
int weaverSlot = getNextAvailableWeaverSlot();
Log.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId);
byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
if (weaverSecret == null) {
Log.e(TAG, "Fail to enroll user password under weaver " + userId);
return DEFAULT_HANDLE;
}
saveWeaverSlot(weaverSlot, handle, userId);
mPasswordSlotManager.markSlotInUse(weaverSlot);
synchronizeWeaverFrpPassword(pwd, requestedQuality, userId, weaverSlot);
pwd.passwordHandle = null;
sid = GateKeeper.INVALID_SECURE_USER_ID;
applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
} else {
// In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
// to prevent them from accumulating and causing problems.
gatekeeper.clearSecureUserId(fakeUid(userId));
// GateKeeper based user password
GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
passwordTokenToGkInput(pwdToken));
if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
return DEFAULT_HANDLE;
}
pwd.passwordHandle = response.getPayload();
sid = sidFromPasswordHandle(pwd.passwordHandle);
applicationId = transformUnderSecdiscardable(pwdToken,
createSecdiscardable(handle, userId));
synchronizeFrpPassword(pwd, requestedQuality, userId);
}
saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
applicationId, sid, userId);
return handle;
}
(2)、在IGateKeeperService的aidl中描述了IGateKeeperService;
(frameworks/base/core/java/android/service/gatekeeper/IGateKeeperService.aidl)
interface IGateKeeperService {
/**
* Enrolls a password, returning the handle to the enrollment to be stored locally.
* @param uid The Android user ID associated to this enrollment
* @param currentPasswordHandle The previously enrolled handle, or null if none
* @param currentPassword The previously enrolled plaintext password, or null if none.
* If provided, must verify against the currentPasswordHandle.
* @param desiredPassword The new desired password, for which a handle will be returned
* upon success.
* @return an EnrollResponse or null on failure
*/
GateKeeperResponse enroll(int uid, in byte[] currentPasswordHandle, in byte[] currentPassword,
in byte[] desiredPassword);
/**
* Verifies an enrolled handle against a provided, plaintext blob.
* @param uid The Android user ID associated to this enrollment
* @param enrolledPasswordHandle The handle against which the provided password will be
* verified.
* @param The plaintext blob to verify against enrolledPassword.
* @return a VerifyResponse, or null on failure.
*/
GateKeeperResponse verify(int uid, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
/**
* Verifies an enrolled handle against a provided, plaintext blob.
* @param uid The Android user ID associated to this enrollment
* @param challenge a challenge to authenticate agaisnt the device credential. If successful
* authentication occurs, this value will be written to the returned
* authentication attestation.
* @param enrolledPasswordHandle The handle against which the provided password will be
* verified.
* @param The plaintext blob to verify against enrolledPassword.
* @return a VerifyResponse with an attestation, or null on failure.
*/
GateKeeperResponse verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
in byte[] providedPassword);
/**
* Retrieves the secure identifier for the user with the provided Android ID,
* or 0 if none is found.
* @param uid the Android user id
*/
long getSecureUserId(int uid);
/**
* Clears secure user id associated with the provided Android ID.
* Must be called when password is set to NONE.
* @param uid the Android user id.
*/
void clearSecureUserId(int uid);
/**
* Notifies gatekeeper that device setup has been completed and any potentially still existing
* state from before a factory reset can be cleaned up (if it has not been already).
*/
void reportDeviceSetupComplete();
}
(3)、在gatekeeperd中实现了IGateKeeperService,并在gatekeeper的main函数中,添加了这个service
(system/core/gatekeeperd/IGateKeeperService.cpp)
const android::String16 IGateKeeperService::descriptor("android.service.gatekeeper.IGateKeeperService");
const android::String16& IGateKeeperService::getInterfaceDescriptor() const {
return IGateKeeperService::descriptor;
}
status_t BnGateKeeperService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch(code) {
case ENROLL: {
CHECK_INTERFACE(IGateKeeperService, data, reply);
uint32_t uid = data.readInt32();
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;
ssize_t desiredPasswordSize = data.readInt32();
const uint8_t *desiredPassword =
static_cast<const uint8_t *>(data.readInplace(desiredPasswordSize));
if (!desiredPassword) desiredPasswordSize = 0;
uint8_t *out = NULL;
uint32_t outSize = 0;
int ret = enroll(uid, currentPasswordHandle, currentPasswordHandleSize,
currentPassword, currentPasswordSize, desiredPassword,
desiredPasswordSize, &out, &outSize);
reply->writeNoException();
reply->writeInt32(1);
if (ret == 0 && outSize > 0 && out != NULL) {
reply->writeInt32(GATEKEEPER_RESPONSE_OK);
reply->writeInt32(0);
reply->writeInt32(outSize);
reply->writeInt32(outSize);
void *buf = reply->writeInplace(outSize);
memcpy(buf, out, outSize);
delete[] out;
} else if (ret > 0) {
reply->writeInt32(GATEKEEPER_RESPONSE_RETRY);
reply->writeInt32(ret);
} else {
reply->writeInt32(GATEKEEPER_RESPONSE_ERROR);
}
return OK;
}
case VERIFY: {
......
}
case VERIFY_CHALLENGE: {
......
}
case GET_SECURE_USER_ID: {
......
}
case CLEAR_SECURE_USER_ID: {
......
}
case REPORT_DEVICE_SETUP_COMPLETE: {
......
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
};
(4)、在的switch case中,调用了gatekeeprd.cpp中的中间函数,以enroll为例
在该函数中,如果硬件hal实现了,则会调用硬件实现的方法,否则调用纯软件逻辑
(system/core/gatekeeperd/gatekeeperd.cpp)
virtual int enroll(uint32_t uid,
const uint8_t *current_password_handle, uint32_t current_password_handle_length,
const uint8_t *current_password, uint32_t current_password_length,
const uint8_t *desired_password, uint32_t desired_password_length,
uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) {
......
if (hw_device != nullptr) {
......
Return<void> hwRes = hw_device->enroll(hw_uid, curPwdHandle, curPwd, newPwd,
[&ret, enrolled_password_handle, enrolled_password_handle_length]
(const GatekeeperResponse &rsp) {
......
} else {
ret = soft_device->enroll(uid,
current_password_handle, current_password_handle_length,
current_password, current_password_length,
desired_password, desired_password_length,
enrolled_password_handle, enrolled_password_handle_length);
}
......
}
(5)、在vendor实现的硬件gatekeeper hal接口中,会发送调用去调用gatekeeper TA
在中调用了TEEC_InvokeCommand,发送命令到TA中干活.
(vendor/mediatek/proprietary/trustzone/microtrust/source/common/300/gatekeeper/ut_gatekeeper.cpp)
static int ut_gk_enroll(const struct gatekeeper_device* dev, uint32_t uid,
const uint8_t* current_password_handle,
uint32_t current_password_handle_length, const uint8_t* current_password,
uint32_t current_password_length, const uint8_t* desired_password,
uint32_t desired_password_length, uint8_t** enrolled_password_handle,
uint32_t* enrolled_password_handle_length)
{
......
if (!ut_gk_transfer_buff(gatekeeper_transfer_buffer))
......
return ret;
}
主要看enroll和verify函数:
(函数原型)
int (*enroll)(const struct gatekeeper_device *dev, uint32_t uid,
const uint8_t *current_password_handle, uint32_t current_password_handle_length,
const uint8_t *current_password, uint32_t current_password_length,
const uint8_t *desired_password, uint32_t desired_password_length,
uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length);
int (*verify)(const struct 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_t provided_password_length,
uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll);
password参数解释:
【enroll】
current_password_handle : 注册信息, 第一次注册时为空
current_password : 原来的密码(需要验证的密码),第一次注册时为空
desired_password : 录入的密码
enrolled_password_handle : 返回给android的注册信息,需要android来保存
【verify】
enrolled_password_handle : 当前的注册信息
provided_password : 需要验证的密码
enroll的返回信息,也就是对enrolled_password_handle变量的填充
填充的类型:
system/gatekeeper/include/gatekeeper/password_handle.h
struct attribute ((packed)) password_handle_t {
uint8_t version;
secure_id_t user_id;
uint64_t flags;
salt_t salt;
uint8_t signature[32];
bool hardware_backed;
};
TEE中的填充方法:
enrolled_password_handle->version = handle_version
enrolled_password_handle->salt = salt
enrolled_password_handle->user_id = user_id
enrolled_password_handle->flags = flags
enrolled_password_handle->hardware_backed = gkbase->IsHardwareBacked()
enrolled_password_handle->signature
解释:
handle_version : 在tee中写死的2
salt : 每次enroll时,在tee中GetRandom随机生成
user_id : 第一次enroll时,在tee中GetRandom随机生成.其实就是SID
flags : throttle flag
hardware_backed : 为1
signature : 对密码的签名后数据
(1)、上层一些程序的总结
(service) 路径
frameworks/base/services/core/java/com/android/server/locksettings/
LockSettingsService.java LockSettingsStorage.java PasswordSlotManager.java SyntheticPasswordCrypto.java recoverablekeystore
LockSettingsShellCommand.java LockSettingsStrongAuth.java SP800Derive.java SyntheticPasswordManager.java
frameworks/base/services/core/java/com/android/server/biometrics/fingerprint/
FingerprintConstants.java FingerprintService.java FingerprintUserState.java FingerprintUtils.java
frameworks/base/services/core/java/com/android/server/biometrics/face/
FaceConstants.java FaceService.java FaceUserState.java FaceUtils.java
(Manager) 路径
frameworks/base/services/core/java/com/android/server/locksettings/
LockSettingsService.java LockSettingsStorage.java PasswordSlotManager.java SyntheticPasswordCrypto.java recoverablekeystore
LockSettingsShellCommand.java LockSettingsStrongAuth.java SP800Derive.java SyntheticPasswordManager.java
(AIDL) 路径
frameworks/base/core/java/android/service/gatekeeper
GateKeeperResponse.aidl GateKeeperResponse.java IGateKeeperService.aidl
frameworks/base/core/java/android/hardware/face/
Fingerprint.aidl Fingerprint.java FingerprintManager.java IFingerprintClientActiveCallback.aidl IFingerprintService.aidl IFingerprintServiceReceiver.aidl
frameworks/base/core/java/android/hardware/fingerprint/
Face.aidl Face.java FaceManager.java IFaceService.aidl IFaceServiceReceiver.aidl