当前位置: 首页 > news >正文

广州公司营销型网站建设百度平台app下载

广州公司营销型网站建设,百度平台app下载,友情链接是什么,学软件工程培训就业机构上一篇最后讲到,dispatchCommand是通过调用runCommand来执行具体的CMD操作,这一篇会接着说明。在进行说明前,需要先了解FBE的一些内容,为什么需要这些内容呢?因为在接下来的分析会涉及到CE、DE的存储位置,所…

上一篇最后讲到,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

int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,

int argc, char **argv) {

// 验证执行操作的进行的用户的权限

if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {

cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run cryptfs commands", false);

return 0;

}

if (argc < 2) {

cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing subcommand", false);

return 0;

}

int rc = 0;

std::string subcommand(argv[1]);

// 根据subcommand进行选择,这里是"enablefilecrypto",下面直接分析这个CMD

if (subcommand == "checkpw") {

if (!check_argc(cli, subcommand, argc, 3, "")) return 0;

dumpArgs(argc, argv, 2);

..................

} else if (subcommand == "enablefilecrypto") {

if (!check_argc(cli, subcommand, argc, 2, "")) return 0;

dumpArgs(argc, argv, -1);

// easy,什么都不做,调用e4crypt_initialize_global_de来完成

rc = e4crypt_initialize_global_de();

} else if (subcommand == "changepw") {

.................

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

intCryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,

intargc,char**argv){

// 验证执行操作的进行的用户的权限

if((cli->getUid()!=0)&&(cli->getUid()!=AID_SYSTEM)){

cli->sendMsg(ResponseCode::CommandNoPermission,"No permission to run cryptfs commands",false);

return0;

}

if(argc<2){

cli->sendMsg(ResponseCode::CommandSyntaxError,"Missing subcommand",false);

return0;

}

intrc=0;

std::stringsubcommand(argv[1]);

// 根据subcommand进行选择,这里是"enablefilecrypto",下面直接分析这个CMD

if(subcommand=="checkpw"){

if(!check_argc(cli,subcommand,argc,3,""))return0;

dumpArgs(argc,argv,2);

..................

}elseif(subcommand=="enablefilecrypto"){

if(!check_argc(cli,subcommand,argc,2,""))return0;

dumpArgs(argc,argv,-1);

// easy,什么都不做,调用e4crypt_initialize_global_de来完成

rc=e4crypt_initialize_global_de();

}elseif(subcommand=="changepw"){

.................

runCommand –> e4crypt_initialize_global_de

bool e4crypt_initialize_global_de() {

LOG(INFO) << "e4crypt_initialize_global_de";

if (s_global_de_initialized) {

LOG(INFO) << "Already initialized";

return true;

}

/*

* 最后经过函数调用和赋值后

* contents_mode = "ice"

* filenames_mode = "aes-256-cts"

* mode_filename = /data/unencrypted/mode

*/

const char *contents_mode;

const char *filenames_mode;

cryptfs_get_file_encryption_modes(&contents_mode, &filenames_mode);

std::string modestring = std::string(contents_mode) + ":" + filenames_mode;

std::string mode_filename = std::string("/data") + e4crypt_key_mode;

if (!android::base::WriteStringToFile(modestring, mode_filename)) {

PLOG(ERROR) << "Cannot save type";

return false;

}

std::string device_key_ref;

// 调用retrieveAndInstallKey创建秘钥

if (!android::vold::retrieveAndInstallKey(true,

device_key_path, device_key_temp, &device_key_ref)) return false;

// 最后应用秘钥

std::string ref_filename = std::string("/data") + e4crypt_key_ref;

if (!android::base::WriteStringToFile(device_key_ref, ref_filename)) {

PLOG(ERROR) << "Cannot save key reference to:" << ref_filename;

return false;

}

LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;

s_global_de_initialized = true;

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

boole4crypt_initialize_global_de(){

LOG(INFO)<

if(s_global_de_initialized){

LOG(INFO)<

returntrue;

}

/*

* 最后经过函数调用和赋值后

* contents_mode = "ice"

* filenames_mode = "aes-256-cts"

* mode_filename = /data/unencrypted/mode

*/

constchar*contents_mode;

constchar*filenames_mode;

cryptfs_get_file_encryption_modes(&contents_mode,&filenames_mode);

std::stringmodestring=std::string(contents_mode)+":"+filenames_mode;

std::stringmode_filename=std::string("/data")+e4crypt_key_mode;

if(!android::base::WriteStringToFile(modestring,mode_filename)){

PLOG(ERROR)<

returnfalse;

}

std::stringdevice_key_ref;

// 调用retrieveAndInstallKey创建秘钥

if(!android::vold::retrieveAndInstallKey(true,

device_key_path,device_key_temp,&device_key_ref))returnfalse;

// 最后应用秘钥

std::stringref_filename=std::string("/data")+e4crypt_key_ref;

if(!android::base::WriteStringToFile(device_key_ref,ref_filename)){

PLOG(ERROR)<

returnfalse;

}

LOG(INFO)<

s_global_de_initialized=true;

returntrue;

}

e4crypt_initialize_global_de –> retrieveAndInstallKey

/*

* create_if_absent = true

* key_path = /data/unencrypted/key

* tmp_path = /data/unencrypted/tmp

*/

bool retrieveAndInstallKey(bool create_if_absent, const std::string& key_path,

const std::string& tmp_path, std::string* key_ref) {

KeyBuffer key;

// 路径已存在

if (pathExists(key_path)) {

LOG(DEBUG) << "Key exists, using: " << key_path;

if (!retrieveKey(key_path, kEmptyAuthentication, &key)) return false;

} else {

if (!create_if_absent) {

LOG(ERROR) << "No key found in " << key_path;

return false;

}

LOG(INFO) << "Creating new key in " << key_path;

// 创建DE秘钥

if (!randomKey(&key)) return false;

// 保存DE秘钥

if (!storeKeyAtomically(key_path, tmp_path,

kEmptyAuthentication, key)) return false;

}

// 存储秘钥到秘钥库中

if (!installKey(key, key_ref)) {

LOG(ERROR) << "Failed to install key in " << key_path;

return false;

}

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/*

* create_if_absent = true

* key_path = /data/unencrypted/key

* tmp_path = /data/unencrypted/tmp

*/

boolretrieveAndInstallKey(boolcreate_if_absent,conststd::string&key_path,

conststd::string&tmp_path,std::string*key_ref){

KeyBufferkey;

// 路径已存在

if(pathExists(key_path)){

LOG(DEBUG)<

if(!retrieveKey(key_path,kEmptyAuthentication,&key))returnfalse;

}else{

if(!create_if_absent){

LOG(ERROR)<

returnfalse;

}

LOG(INFO)<

// 创建DE秘钥

if(!randomKey(&key))returnfalse;

// 保存DE秘钥

if(!storeKeyAtomically(key_path,tmp_path,

kEmptyAuthentication,key))returnfalse;

}

// 存储秘钥到秘钥库中

if(!installKey(key,key_ref)){

LOG(ERROR)<

returnfalse;

}

returntrue;

}

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

回到post-fs-data阶段

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

on post-fs-data

.......

mkdir /data/cache/backup 0700 system system

init_user0

# Set SELinux security contexts on upgrade or policy update.

restorecon --recursive --skip-ce /data

.......

1

2

3

4

5

6

7

8

9

onpost-fs-data

.......

mkdir/data/cache/backup0700systemsystem

init_user0

# Set SELinux security contexts on upgrade or policy update.

restorecon--recursive--skip-ce/data

.......

这里init_user0对应的函数是do_init_user0

do_init_user0

static int do_init_user0(const std::vector<:string>& args) {

std::vector<:string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",

"init_user0"};

return do_exec(exec_args);

}

1

2

3

4

5

staticintdo_init_user0(conststd::vector<:string>&args){

std::vector<:string>exec_args={"exec","/system/bin/vdc","--wait","cryptfs",

"init_user0"};

returndo_exec(exec_args);

}

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

CryptCommandListener::runCommand

int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,

int argc, char **argv) {

.................

rc = cryptfs_isConvertibleToFBE();

} else if (subcommand == "init_user0") {

if (!check_argc(cli, subcommand, argc, 2, "")) return 0;

// sendGenericOkFailOnBool会根据e4crypt_init_user0调用返回值给client端发送对应的信息

return sendGenericOkFailOnBool(cli, e4crypt_init_user0());

} else if (subcommand == "create_user_key") {

................

}

1

2

3

4

5

6

7

8

9

10

11

12

13

intCryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,

intargc,char**argv){

.................

rc=cryptfs_isConvertibleToFBE();

}elseif(subcommand=="init_user0"){

if(!check_argc(cli,subcommand,argc,2,""))return0;

// sendGenericOkFailOnBool会根据e4crypt_init_user0调用返回值给client端发送对应的信息

returnsendGenericOkFailOnBool(cli,e4crypt_init_user0());

}elseif(subcommand=="create_user_key"){

................

}

runCommand –> e4crypt_init_user0

bool e4crypt_init_user0() {

LOG(DEBUG) << "e4crypt_init_user0";

if (e4crypt_is_native()) {

// 准备存储key的文件夹,user_key_dir = "/data/misc/vold/user_keys"

if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;

if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;

if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;

if (!android::vold::pathExists(get_de_key_path(0))) {

// 创建user0使用的key

if (!create_and_install_user_keys(0, false)) return false;

}

// 加载所有用户使用的DE key

if (!load_all_de_keys()) return false;

}

// 准备user的DE存储空间

if (!e4crypt_prepare_user_storage(nullptr, 0, 0, FLAG_STORAGE_DE)) {

LOG(ERROR) << "Failed to prepare user 0 storage";

return false;

}

// 不是用FBE就解锁

if (!e4crypt_is_native() && !e4crypt_is_emulated()) {

e4crypt_unlock_user_key(0, 0, "!", "!");

}

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

boole4crypt_init_user0(){

LOG(DEBUG)<

if(e4crypt_is_native()){

// 准备存储key的文件夹,user_key_dir = "/data/misc/vold/user_keys"

if(!prepare_dir(user_key_dir,0700,AID_ROOT,AID_ROOT))returnfalse;

if(!prepare_dir(user_key_dir+"/ce",0700,AID_ROOT,AID_ROOT))returnfalse;

if(!prepare_dir(user_key_dir+"/de",0700,AID_ROOT,AID_ROOT))returnfalse;

if(!android::vold::pathExists(get_de_key_path(0))){

// 创建user0使用的key

if(!create_and_install_user_keys(0,false))returnfalse;

}

// 加载所有用户使用的DE key

if(!load_all_de_keys())returnfalse;

}

// 准备user的DE存储空间

if(!e4crypt_prepare_user_storage(nullptr,0,0,FLAG_STORAGE_DE)){

LOG(ERROR)<

returnfalse;

}

// 不是用FBE就解锁

if(!e4crypt_is_native()&&!e4crypt_is_emulated()){

e4crypt_unlock_user_key(0,0,"!","!");

}

returntrue;

}

e4crypt_init_user0 –> create_and_install_user_keys

// NB this assumes that there is only one thread listening for crypt commands, because

// it creates keys in a fixed location.

static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) {

KeyBuffer de_key, ce_key;

// 产生CE和DE key

if (!android::vold::randomKey(&de_key)) return false;

if (!android::vold::randomKey(&ce_key)) return false;

// create_ephemeral为false

if (create_ephemeral) {

// If the key should be created as ephemeral, don't store it.

s_ephemeral_users.insert(user_id);

} else {

// 获取CE key保存的路径

auto const directory_path = get_ce_key_directory_path(user_id);

if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false;

auto const paths = get_ce_key_paths(directory_path);

std::string ce_key_path;

// 获取CE key保存路径

if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;

// 保存CE key

if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp,

kEmptyAuthentication, ce_key)) return false;

fixate_user_ce_key(directory_path, ce_key_path, paths);

// 保存DE key

if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,

kEmptyAuthentication, de_key)) return false;

}

