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

 

 

未完待续...

转载于:https://www.cnblogs.com/ash1/p/6350253.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值