在密码或指纹验证通过后(verify通过后),需返回一个authToken值,然后交由keystore保持起来. 以下是gatekeeper的verify产生authToken和调用keystore保存authToken的流程图:
在gatekeeper TA的verify()通过后,对填充authToken结构体,然后再返回。
(hardware/libhardware/include/hardware/hw_auth_token.h)
typedef struct __attribute__((__packed__)) {
uint8_t version; // Current version is 0
uint64_t challenge;
uint64_t user_id; // secure user ID, not Android user ID
uint64_t authenticator_id; // secure authenticator ID
uint32_t authenticator_type; // hw_authenticator_type_t, in network order
uint64_t timestamp; // in network order
uint8_t hmac[32];
} hw_auth_token_t;
质询 : challenge
用户SID :user_id
身份验证程序 ID (ASID) : authenticator_id
身份验证程序类型 : authenticator_type,00-gatekeeper,01-指纹
在gatekeeperd中调用hw_device->verify()后,先判断authToken,如果为空,则认为是verify失败(鉴权失败)。如果不为空,则认为verify成功. 并调用addAuthToken将authToken保持下来
以下是authToken的使用逻辑,同底层硬件/TEE无关
在gatekeeperd的verifychallange中hw_device->verify()结束后,调用keystore的addAuthToken方法,将authToken保存下来
(system/core/gatekeeperd$ vim gatekeeperd.cpp)
if (ret == 0 && *auth_token != NULL && *auth_token_length > 0) {
// TODO: cache service?
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
sp<security::keystore::IKeystoreService> service =
interface_cast<security::keystore::IKeystoreService>(binder);
if (service != NULL) {
std::vector<uint8_t> auth_token_vector(*auth_token,
(*auth_token) + *auth_token_length);
int result = 0;
auto binder_result = service->addAuthToken(auth_token_vector, &result);
if (!binder_result.isOk() || !keystore::KeyStoreServiceReturnCode(result).isOk()) {
ALOGE("Failure sending auth token to KeyStore: %" PRId32, result);
}
} else {
ALOGE("Unable to communicate with KeyStore");
}
}
(frameworks/base/keystore/java/android/security/KeyStore.java)
public int addAuthToken(byte[] authToken) {
try {
return mBinder.addAuthToken(authToken);
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
}
}
(system/security/keystore/key_store_service.cpp)
Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
int32_t* aidl_return) {
KEYSTORE_SERVICE_LOCK;
// TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
// receive a HardwareAuthToken, rather than an opaque byte array.
if (!checkBinderPermission(P_ADD_AUTH)) {
ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
*aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
return Status::ok();
}
if (authTokenAsVector.size() != sizeof(hw_auth_token_t)) {
*aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
return Status::ok();
}
hw_auth_token_t authToken;
memcpy(reinterpret_cast<void*>(&authToken), authTokenAsVector.data(), sizeof(hw_auth_token_t));
if (authToken.version != 0) {
*aidl_return = KeyStoreServiceReturnCode(ErrorCode::INVALID_ARGUMENT).getErrorCode();
return Status::ok();
}
mKeyStore->getAuthTokenTable().AddAuthenticationToken(
hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
*aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
return Status::ok();
}
max_entries_等于32,authToken的个数小于32,则直接将此authToken压入表中,若大于32则替换一个最小的
(system/security/keystore/auth_token_table.cpp)
void AuthTokenTable::AddAuthenticationToken(HardwareAuthToken&& auth_token) {
Entry new_entry(std::move(auth_token), clock_function_());
// STOPSHIP: debug only, to be removed
ALOGD("AddAuthenticationToken: timestamp = %llu, time_received = %lld",
static_cast<unsigned long long>(new_entry.token().timestamp),
static_cast<long long>(new_entry.time_received()));
std::lock_guard<std::mutex> lock(entries_mutex_);
RemoveEntriesSupersededBy(new_entry);
if (entries_.size() >= max_entries_) {
ALOGW("Auth token table filled up; replacing oldest entry");
*min_element(entries_) = std::move(new_entry);
} else {
entries_.push_back(std::move(new_entry));
}
}