在Android M上,google改变了之前在java层进行加密的方式, 引入了Gatekeeper ,将密码校验以及相关事务通过HAL层的相关服务进行处理, 完成了对TEE的支持,用以支撑指纹识别等硬件安全特性,于此同时 普通的锁屏加密方式安全性也由于此项更新得到了大大的提升,整个系统的安全性得到了很大的加强,那么新引入的特性是如何与上层进行交互以及如何工作的呢,我们这就一探究竟:
首先我们看看该模块的目录结构:
├── Android.mk
├── gatekeeperd.cpp
├── IGateKeeperService.cpp
├── IGateKeeperService.h
├── IUserManager.cpp
├── IUserManager.h
├── SoftGateKeeperDevice.cpp
├── SoftGateKeeperDevice.h
├── SoftGateKeeper.h
└── tests
├── Android.mk
└── gatekeeper_test.cpp
可以看到该目录的结构十分简单,只有四个关键的文件,我们找到入口方法位于gatekeeperd中:
1 int main(int argc, char* argv[]) { 2 ALOGI("Starting gatekeeperd..."); 3 if (argc < 2) { 4 ALOGE("A directory must be specified!"); 5 return 1; 6 } 7 if (chdir(argv[1]) == -1) { 8 ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 9 return 1; 10 } 11 12 android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 13 android::sp<android::GateKeeperProxy> proxy = new android::GateKeeperProxy(); 14 android::status_t ret = sm->addService( 15 android::String16("android.service.gatekeeper.IGateKeeperService"), proxy); 16 if (ret != android::OK) { 17 ALOGE("Couldn't register binder service!"); 18 return -1; 19 } 20 21 /* 22 * We're the only thread in existence, so we're just going to process 23 * Binder transaction as a single-threaded program. 24 */ 25 android::IPCThreadState::self()->joinThreadPool(); 26 return 0; 27 }
这里通过serviceManager将GateKeeperProxy加入servicelist,由此可想而知,该模块是通过Binder与其他模块交互的,其中包括fwk.
我们继续看到GateKeeperProxy中:
1 int ret = hw_get_module_by_class(GATEKEEPER_HARDWARE_MODULE_ID, NULL, &module); 2 device = NULL; 3 4 if (ret < 0) { 5 ALOGW("falling back to software GateKeeper"); 6 soft_device.reset(new SoftGateKeeperDevice()); 7 } else { 8 ret = gatekeeper_open(module, &device); 9 if (ret < 0) 10 LOG_ALWAYS_FATAL_IF(ret < 0, "Unable to open GateKeeper HAL"); 11 } 12 13 if (mark_cold_boot()) { 14 ALOGI("cold boot: clearing state"); 15 if (device != NULL && device->delete_all_users != NULL) { 16 device->delete_all_users(device); 17 } 18 }
以上片段为GateKeeperProxy的构造方法,可以看到这里主要是初始化硬件设备(TEE),当硬件设备不可及时,会启用SoftGateKeeperDevice.
既然我们之前判断该模块是通过IPC向其他模块提供服务的,那么我们看看IInterface的定义:
1 class IGateKeeperService : public IInterface { 2 public: 3 enum { 4 ENROLL = IBinder::FIRST_CALL_TRANSACTION + 0, 5 VERIFY = IBinder::FIRST_CALL_TRANSACTION + 1, 6 VERIFY_CHALLENGE = IBinder::FIRST_CALL_TRANSACTION + 2, 7 GET_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 3, 8 CLEAR_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 4, 9 }; 10 11 enum { 12 GATEKEEPER_RESPONSE_OK = 0, 13 GATEKEEPER_RESPONSE_RETRY = 1, 14 GATEKEEPER_RESPONSE_ERROR = -1, 15 }; 16 17 // DECLARE_META_INTERFACE - C++ client interface not needed 18 static const android::String16 descriptor; 19 virtual const android::String16& getInterfaceDescriptor() const; 20 IGateKeeperService() {} 21 virtual ~IGateKeeperService() {} 22 23 /** 24 * Enrolls a password with the GateKeeper. Returns 0 on success, negative on failure. 25 * Returns: 26 * - 0 on success 27 * - A timestamp T > 0 if the call has failed due to throttling and should not 28 * be reattempted until T milliseconds have elapsed 29 * - -1 on failure 30 */ 31 virtual int enroll(uint32_t uid, 32 const uint8_t *current_password_handle, uint32_t current_password_handle_length, 33 const uint8_t *current_password, uint32_t current_password_length, 34 const uint8_t *desired_password, uint32_t desired_password_length, 35 uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length) = 0; 36 37 /** 38 * Verifies a password previously enrolled with the GateKeeper. 39 * Returns: 40 * - 0 on success 41 * - A timestamp T > 0 if the call has failed due to throttling and should not 42 * be reattempted until T milliseconds have elapsed 43 * - -1 on failure 44 */ 45 virtual int verify(uint32_t uid, const uint8_t *enrolled_password_handle, 46 uint32_t enrolled_password_handle_length, 47 const uint8_t *provided_password, uint32_t provided_password_length, 48 bool *request_reenroll) = 0; 49 50 /** 51 * Verifies a password previously enrolled with the GateKeeper. 52 * Returns: 53 * - 0 on success 54 * - A timestamp T > 0 if the call has failed due to throttling and should not 55 * be reattempted until T milliseconds have elapsed 56 * - -1 on failure 57 */ 58 virtual int verifyChallenge(uint32_t uid, uint64_t challenge, 59 const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, 60 const uint8_t *provided_password, uint32_t provided_password_length, 61 uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll) = 0; 62 /** 63 * Returns the secure user ID for the provided android user 64 */ 65 virtual uint64_t getSecureUserId(uint32_t uid) = 0; 66 67 /** 68 * Clears the secure user ID associated with the user. 69 */ 70 virtual void clearSecureUserId(uint32_t uid) = 0; 71 };
可以看到这里提供的方法并不多,fwk主要调用的是verify函数(分析fwk代码得知),那我们这里就主要跟踪一下verify的流程,进入onTransact函数的Verify case经过一系列的调用,最终会调用到verifyChallenge:
1 virtual int verifyChallenge(uint32_t uid, uint64_t challenge, 2 const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, 3 const uint8_t *provided_password, uint32_t provided_password_length, 4 uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll) { 5 IPCThreadState* ipc = IPCThreadState::self(); 6 const int calling_pid = ipc->getCallingPid(); 7 const int calling_uid = ipc->getCallingUid(); 8 if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) { 9 return PERMISSION_DENIED; 10 } 11 12 // can't verify if we're missing either param 13 if ((enrolled_password_handle_length | provided_password_length) == 0) 14 return -EINVAL; 15 16 int ret; 17 if (device) { 18 const gatekeeper::password_handle_t *handle = 19 reinterpret_cast<const gatekeeper::password_handle_t *>(enrolled_password_handle); 20 // handle version 0 does not have hardware backed flag, and thus cannot be upgraded to 21 // a HAL if there was none before 22 if (handle->version == 0 || handle->hardware_backed) { 23 ret = device->verify(device, uid, challenge, 24 enrolled_password_handle, enrolled_password_handle_length, 25 provided_password, provided_password_length, auth_token, auth_token_length, 26 request_reenroll); 27 } else { 28 // upgrade scenario, a HAL has been added to this device where there was none before 29 SoftGateKeeperDevice soft_dev; 30 ret = soft_dev.verify(uid, challenge, 31 enrolled_password_handle, enrolled_password_handle_length, 32 provided_password, provided_password_length, auth_token, auth_token_length, 33 request_reenroll); 34 35 if (ret == 0) { 36 // success! re-enroll with HAL 37 *request_reenroll = true; 38 } 39 } 40 } else { 41 ret = soft_device->verify(uid, challenge, 42 enrolled_password_handle, enrolled_password_handle_length, 43 provided_password, provided_password_length, auth_token, auth_token_length, 44 request_reenroll); 45 } 46 47 if (ret == 0 && *auth_token != NULL && *auth_token_length > 0) { 48 // TODO: cache service? 49 sp<IServiceManager> sm = defaultServiceManager(); 50 sp<IBinder> binder = sm->getService(String16("android.security.keystore")); 51 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder); 52 if (service != NULL) { 53 status_t ret = service->addAuthToken(*auth_token, *auth_token_length); 54 if (ret != ResponseCode::NO_ERROR) { 55 ALOGE("Falure sending auth token to KeyStore: %d", ret); 56 } 57 } else { 58 ALOGE("Unable to communicate with KeyStore"); 59 } 60 } 61 62 if (ret == 0) { 63 maybe_store_sid(uid, reinterpret_cast<const gatekeeper::password_handle_t *>( 64 enrolled_password_handle)->user_id); 65 } 66 67 return ret; 68 }
这里首先会进行一些权限的验证以及密码合法性的验证,然后会判断当前可用GateKeeper设备,由于我们这里只分析softGateKeeper,我们直接跳入soft_device,即SoftGateKeeperDevice后,通过impl_调用到SoftGateKeeper中:
这个类,我们先看一下定义:class SoftGateKeeper : public GateKeeper ,首先该类继承自GateKeeper,
未完待续...