在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,
未完待續...