std::string de_raw_ref;

// 存储DE key到秘钥库

if (!android::vold::installKey(de_key, &de_raw_ref)) return false;

s_de_key_raw_refs[user_id] = de_raw_ref;

std::string ce_raw_ref;

// 存储CE key到秘钥库

if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false;

s_ce_keys[user_id] = ce_key;

s_ce_key_raw_refs[user_id] = ce_raw_ref;

LOG(DEBUG) << "Created keys for user " << user_id;

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

// NB this assumes that there is only one thread listening for crypt commands, because

// it creates keys in a fixed location.

staticboolcreate_and_install_user_keys(userid_tuser_id,boolcreate_ephemeral){

KeyBufferde_key,ce_key;

// 产生CE和DE key

if(!android::vold::randomKey(&de_key))returnfalse;

if(!android::vold::randomKey(&ce_key))returnfalse;

// create_ephemeral为false

if(create_ephemeral){

// If the key should be created as ephemeral, don't store it.

s_ephemeral_users.insert(user_id);

}else{

// 获取CE key保存的路径

autoconstdirectory_path=get_ce_key_directory_path(user_id);

if(!prepare_dir(directory_path,0700,AID_ROOT,AID_ROOT))returnfalse;

autoconstpaths=get_ce_key_paths(directory_path);

std::stringce_key_path;

// 获取CE key保存路径

if(!get_ce_key_new_path(directory_path,paths,&ce_key_path))returnfalse;

// 保存CE key

if(!android::vold::storeKeyAtomically(ce_key_path,user_key_temp,

kEmptyAuthentication,ce_key))returnfalse;

fixate_user_ce_key(directory_path,ce_key_path,paths);

// 保存DE key

if(!android::vold::storeKeyAtomically(get_de_key_path(user_id),user_key_temp,

kEmptyAuthentication,de_key))returnfalse;

}

std::stringde_raw_ref;

// 存储DE key到秘钥库

if(!android::vold::installKey(de_key,&de_raw_ref))returnfalse;

s_de_key_raw_refs[user_id]=de_raw_ref;

std::stringce_raw_ref;

// 存储CE key到秘钥库

if(!android::vold::installKey(ce_key,&ce_raw_ref))returnfalse;

s_ce_keys[user_id]=ce_key;

s_ce_key_raw_refs[user_id]=ce_raw_ref;

LOG(DEBUG)<

returntrue;

}

