Jimmy Chen

A Programmer

(原创)Android FBE加密源码分析(二)

上一篇最后讲到,dispatchCommand是通过调用runCommand来执行具体的CMD操作,这一篇会接着说明。在进行说明前,需要先了解FBE的一些内容,为什么需要这些内容呢?因为在接下来的分析会涉及到CE、DE的存储位置,所以需要先了解。

全盘加密和文件级加密的区别

  借助文件级加密,Android 7.0 中引入了一项称为直接启动的新功能。该功能处于启用状态时,已加密设备在启动后将直接进入锁定屏幕。之前,在使用全盘加密 (FDE) 的已加密设备上,用户在访问任何数据之前都需要先提供凭据,从而导致手机无法执行除最基本操作之外的所有其他操作。例如,闹钟无法运行,无障碍服务不可用,手机无法接电话,而只能进行基本的紧急拨号操作。

文件级加密概述

  引入文件级加密 (FBE) 和新 API 后,便可以将应用设为加密感知型应用,这样一来,它们将能够在受限环境中运行。这些应用将可以在用户提供凭据之前运行,同时系统仍能保护私密用户信息。

在启用了 FBE 的设备上,每位用户均有两个可供应用使用的存储位置:

  • 凭据加密 (CE) 存储空间:这是默认存储位置,只有在用户解锁设备后才可用。
  • 设备加密 (DE) 存储空间:在直接启动模式期间以及用户解锁设备后均可用。

这种区分能够使工作资料更加安全,因为这样一来,加密不再只基于启动时密码,从而能够同时保护多位用户。好了,这里就先了解这么多,如果需要更详细的分析大家可以看Android文档的描述或者找其他博客看看。

帅气分割线

根据虚函数和继承关系,最后调用的runCommand是CryptCommandListener::CryptfsCmd::runCommand,另外大家回想下,之前在client端传进来command是CMD=”PID cryptfs enablefilecrypto”,记住这个下面要对这个CMD进行解析了。

CryptCommandListener::CryptfsCmd::runCommand

runCommand –> e4crypt_initialize_global_de

e4crypt_initialize_global_de –> retrieveAndInstallKey

这样,DE key就创建完成了。至于installKey、retrieveKey之类的函数具体是怎么样产生key的留做以后学习分析。有兴趣的童鞋也可以自行看,这里就先不扩展讲解了。接下来看看CE key是如何生成的。

回到post-fs-data阶段

在post-fs-data阶段的最后部分,有一个init_user0的动作

这里init_user0对应的函数是do_init_user0

do_init_user0

看这个代码和上一篇博客中do_installKey的代码是类似的,最后也是通过vdc,传送init_user0进行最后的操作。调用启动过程这里就简略了,直接分析CryptCommandListener的runCommand是如何处理init_user0的。

CryptCommandListener::runCommand

runCommand –> e4crypt_init_user0

e4crypt_init_user0 –> create_and_install_user_keys

到这里,用户的DE和CE key都已经有了。问题是,在installKey的时候也已经产生过DE key了,这里为什么还需要再生成一次DE key呢?这里留个疑问,具体到时候还得看看,不过看回installKey部分的代码,猜测installkey生成的DE key应该是全局DE key,init_user0的DE key是用户DE key,所以是两组不同的key。

key已经有了,接下来就是使用key对文件进行加解密了。判断哪些文件需要进行加解密实在init.rc中通过mkdir的时候记性的,init.rc中mkdir动作,是通过do_mkdir函数进行的。

do_mkdir

do_mkdir函数前面的代码基本就是判断参数,根据参数创建对应的文件夹,而对应加密规则的设置则是在最后面部分。我们只分析最后面部分即可。

do_mkdir –> e4crypt_set_directory_policy

e4crypt_set_directory_policy —> set_system_de_policy_on

set_system_de_policy_on —> e4crypt_policy_ensure

contents_encryption_mode和filenames_mode在installKey的时候就有设置过了,类似于contents_mode = “ice”,filenames_mode = “aes-256-cts”。

e4crypt_policy_ensure —> e4crypt_policy_set

到这里设置就做完了。FBE大概就了解这么多,但是感觉还是不够深入,后续有机会再多做些分析吧。

  1. cigogo说道:

    看博主对这块研究比较深。
    我这边有个疑问,系统默认只支持data分区的FDE功能,如果想添加一个自己增加分区,进行FDE支持,系统是否可以支持,有什么可以借鉴或者注意的地方? :smile:

    1. jimmychen说道:

      既然data分区支持FDE加密,那按照启动时的data分区FDE加载流程修改一下,应该是可以支持其他分区进行FDE加密的

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注