[Android]鎖屏密碼校驗Gatekeeper-SoftGatekeeper


在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,

 

 

未完待續...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM