searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

ext4文件加密原理分析

2024-08-21 09:43:14
92
0

1. 概述

文件系统加密常见两个方式,FDE(full disk encrypt),FBE(file baseed encrypt)和ME(metadata encrypt)。文件加密常用于用户数据保护场景,避免用户数据泄露。本文以ext4文件系统的读取流程为切入点,介绍其FBE的实现机制,以及与Keyring和fscypt的交互流程。

2. ext4文件加密

ext4支持对指定目录或者文件设置为加密目录或文件。

2.1 设置指定目录或文件加密

用户可以ioctl设置指定目录或者文件加密,相关调用链如下:

ioctl(EXT4_IOC_SET_ENCRYPTION_POLICY) -> ext4_ioctl -> fscrypt_ioctl_set_policy->create_encryption_context_from_policy -> ext4_set_context

1)fscrypt_ioctl_set_policy

ext4调用fscypt接口设置inode的加密上下文。

2)create_encryption_context_from_policy

此处会使用生成一个随机数作为派生秘钥的加密秘钥。每文件的加密秘钥如何生成,后续小节会详细介绍

3)ext4_set_context

ext4文件系统中使用inode的xattr保存加密上下文。

2.2 顶层加密目录节点的秘钥派生

上节介绍ioctl仅设置目录节点的fscypt_context并写入inode的xattr中。但是并未涉及派生秘钥的生成。当目录第一次open时,将inode->i_crypt_info初始化,并设置加密算法和派生秘钥

ext4_readdir/ext4_dir_open -> fscrypt_get_encryption_info -> find_and_derive_key -> derive_key_aes

1) fscrypt_get_encryption_info

当加密目录第一次打开时,会在inode中加载crypt_info数据,其中包含加密算法和加密秘钥的派生。

2)find_and_derive_key

秘钥派生前,需要获取当前进程的主密钥。进程的主密钥导入是基于keyring实现,本文不展开介绍。

3)秘钥派生derive_key_aes

秘钥派生实际上是使用ioctl流程生成的随机数对进程主密钥进行aes加密的过程。

4)进程主密钥,派生秘钥和生成随机数的关系

  • 进程主秘钥作为输入数据
  • ioctl设置加密目录时生成的随机数作为对称秘钥
  • 主秘钥加密后即作为派生秘钥
  • 由于目录的随机数是未知,因此即使同一进程的不同目录生成派生秘钥也不同

2.3 子目录或者文件节点的秘钥派生

当已设置某个目录为加密目录时,再此目录下创建的子目录和文件都将默认加密,且派生秘钥不同。从支持不同文件或目录使用不同秘钥进行加解密。

ext4_create/ext4_mkdir -> ext4_new_inode_start_handle -> __ext4_new_inode -> fscrypt_inherit_context

1)__ext4_new_inode

创建子节点时,如果是作为加密目录,需要设置加密上下文。

2)fscrypt_inherit_context

FBE的核心要求就是不同文件或者目录采用不同的加密秘钥,实际的体现就是不同inode的采用不同随机数用于秘钥派生,即ctx.noce重新生成。

2.4 写文件的相关流程

写文件操作涉及发起写请求和写回调处理。

2.4.1 写请求

当inode已加载crypt_info,用户调用write系统调用写文件时,ext4将调用fscypt接口,对page进行加密,然后将加密后的page提交bio。以writepage流程举例

写io发起流程:

sys_write-> ... -> ext4_writepage -> ext4_bio_write_page

1)ext4_bio_write_page

作为发起写io的核心流程,涉及加密节点相关任务

  • 待写入page的加密
  • 发起bio

 

2)fscrypt_encrypt_page

此处对明文page进行加密操作,不是直接修改当前page,而是申请一个新page,用于存储加密后的数据。

原因是原明文page,属于page cache需要继续报错明文,从而被应用使用。

2.4.2 写回调end_io

当写io完成时,回收bio以及加密page,并设置page状态

ext4_end_io -> ext4_finish_bio

2.5 读文件的解密流程

读文件和写文件类似涉及读io发起和读回调流程

2.5.1 读请求

当inode已加载crypt_info,用户调用read系统调用读文件时,由于磁盘中实际的block为加密数据,ext4需要对读取page进行解密后返回给用户。以readpage流程举例

读io发起流程:

sys_read-> ... -> ext4_readpage -> ext4_mpage_readpages

其中ext4_mpage_readpages涉及的关键点如下

  • 设置end_io回调的解密算法和秘钥
  • 发起读bio

2.5.2 读回调

当读io完成时,对读取加密page进行解密

mpage_end_io -> fscrypt_enqueue_decrypt_bio -> completion_pages -> __fscrypt_decrypt_bio -> fscrypt_decrypt_page

1)fscrypt_enqueue_decrypt_bio

由于end_io属于软中断上下文,因此加解密等耗时操作,不能在此流程中进行。

 2)fscrypt_decrypt_page

由于对密文page不需要保留,因此解密过程不会申请新page,直接覆盖原密文内容即可。

3. 总结

本文以用户进行FBE加密的操作过程为切入点,介绍ext4的FBE实现逻辑。其中涉及密码学部分,如对称秘钥等内容,需要读者扩展学习。

