一、概述
加密是最常见的数据安全保护技术,在数据生命周期各阶段均有应用。从应用场景和技术实现上,按加密对象、用户是否感知、加密算法等维度,有多种分类及对应方案,并在主流操作系统如Windows、Linux、Android中有广泛应用。
本文是Linux内核安全技术系列第二篇,主要介绍磁盘加密技术及主流实现方案。首先介绍磁盘加密技术背景,包括应用场景、威胁模型、技术路线分类等;其次介绍磁盘加密的两种实现方案,即全盘加密FDE和文件系统加密FBE,重点介绍Linux系统和内核主流FBE实现方案;最后以eCryptfs为例,详细分析其原理和应用。
Linux内核安全技术系列第一篇:Linux内核安全技术——开源演进回顾
1.1、说明
数据在其生命周期各阶段的信息安全风险有很多,如仿冒、篡改、泄漏、越权访问、DoS拒绝访问等,一些成熟方案通常能解决消减多种风险。本文主要介绍磁盘加密技术,主要关注的是数据泄漏、机密性维度,其他维度风险和保护不过多涉及。
1.2、缩略语和术语
本文使用的缩略语和术语说明如下:
二、技术背景介绍
2.1、威胁模型
数据生命周期管理(Data Lifecycle Management)通常将数据划分为生产、存储、使用、分享、销毁、归档几个阶段。而从信息安全保护维度,则一般将数据划分为三种状态,即:Data in Use、Data in Motion/Transit、Data at Rest。
Data in Motion/Transit,即数据传输场景,是大家最熟悉、技术发展最成熟的安全场景。例如基于SSL/TLS协议的Https应用,基于SSH协议的SCP/SFTP应用等。这些技术对数据的安全保护不仅包括加密传输,也包含双向身份认证、完整性保护等。
Data in Use,即数据使用场景。此时数据缓存在系统DRAM、Cache、CPU Register中,一般明文存在。但在一些高安全场景下,为防止侧信道攻击(如Cold Boot Attack获取DRAM中密钥信息),业界也提出了Full Memory Encryption全内存加密技术。如Intel的TME(Total Memory Encryption)、AMD的SME(Secure Memory Encryption)等。FME使能时系统DRAM数据全部为加密存储,CPU通过特定硬件加解密引擎分别在读写数据时做解密加密操作,加解密密钥则一般每次boot时唯一生成。
Data at Rest,即数据(持久化)存储场景。此时数据属于inactive状态未使用,存储在磁盘等非易失性介质。安全风险主要有非授权访问、设备丢失导致数据泄漏等。常见保护方式包括物理/网络层面的隔离和访问控制、以及数据(落盘)加密。对于加密存储的磁盘数据,即使设备(如PC/手机)丢失,攻击者拆出硬盘或Flash器件,也只能读取到器件中的密文,保证关键数据机密性。
2.2、技术路线
加密是防止数据泄漏、保证机密性的有效手段。按照不同维度,加密技术/方案可以有多种分类,简单汇总如下:
需要说明的是,几种维度不互斥,某一方案通常符合/采用多个特征/技术。例如本文要介绍的磁盘加密技术Disk Encryption,其加密对象一般是整个磁盘或文件系统,但从数据状态维度看属于Data at Res Encryption技术,从用户感知维度看属于透明加密技术,从加密算法维度看采用对称加密。
下面简单介绍几个分类涉及的技术概念/术语,详情可查阅文末参考链接,及后续章节中的详细分析。
Data at Rest Encryption
数据在at Rest状态下保持加密的技术,参考https://wiki.archlinux.org/title/Data-at-rest_encryption说明,加密对象一般为磁盘(块设备)、文件系统目录,加解密过程采用透明加密技术。
Transparent Encryption
透明加密,也称作real-time encryption或on-the-fly encryption。特点是数据在使用过程中自动完成加解密,无需用户干预。
三、磁盘加密技术
如上节所述,Disk Encryption磁盘加密,目标是保护数据at Rest状态下的机密性,加密对象是整个磁盘/分区、或者文件系统,采用实时加解密技术。更多介绍可参考https://en.wikipedia.org/wiki/Disk_encryption 。
磁盘加密技术从加密对象,软硬件实现、文件系统特征等维度,也可以有多种分类。首先,根据加密对像是整个磁盘,还是文件系统,可分为Full-Disk Encryption 和 Filesystem-Level Encryption(也称为File-Based Encryption)两大类。
3.1、FDE
Full-Disk Encryption全盘加密在实现上有硬件、软件两种方案。两者核心原理类似,区别是加解密核心功能所在主体是软件还是硬件,另外软件方案一般不能真正加密整个硬盘(boot分区不加密),而硬件方案Hardware-based Full-Disk Encryption则具备整个硬盘加密能力。硬件FDE方案产品主要是Self Encryption Drive自加密硬盘,一般由存储器件厂商、安全厂商提供。关于硬件FDE方案和SED产品技术,可参阅文末Hardware-based Full Disk Encryption 和SED相关链接。
硬件和软件FDE方案核心原理及流程类似,统一抽象说明如下:
在初始化或创建FDE时,会随机生成一个磁盘数据加密DEK(Disk Encryption Key,用户无感知),同时要求用户输入一个AK(Authentication Key)用来加密保护DEK。在使用时,需用户先输入AK验证并解密DEK,之后操作系统才能使用DEK访问加密磁盘上的数据。下图是一个软件FDE的描述。
由于需执行特定程序展示UI提供用户输入AK并验证,故这部分启动代码不能加密。因此引了入Pre-Boot Authentication 及PBA environment的概念。
在PBA实现上,硬件FDE方案(SED产品)一般出厂时内嵌Pre-Boot environment(小的OS或bootloader),上电后先运行Pre-Boot程序并验证AK,再进行正常的加载引导等。
软件FDE方案采用不加密boot分区的方式,一般在initial ramdisk集成PBA功能并完成验证。
软件FDE方案发展历史久,主流OS环境均有成熟方案,例如Windows下的BitLocker、Apple OS/X下的FileVault、以及Linux/UNIX生态下的dm-crypt/LUKS。另外也有不依赖操作系统的三方FDE方案,如TrueCrypt、VeraCrypt等。更多软件FDE方案可以参考链接 https://en.wikipedia.org/wiki/Comparison_of_disk_encryption_software 及下图。
对Linux下dm-crypt/LUKS方案感兴趣的同学可以在Ubuntu虚拟机上测试研究。下面是几个关键场景截图:Ubuntu虚拟机安装时使能磁盘加密配置、启动阶段PBA验证、系统主分区sda5加密后的磁盘类型(可看到boot分区sda1未加密)。
3.2、FBE
File-Based Encryption,又称Filesystem-Level Encryption,文件系统加密。相比于FBE,第二个名字更能体现方案基于文件系统的技术特点。而基于文件系统的特点,一方面决定了只能由软件实现,另一方面决定了各方案差异也主要围绕在文件系统。
常见FBE方案,一般分为Stackable cryptographic filesystem 和Native/General filesystem with encryption两种。
第一种,新增一个加解密文件系统,堆叠在现有存储软件栈的某一层。例如Linux内核自v2.6.19开始支持,已很成熟稳定的eCryptfs方案,就是在VFS -> Native FS层之间加入新加解密文件系统支持。类似还有基于用户态文件系统FUSE的各种方案。
第二种,在现有文件系统中引入加解密功能。例如Linux内核自v4.1支持的Ext4文件系统加密,自v4.2支持的F2FS文件系统加密,自v4.10后支持的UBIFS文件系统加密。需要说明的是,内核中Ext4、F2FS、ubifs共用加解密功能模块,即内核fscrypt特性。另外,Android系统引入的FBE方案,底层内核实现也是基于F2FS+fscrypt。
两种类型及更多业界FBE实现,可参考链接 https://en.wikipedia.org/wiki/List_of_cryptographic_file_systems 及下图:
和FDE方案相比,FBE有几个显著的特点:
1、支持单独的目录或文件加密,方便灵活使用配置。只加密目标对象,不加密整个磁盘,降低了系统加解密负载开销。
2、支持不同目录/文件使用不同加密密钥。
3、加密目录和非加密目录并存(甚至一个加密目录中加密和非加密文件也可以并存)。加密目录文件的备份传输灵活方便。
更多FDE和FBE的详细对比,以及Linux中FBE具体实现,请参见后续章节。
3.2、FDE vs FBE
前面分析已经知道,软件FDE和FBE都是基于文件系统,差别主要在文件系统实现差异,整理对比如下:
【说明】软件FDE/FBE主要是指其加解密功能主体在软件(文件系统)实现,并不意味着不使用硬件,相反为了提高性能,也会利用类似Crypto Engine等硬件引擎来加速。
从整个系统软硬件架构分析,可将硬件FDE、软件FDE、以FBE实现和系统软硬件架构的关系位置描述如下图:
上图中,磁盘加密方案,越往上层实现用户使用配置越灵活,但性能差;越往下层实现越不灵活,但对用户越透明且性能越好。结合前文描述,将FDE和FBE两种方案的差异对比整理如下:
3.3、Linux系统FBE
从Linux系统软件架构看,典型FDE和FBE实现方案分布如下图,包括基于dm-crypt的软件FDE方案、基于通用文件系统的fscrypt FBE方案、基于VFS的eCryptfs FBE方案,以及众多基于FUSE的FBE方案。
前面章节已经简单介绍过基于dm-crypt的FDE方案在ubuntu虚拟机上的验证情况,这里先简单介绍Linux系统和内核的几种软件FBE实现方案和特点,后续章节会以eCryptfs为例做详细分析。
FUSE-Based
FUSE即Filesystem in Userspace,用户态文件系统。FUSE设计初衷就是为方便用户不修改编译内核的情况下,在user space实现定制文件系统。FUSE架构原理和实现如下图,内核态FUSE和用户态libfuse为App –> VFS -> 用户文件系统链路服务,用户定制实现主要在User-Level Filesystem部分。
由于天然的灵活性,基于FUSE实现FBE的方案有很多,例如gocryptfs、EncFS、CryFS、securefs等。但是,FUSE引入的多次系统调用和拷贝等开销,也导致基于FUSE的FBE方案通常性能都不好。gocryptfs项目有一个stackable FBE各方案的对比分析(链接https://nuetzlich.net/gocryptfs/comparison/),该分析数据也验证说明了FUSE FBE方案的优缺点。
首先是各种stackable FBE方案介绍和整体特点,从数量上看,FUSE FBE方案占据绝大多数,非FUSE方案只有eCryptfs。
其次,相比于eCryptfs,FUSE方案在性能上整体处于劣势。尽管gocryptfs在顺序读写上性能不错,但在其他测试如解压缩、MD5计算、目录递归访问/删除等测试项上看,劣势也比较明显。这和我们在3.2章节对比FDE和FBE、以及分析磁盘加密在软件栈不同层级实现的效果差异是一致的。
更多关于FUSE FBE各方案的特点,如文件内容加密、文件名加密等,可参考上述对比链接或各方案主页,在此不详细介绍。
eCryptfs
eCryptfs衍生于Cryptfs项目,早期方案和设计思想源自2005和2007的两篇论文,即《eCryptfs: an enterprise-class cryptographic filesystem for Linux》和《eCryptfs: a Stacked Cryptographic Filesystem》。eCryptfs项目分为内核部分和用户态部分,内核态代码于v2.6.19版本合入社区主线,用户态代码在软件包ecryptfs-utils中维护。
eCryptfs和上面介绍的FUSE方案一样,也属于stackable FBE类型,故不依赖于OS底层文件系统类型,可以堆叠在各种文件系统之上,灵活性很好。也支持对不同文件、目录加密,以及文件名加密。
当前eCryptfs项目开源社区活跃度不高,早期用户/产品也在迁移,但其方案和设计原理仍然值得深入学习分析。详细测试验证和原理分析请见第4章。
fscrypt
fscrypt是在内核文件系统上实现的一个native FBE方案。fscrypt特性也包括内核态和用户态两部分,内核态部分是实现在fs/crypto目录的公用加解密模块,支持ext4、F2FS、UBIFS文件系统集成使用。用户态工具fscrypt则实现各种命令行工具方便用户使用。
fscrypt作为FBE方案,支持不同目录/文件采用不同密钥,对于metadata,fscrypt支持文件名filename加密,其他metadata如timestamp、size、attribute等不加密。fscrypt最大的应用即Android 采用的FBE方案,结合F2FS文件系统,对手机上的数据进行data at rest encryption保护。本文受限于篇幅,不做详细分析。
四、eCryptfs详解
本章节我们先用简单用例验证eCryptfs加密效果特点,使大家对方案有个整体感性认识,同时也会提供一个C版本用例作参考。其次对测试结果进行初步分析,接着详细分析eCryptfs方案架构原理和核心机制,最后对关键业务流程代码进行简单梳理。
测试环境使用Ubuntu 20.04虚拟机,因Ubuntu系统默认打开eCryptfs内核配置(CONFIG_ECRYPT_FS=y),只需apt安装用户态工具ecryptfs-utils即可。
4.1、测试用例
下图是一个脚本基础测试用例。先创建test目录和文件hello,之后使用 mount -t ecryptfs方式对test目录进行加密,为避免命令行交互,将所有加密参数(passwd、cipher、key size等)通过命令行-o传递。加密后在test目录创建新文件hello_encrypted。最后umount取消目录加密。
从第一个测试用例可以观察到的现象/特性有:
1、执行mount,写入hello_encrypted文件内容后可以正确访问,但umount后则为密文。说明eCryptfs作为堆叠加密文件系统,是通过mount/unmount操作来开关使能的。功能打开时,用户读写操作是感知不到数据加解密过程的,即透明加密。
2、hello文件内容在mount前写入,在mount前后都能正确访问(用例只测了读操作,实际写也可以)。说明eCryptfs支持非加密文件和加密文件在一个目录内混合存储,并能正确访问(实际操作强烈不建议,见下个用例)。
3、对于加密文件hello_encrypted,明文状态下长度为16 Bytes,加密状态下为12KB,变化比较明显。
如果对上述测试用例稍加改动,调整mount -t ecryptfs参数,如改变passwd,取消no_sig_cache=y配置,打开文件名加密参数即ecryptfs_enable_filename_crypto=y,测试效果如下图:
从第二个改动后的用例可以观察到的现象/特性有 :
4、ecryptfs支持文件名加密。因为文件名加密密钥FNEK未在参数中指定,mount helper会提示/默认使用文件内容加密密钥(即图中fnek_sig和fs_sig相同,需说明的是加密密钥并非参数中的passwd,后续架构和密钥管理章节会说明)。
5、虽然ecryptfs_passthrough特性仍打开,即允许加密和非加密文件共存,但与上一个用例效果不同。启动文件名加密并mount后,未加密文件hello无法在test中显示,umount后又可正常访问。两个用例中passthrough特性在不同参数下表现不同,因此实际应用中,强烈不建议加密和非加密文件在一个目录混存。
另外补充一个现象/特性:
6、umount后,即加密的test目录是可以直接传输/拷贝到其他主机/网络进行存储备份的。其他用户使用时,只需用相同参数重新mount即可正确访问。
关于用例中mount -t ecryptfs命令的相关参数汇总如下,详情可参考man ecryptfs手册及ecryptfs-utils源码。部分参数和意义会在架构分析和密钥管理章节进一步说明。
需要说明的是,上述脚本用例的功能基本都可以用ecryptfs-utils提供接口API实现。下面是作者实现的一个C用例的部分代码参考。因为C程序需引用ecryptfs.h头文件并使用相关API函数,需要安装libecryptfs-dev软件包,并在编译时指定-lecryptfs链接对应库文件。
C用例中需要注意的是,mount操作前必须进行ecryptfs_add_passphrase_key_to_keyring,即将passphrase转换成对应的key(实际为FEKEK,见后续分析),并注册到内核keyring,同时返回一个key_sig给用户后续使用。
4.2、结果分析
从上节测试结果中,汇总相关测试项以及eCryptfs效果特性如下表,需要说明的有两点:
一是对test目录重复mount且每次使用不同密钥的效果。从下图用例看,对应passwd mount后生成的文件,只能在该mount context中正确访问。这个用例仅为简单说明,在参数变化情况下,例如文件名加密,情况可能更复杂和不确定,因此也不建议使用。
二是文件加密后大小变化问题,这个原因在于eCryptfs的方案本身设计。下图是eCryptfs明文和密文的映射关系及论文中的说明,分别出自2006年设计文档《eCryptfs v0.1 Design Document》和2007年论文《eCryptfs: a Stacked Cryptographic Filesystem》。从中可看出加密文件格式会多增加一个header信息(预留一个page)。对于文件内容则是按页分块加密。为了综合性能考虑,故使文件大小做到page对齐,最小12KB。
从方案设计和文件格式看,加密对于小文件来说损耗有点大,文件越大影响越小。下图是分别用4M、40M、400M文件测试对比结果,不论源文件大小,加密后的文件size增加8KB。
4.3、整体架构
eCryptfs整体架构如下图,主要是内核模块eCryptfs以及用户态进程ecryptfsd。ecryptfsd进程只在使用key type为openssl模式时需要,使用passphrase模式(如上述测试用例)时不需要。ecryptfs-utils可作为用户态辅助工具或C接口编程参考。
应用程序发起系统调用时先经过VFS,判断目录类型为eCryptfs时调用eCryptfs模块的注册函数。之后eCryptfs根据mount session中保存的key signature参数从keyring中找到对应密钥(FEKEK),再调用crypto模块API完成文件加解密。
eCryptfs核心加解密机制如下图,主要特点归纳如下:
1、FEK(File Encryption Key)唯一,即每个文件的加密密钥均不同,是随文件创建时生成的一个随机数。
2、每个文件的FEK经过FEKEK(File Encryption Key Encryption Key)加密保护,加密后FEK称为EFEK(Encrypted File Encryption Key),并保存在eCryptfs加密文件的header信息中(如前述page 0区域)。
3、passphrase模式下,FEKEK是基于用户passphrase_passwd派生而来,派生方式是hash计算(参考代码分析章节)。
4、文件内容按照page大小(Data Extent)进行块加密。
核心过程可简单描述为:
1、新文件加密时,生成随机数FEK,对文件内容进行分块加密并存储。根据用户传递的key_sig参数从keyring找到对应的FEKEK,用FEKEK加密FEK,生成EFEK并保存在文件header中。
2、解密时,同样根绝key_sig找到FEKEK,用FEKEK解密EFEK后得到FEK,再用FEK解密文件内容。
4.4、密钥管理
从上节中我们了解到eCryptfs中核心机制中主要有两个KEY,即FEKEK和FEK,前者和用户输入passphrase_passwd有关,后者是每个文件唯一的随机数。下面结合ecryptfs-utils源码,分别介绍这两个KEY的生成过程。
1、用户passphrase_passwd 到 FEKEK的转换
从C测试用例中看到,opt参数只有key_sig信息,并不指定FEKEK。且mount操作前提是已添加对应key(FEKEK)到内核keyring。脚本命令实际是mount helper协助(隐式)完成了添加keyring的操作。
核心函数即C用例中调用的ecryptfs_add_passphrase_key_to_key_ring,这个函数的调用关系如下图:
首先ecryptfs_generate_passphrase_auth_tok会根据用户输入的passphrases信息、salt信息(参数指定,ecryptfs-utils有一个默认值ECRYPTFS_DEFAULT_SALT如下图),在generate_passphrase_sig函数中进行hash计算,并将结果记录在变量fekek中,然后对fekek再进行一次hash计算,结果记录为passphrase_sig/auth_token_sig,并返回给用户后续使用(key_sig)。
generate_payload则为每一次session创建一个auth_tok结构体,记录更多加解密相关信息。
最后调用ecryptfs_add_auth_tok_to_keyring中,将对应FEKEK、key_sig、salt等信息都添加到keyring。至此就完成了从passphrase_passwd到FEKEK的转换和内核keyring添加。
2、FEK的生成过程
FEK作为文件内容加密key,是每个文件唯一的随机数。生成时机是在create系统调用阶段,具体是在内核函数ecryptfs_new_file_context 和 ecryptfs_generate_new_key中完成,代码见下。
4.5、代码分析
本节将eCryptfs方案核心过程的代码调用关系进行了简单梳理并罗列,供读者参考和对照阅读,不做详细分析。
1、Mount过程关键函数调用。
从mount_crypt_stat关键结构体,以及tokens结构体中可看出,mount opt只接受key signature信息。
2、Create过程关键函数调用。
create过程中创建新文件,此时ecryptfs_crypt_stat结构体中保存了每个文件的加密参数信息。
3、open过程关键函数调用。
4、read & write过程关键函数调用。
五、总结
本文首先介绍了磁盘加密技术背景,包括威胁模型,技术路线和特点,随后根据加密对象差异,分别介绍了FDE和FBE两种磁盘加密方案,包括软硬件实现、文件系统实现差异等,并做了对比分析。最后重点介绍了Linux系统中典型FBE方案及特点,并以eCryptfs为例进行了详细分析。
希望能帮助读者对磁盘加密技术概念、FDE和FBE区别、业界FBE方案特点、以及FBE实现关键技术能有进一步了解。受限于篇幅,很多技术细节和方案无法再深入展开,如fscrypt。希望在后续文章中能结合Android FBE对fscrypt做进一步分享。
参考资料:
Data in use https://en.wikipedia.org/wiki/Data_in_use
Data in transit https://en.wikipedia.org/wiki/Data_in_transit
Data at rest https://en.wikipedia.org/wiki/Data_at_rest
Data at rest encryption https://wiki.archlinux.org/title/Data-at-rest_encryption
Disk Encryption https://en.wikipedia.org/wiki/Disk_encryption
Full Disk Encryption https://en.wikipedia.org/wiki/Disk_encryption#Full_disk_encryption
Pre-boot Authentication https://en.wikipedia.org/wiki/Pre-boot_authentication
What is full disk encryption https://specopssoft.com/blog/what-is-full-disk-encryption/
Hardware-based full disk encryption https://en.wikipedia.org/wiki/Hardware-based_full_disk_encryption
Self Encryption Drives https://wiki.archlinux.org/title/Self-encrypting_drives
Disk Encryption Software https://en.wikipedia.org/wiki/Disk_encryption_software
Comparison of disk encryption software https://en.wikipedia.org/wiki/Comparison_of_disk_encryption_software
Filesystem-level encryption https://en.wikipedia.org/wiki/Filesystem-level_encryption
List of cryptographic filesystems https://en.wikipedia.org/wiki/List_of_cryptographic_file_systems
Filesystem in Userspace,FUSE https://en.wikipedia.org/wiki/Filesystem_in_Userspace
Comparison of FUSE-Based FBE https://nuetzlich.net/gocryptfs/comparison/
fscrypt kernel documentation https://docs.kernel.org/filesystems/fscrypt.html
eCryptfs documentation https://www.ecryptfs.org/documentation
eCryptfs Linux Manual Page https://linux.die.net/man/7/ecryptfs
2005.07 eCryptfs: an enterprise-class cryptographic filesystem for Linux https://web.archive.org/web/20080916022422/http://www.linuxsymposium.org/2005/linuxsymposium_procv1.pdf
2006.03 eCryptfs v0.1 Design Document http://www.dubeyko.com/development/FileSystems/eCryptfs/ecryptfs_design_doc_v0_1.pdf
2007.05 eCryptfs: a Stacked Cryptographic Filesystem http://www.dubeyko.com/development/FileSystems/eCryptfs/ecryptfs-article.pdf
2016.01动态加密技术综述,梁金千 http://blog.nsfocus.net/dynamic-encryption-technology-review/
2017.09 File-system and Block-layer Encryption: Theory, Practice, and Improvement https://www.snia.org/educational-library/file-system-and-block-layer-encryption-theory-practice-and-improvement-2017
长按关注内核工匠微信
Linux内核黑科技| 技术文章 | 精选教程