到这里,用户的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

static int do_mkdir(const std::vector<:string>& args) {

mode_t mode = 0755;

int ret;

...............

// 如果使用FBE

if (e4crypt_is_native()) {

// 设置文件目录加密规则

if (e4crypt_set_directory_policy(args[1].c_str())) {

// 设置失败需要进入recovery模式

const std::vector<:string> options = {

"--prompt_and_wipe_data",

"--reason=set_policy_failed:"s + args[1]};

reboot_into_recovery(options);

return 0;

}

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

staticintdo_mkdir(conststd::vector<:string>&args){

mode_tmode=0755;

intret;

...............

// 如果使用FBE

if(e4crypt_is_native()){

// 设置文件目录加密规则

if(e4crypt_set_directory_policy(args[1].c_str())){

// 设置失败需要进入recovery模式

conststd::vector<:string>options={

"--prompt_and_wipe_data",

"--reason=set_policy_failed:"s+args[1]};

reboot_into_recovery(options);

return0;

}

}

return0;

}

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

do_mkdir –> e4crypt_set_directory_policy

int e4crypt_set_directory_policy(const char* dir)

{

// 判断是否在/data/路径

if (!dir || strncmp(dir, "/data/", 6)) {

return 0;

}

// Special-case /data/media/obb per b/64566063

if (strcmp(dir, "/data/media/obb") == 0) {

// Try to set policy on this directory, but if it is non-empty this may fail.

set_system_de_policy_on(dir);

return 0;

}

if (strchr(dir + 6, '/')) {

return 0;

}

// 不需要处理的文件夹集合,但是底下的文件夹还是会被加密

std::vector<:string> directories_to_exclude = {

"lost+found",

"system_ce", "system_de",

"misc_ce", "misc_de",

"media",

"data", "user", "user_de",

};

std::string prefix = "/data/";

for (auto d: directories_to_exclude) {

if ((prefix + d) == dir) {

LOG(INFO) << "Not setting policy on " << dir;

return 0;

}

}

// 对不在directories_to_exclude的文件夹进行处理

return set_system_de_policy_on(dir);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

inte4crypt_set_directory_policy(constchar*dir)

{

// 判断是否在/data/路径

if(!dir||strncmp(dir,"/data/",6)){

return0;

}

// Special-case /data/media/obb per b/64566063

if(strcmp(dir,"/data/media/obb")==0){

// Try to set policy on this directory, but if it is non-empty this may fail.

set_system_de_policy_on(dir);

return0;

}

if(strchr(dir+6,'/')){

return0;

}

// 不需要处理的文件夹集合,但是底下的文件夹还是会被加密

std::vector<:string>directories_to_exclude={

"lost+found",

"system_ce","system_de",

"misc_ce","misc_de",

"media",

"data","user","user_de",

};

std::stringprefix="/data/";

for(autod:directories_to_exclude){

if((prefix+d)==dir){

LOG(INFO)<

return0;

}

}

// 对不在directories_to_exclude的文件夹进行处理

returnset_system_de_policy_on(dir);

}

e4crypt_set_directory_policy —> set_system_de_policy_on

static int set_system_de_policy_on(char const* dir) {

// 秘钥引用,ref_filename=/data/unencrypted/ref

std::string ref_filename = std::string("/data") + e4crypt_key_ref;

std::string policy;

// 读取秘钥应用内容到policy

if (!android::base::ReadFileToString(ref_filename, &policy)) {

LOG(ERROR) << "Unable to read system policy to set on " << dir;

return -1;

}

// 获取加密模式

auto type_filename = std::string("/data") + e4crypt_key_mode;

std::string modestring;

if (!android::base::ReadFileToString(type_filename, &modestring)) {

LOG(ERROR) << "Cannot read mode";

}

std::vector<:string> modes = android::base::Split(modestring, ":");

if (modes.size() < 1 || modes.size() > 2) {

LOG(ERROR) << "Invalid encryption mode string: " << modestring;

return -1;

}

LOG(INFO) << "Setting policy on " << dir;

// 设置加密

int result = e4crypt_policy_ensure(dir, policy.c_str(), policy.length(),

modes[0].c_str(),

modes.size() >= 2 ?

modes[1].c_str() : "aes-256-cts");

if (result) {

LOG(ERROR) << android::base::StringPrintf(

"Setting %02x%02x%02x%02x policy on %s failed!",

policy[0], policy[1], policy[2], policy[3], dir);

return -1;

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

staticintset_system_de_policy_on(charconst*dir){

// 秘钥引用,ref_filename=/data/unencrypted/ref

std::stringref_filename=std::string("/data")+e4crypt_key_ref;

std::stringpolicy;

// 读取秘钥应用内容到policy

if(!android::base::ReadFileToString(ref_filename,&policy)){

LOG(ERROR)<

return-1;

}

// 获取加密模式

autotype_filename=std::string("/data")+e4crypt_key_mode;

std::stringmodestring;

if(!android::base::ReadFileToString(type_filename,&modestring)){

LOG(ERROR)<

}

std::vector<:string>modes=android::base::Split(modestring,":");

if(modes.size()<1||modes.size()>2){

LOG(ERROR)<

return-1;

}

LOG(INFO)<

// 设置加密

intresult=e4crypt_policy_ensure(dir,policy.c_str(),policy.length(),

modes[0].c_str(),

modes.size()>=2?

modes[1].c_str():"aes-256-cts");

if(result){

LOG(ERROR)<<:base::stringprintf>

"Setting %02x%02x%02x%02x policy on %s failed!",

policy[0],policy[1],policy[2],policy[3],dir);

return-1;

}

return0;

}

set_system_de_policy_on —> e4crypt_policy_ensure

int e4crypt_policy_ensure(const char *directory, const char *policy,

size_t policy_length,

const char *contents_encryption_mode,

const char *filenames_encryption_mode) {

int contents_mode = 0;

int filenames_mode = 0;

if (!strcmp(contents_encryption_mode, "software") ||

!strcmp(contents_encryption_mode, "aes-256-xts")) {

contents_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;

} else if (!strcmp(contents_encryption_mode, "ice")) {

contents_mode = EXT4_ENCRYPTION_MODE_PRIVATE;

} else {

LOG(ERROR) << "Invalid file contents encryption mode: "

<< contents_encryption_mode;

return -1;

}

if (!strcmp(filenames_encryption_mode, "aes-256-cts")) {

filenames_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS;

} else if (!strcmp(filenames_encryption_mode, "aes-256-heh")) {

filenames_mode = EXT4_ENCRYPTION_MODE_AES_256_HEH;

} else {

LOG(ERROR) << "Invalid file names encryption mode: "

<< filenames_encryption_mode;

return -1;

}

bool is_empty;

if (!is_dir_empty(directory, &is_empty)) return -1;

if (is_empty) {

// 设置加密

if (!e4crypt_policy_set(directory, policy, policy_length,

contents_mode, filenames_mode)) return -1;

} else {

if (!e4crypt_policy_check(directory, policy, policy_length,

contents_mode, filenames_mode)) return -1;

}

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

inte4crypt_policy_ensure(constchar*directory,constchar*policy,

size_tpolicy_length,

constchar*contents_encryption_mode,

constchar*filenames_encryption_mode){

intcontents_mode=0;

intfilenames_mode=0;

if(!strcmp(contents_encryption_mode,"software")||

!strcmp(contents_encryption_mode,"aes-256-xts")){

contents_mode=EXT4_ENCRYPTION_MODE_AES_256_XTS;

}elseif(!strcmp(contents_encryption_mode,"ice")){

contents_mode=EXT4_ENCRYPTION_MODE_PRIVATE;

}else{

LOG(ERROR)<

<

return-1;

}

if(!strcmp(filenames_encryption_mode,"aes-256-cts")){

filenames_mode=EXT4_ENCRYPTION_MODE_AES_256_CTS;

}elseif(!strcmp(filenames_encryption_mode,"aes-256-heh")){

filenames_mode=EXT4_ENCRYPTION_MODE_AES_256_HEH;

}else{

LOG(ERROR)<

<

return-1;

}

boolis_empty;

if(!is_dir_empty(directory,&is_empty))return-1;

if(is_empty){

// 设置加密

if(!e4crypt_policy_set(directory,policy,policy_length,

contents_mode,filenames_mode))return-1;

}else{

if(!e4crypt_policy_check(directory,policy,policy_length,

contents_mode,filenames_mode))return-1;

}

return0;

}

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

e4crypt_policy_ensure —> e4crypt_policy_set

static bool e4crypt_policy_set(const char *directory, const char *policy,

size_t policy_length,

int contents_encryption_mode,

int filenames_encryption_mode) {

if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) {

LOG(ERROR) << "Policy wrong length: " << policy_length;

return false;

}

int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);

if (fd == -1) {

PLOG(ERROR) << "Failed to open directory " << directory;

return false;

}

// 设置ext4加密规则

ext4_encryption_policy eep;

eep.version = 0;

eep.contents_encryption_mode = contents_encryption_mode;

eep.filenames_encryption_mode = filenames_encryption_mode;

eep.flags = e4crypt_get_policy_flags(filenames_encryption_mode);

memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE);

// 调用IOCTL设置加密规则

if (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep)) {

PLOG(ERROR) << "Failed to set encryption policy for " << directory;

close(fd);

return false;

}

close(fd);

char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];

policy_to_hex(policy, policy_hex);

LOG(INFO) << "Policy for " << directory << " set to " << policy_hex;

return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

staticboole4crypt_policy_set(constchar*directory,constchar*policy,

size_tpolicy_length,

intcontents_encryption_mode,

intfilenames_encryption_mode){

if(policy_length!=EXT4_KEY_DESCRIPTOR_SIZE){

LOG(ERROR)<

returnfalse;

}

intfd=open(directory,O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);

if(fd==-1){

PLOG(ERROR)<

returnfalse;

}

// 设置ext4加密规则

ext4_encryption_policyeep;

eep.version=0;

eep.contents_encryption_mode=contents_encryption_mode;

eep.filenames_encryption_mode=filenames_encryption_mode;

eep.flags=e4crypt_get_policy_flags(filenames_encryption_mode);

memcpy(eep.master_key_descriptor,policy,EXT4_KEY_DESCRIPTOR_SIZE);

// 调用IOCTL设置加密规则

if(ioctl(fd,EXT4_IOC_SET_ENCRYPTION_POLICY,&eep)){

PLOG(ERROR)<

close(fd);

returnfalse;

}

close(fd);

charpolicy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX];

policy_to_hex(policy,policy_hex);

LOG(INFO)<

returntrue;

}

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