0条评论
0 / 1000
c****v
2文章数
0粉丝数
c****v
2 文章 | 0 粉丝
c****v
2文章数
0粉丝数
c****v
2 文章 | 0 粉丝
原创

ext4文件加密原理分析

2024-08-21 09:43:14
92
0

1. 概述

文件系统加密常见两个方式,FDE(full disk encrypt),FBE(file baseed encrypt)和ME(metadata encrypt)。文件加密常用于用户数据保护场景,避免用户数据泄露。本文以ext4文件系统的读取流程为切入点,介绍其FBE的实现机制,以及与Keyring和fscypt的交互流程。

2. ext4文件加密

ext4支持对指定目录或者文件设置为加密目录或文件。

2.1 设置指定目录或文件加密

用户可以ioctl设置指定目录或者文件加密,相关调用链如下:

ioctl(EXT4_IOC_SET_ENCRYPTION_POLICY) -> ext4_ioctl -> fscrypt_ioctl_set_policy->create_encryption_context_from_policy -> ext4_set_context

1)fscrypt_ioctl_set_policy

ext4调用fscypt接口设置inode的加密上下文。

2)create_encryption_context_from_policy

此处会使用生成一个随机数作为派生秘钥的加密秘钥。每文件的加密秘钥如何生成,后续小节会详细介绍

3)ext4_set_context

ext4文件系统中使用inode的xattr保存加密上下文。

2.2 顶层加密目录节点的秘钥派生

上节介绍ioctl仅设置目录节点的fscypt_context并写入inode的xattr中。但是并未涉及派生秘钥的生成。当目录第一次open时,将inode->i_crypt_info初始化,并设置加密算法和派生秘钥

ext4_readdir/ext4_dir_open -> fscrypt_get_encryption_info -> find_and_derive_key -> derive_key_aes

1) fscrypt_get_encryption_info

当加密目录第一次打开时,会在inode中加载crypt_info数据,其中包含加密算法和加密秘钥的派生。

2)find_and_derive_key

秘钥派生前,需要获取当前进程的主密钥。进程的主密钥导入是基于keyring实现,本文不展开介绍。

3)秘钥派生derive_key_aes

秘钥派生实际上是使用ioctl流程生成的随机数对进程主密钥进行aes加密的过程。

4)进程主密钥,派生秘钥和生成随机数的关系

  • 进程主秘钥作为输入数据
  • ioctl设置加密目录时生成的随机数作为对称秘钥
  • 主秘钥加密后即作为派生秘钥
  • 由于目录的随机数是未知,因此即使同一进程的不同目录生成派生秘钥也不同

2.3 子目录或者文件节点的秘钥派生

当已设置某个目录为加密目录时,再此目录下创建的子目录和文件都将默认加密,且派生秘钥不同。从支持不同文件或目录使用不同秘钥进行加解密。

ext4_create/ext4_mkdir -> ext4_new_inode_start_handle -> __ext4_new_inode -> fscrypt_inherit_context

1)__ext4_new_inode

创建子节点时,如果是作为加密目录,需要设置加密上下文。

2)fscrypt_inherit_context

FBE的核心要求就是不同文件或者目录采用不同的加密秘钥,实际的体现就是不同inode的采用不同随机数用于秘钥派生,即ctx.noce重新生成。

2.4 写文件的相关流程

写文件操作涉及发起写请求和写回调处理。

2.4.1 写请求

当inode已加载crypt_info,用户调用write系统调用写文件时,ext4将调用fscypt接口,对page进行加密,然后将加密后的page提交bio。以writepage流程举例

写io发起流程:

sys_write-> ... -> ext4_writepage -> ext4_bio_write_page

1)ext4_bio_write_page

作为发起写io的核心流程,涉及加密节点相关任务

  • 待写入page的加密
  • 发起bio

 

2)fscrypt_encrypt_page

此处对明文page进行加密操作,不是直接修改当前page,而是申请一个新page,用于存储加密后的数据。

原因是原明文page,属于page cache需要继续报错明文,从而被应用使用。

2.4.2 写回调end_io

当写io完成时,回收bio以及加密page,并设置page状态

ext4_end_io -> ext4_finish_bio

2.5 读文件的解密流程

读文件和写文件类似涉及读io发起和读回调流程

2.5.1 读请求

当inode已加载crypt_info,用户调用read系统调用读文件时,由于磁盘中实际的block为加密数据,ext4需要对读取page进行解密后返回给用户。以readpage流程举例

读io发起流程:

sys_read-> ... -> ext4_readpage -> ext4_mpage_readpages

其中ext4_mpage_readpages涉及的关键点如下

  • 设置end_io回调的解密算法和秘钥
  • 发起读bio

2.5.2 读回调

当读io完成时,对读取加密page进行解密

mpage_end_io -> fscrypt_enqueue_decrypt_bio -> completion_pages -> __fscrypt_decrypt_bio -> fscrypt_decrypt_page

1)fscrypt_enqueue_decrypt_bio

由于end_io属于软中断上下文,因此加解密等耗时操作,不能在此流程中进行。

 2)fscrypt_decrypt_page

由于对密文page不需要保留,因此解密过程不会申请新page,直接覆盖原密文内容即可。

3. 总结

本文以用户进行FBE加密的操作过程为切入点,介绍ext4的FBE实现逻辑。其中涉及密码学部分,如对称秘钥等内容,需要读者扩展学习。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0