赞过:

赞 正在加载……

相关

http://www.lbrq.cn/news/2546137.html

相关文章:

  • 做网站 对方传销高明搜索seo
  • WordPress 整个网站导出网上广告怎么推广
  • 企业网站建设费用入什么科目中国法律服务网app最新下载
  • 个人免费网站如何做西安网站seo推广
  • wordpress 菜单 分隔合肥网站优化推广方案
  • 简述网站推广的五要素深圳seo公司助力网络营销飞跃
  • 自己架设的传奇怎么做网站网站制作的流程
  • 服务平台推广seo难不难学
  • 网站建设选用平台分析淄博seo推广
  • 国外真人做爰直播聊天平台网站网页分析工具
  • 专业做网站公司哪家好上海知名的seo推广咨询
  • wordpress the7 建站广州百度关键词排名
  • 海外服务器官网seoapp推广
  • it外包项目都在哪接的南宁百度seo
  • 西宁高端网站建设web成品网站源码免费
  • 德州建网站天津seo网络营销
  • 贵州网站开发公司全网最低价24小时自助下单平台
  • 海阳有没有做企业网站的谷歌网页版入口在线
  • 汉中做网站的公司电话关键词优化意见
  • 网站建设公司哪家好速找盛世传媒我们公司想做网络推广
  • 做一个交友网站怎样做需要多少资金全网
  • 自己做的网页怎么连接到网站安卓优化大师老版本下载
  • 12306网站做的好还是百度做的好怎么申请自己的域名
  • b2b网站开发公司百度网站免费优化软件下载
  • 门头沟做网站公司windows优化大师使用方法
  • 酒店建筑设计网站上海seo网站优化软件
  • 关于做公司app的软件或网站怎样在百度上宣传自己的产品
  • 如何申请深圳设计公司网站搜索推广平台有哪些
  • 做机械设计兼职的网站怎么免费制作网页
  • 新网站前期seo怎么做seo技术306
  • LeetCode 热题100:206. 反转链表
  • 向日葵软件提权
  • 使用 whisper, 音频分割, 整理需求 2
  • 什么是数据集成?和数据融合有什么区别?
  • 正向运动学(Forward Kinematics,简称FK)和逆向运动学(Inverse Kinematics,简称IK)
  • 33.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--财务服务--记账