【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解

前言

之前前辈的那篇文章说希望后续文章中能结合Android FBE对fscrypt做进一步分享。

于是就来了,嗷嗷嗷,感激,学习 学习!!!

原文链接:https://blog.csdn.net/feelabclihu/article/details/131016357?spm=1001.2014.3001.5501

一、前言

用户数据加密是移动设备的重要功能,是使用对称加密算法对Android设备上的所有用户数据进行编码的过程,防止用户数据被未经授权的用户或应用程序访问。

本文是Android系统安全技术系列第二篇,主要介绍基于文件的加密技术。首先介绍Android保护用户隐私数据的技术方案,包括

  • 全盘加密FDE、
  • 文件加密FBE
  • 元数据加密ME。

其次介绍基于文件加密FBE的密钥管理,涉及HAL、Linux Kernel、TEE和Hardware。

1.1、说明

Google FBE是Android系统中较为复杂的模块之一。

从硬件角度,Google FBE特性依赖ICE(Inline Crypto Engine)硬件加速引擎或高安子系统

从软件角度,Google FBE特性涉及frameworks、HAL、Linux Kernel、ATF和TEEOS。wow wow

本着以点带面的原则,本文以密钥管理为主线进行梳理,涉及

  • VOLD、
  • Linux Kernel Keyring、
  • Linux Kernel Fscrypt、
  • KSM、
  • Keymaster
  • ICE,

不涉及VOLD子系统存储管理、Fscrypt用户空间部分和F2FS文件系统IO处理等。

1.2、声明

本文档所有代码来自:

  • AndroidAOSPhttps://cs.android.com/android/platform/superproject

  • Linux AOSP:https://elixir.bootlin.com/linux/v5.15.111/source

  • Google Trusty:https://github.com/haitao52198/TrustyOS/tree/master/AndroidTrustyOS

1.3、缩略语

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第1张图片

二、用户隐私数据保护方案

下图是DCCI(互联网数据中心)联合360发布的《中国Android手机用户隐私安全认知调查报告》,调查发现,图片、联系人和各种账号/密码是三大Android用户认为属于隐私的信息,也是用户最担心泄露的三大隐私信息:

在这里插入图片描述

Android设备可以访问和存储用户的个人隐私数据,如果设备一旦丢失,会极大的增加用户数据泄露的风险。Google规避该风险的措施之一就是磁盘加密(Disk Encryption)。

从Android 4.4开始,Google相继推出FDE全盘加密、FBE文件加密和ME元数据加密。

如果设备丢失,加密可以将泄露用户隐私数据的风险降至最低。

但必须认识到,无论哪种技术手段,主要解决Android设备丢失或被盗等场景下,无法有效地获取用户数据,即使将用户数据复制到其它Android设备依然可以有效保护用户的隐私数据

而对于Android设备运行过程中,攻击者通过提权等手段获取用户的隐私数据,上述技术手段无能为力。(这个又是另外的了,比如将自己的控制权限从EL1提升到EL3)

2.1、全盘加密FDE

Full-Disk Encryption,全盘加密,Android 5.0到Android 9.0版本支持,使用密钥(密钥本身也会被加密)对Android设备上的所有用户数据进行编码的过程。

设备经过加密后,所有由用户创建的数据在存入磁盘前都会自动加密,并且所有读操作都会将数据返回给调用者之前自动解密。

从Google针对FDE这段描述可知,在系统启动过程中,会随机生成userdata partition加密密钥DEK(Disk Encryption Key),同时用户还需要输入Credentials来加密保护DEK。使用时,先要求用户输入Credentials并解密DEK,接下来OS才可以使用DEK解密userdata partition上的数据。所谓用户Credentials是开机启动过程中,在锁屏界面前,OS会提供单独的UI供用户输入密码。 (现在知道为什么咱们需要在解锁手机了吗?)

从Google针对创建DEK这段描述可知,系统启动过程中产生16字节随机数作为DEK,并基于HBK和用户密钥创建KEK(Key Encryption Key)。将KEK作为输入密钥,采用AES_CBC算法加密DEK

虽然全盘加密FDE可以保护整个userdata partition,但在启动时,用户必须先提供Credentials,然后才可以访问userdata partition,这意味着用户提供Credentials前,系统无法访问用户数据,导致闹钟、无障碍服务等无法运行,手机也无法接听电话,所以全盘加密FDE逐渐被文件加密FBE替代。 (!!!突然想清楚了之前的关于这个部分的意义 )

2.2、文件加密FBE

File-Based Encryption,基于文件加密,由于Android将userdata partition格式化为F2FS类型文件系统,所以也可以理解为基于F2FS类型系统的加密。

Android 7.0及更高的版本支持FBE。采用文件级加密时,允许使用不同密钥对不同文件进行加密同时允许对加密文件进行单独解密支持文件级加密的设备支持直接启动,当使能该功能时,已加密设备在启动后可以直接进入锁屏界面,从而使用户可以快速使用Android系统的闹钟和无障碍服务。这些系统服务主要包括:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第2张图片

总而言之,可以在用户解锁前使用系统服务,同时还可以保护用户的隐私数据
(系统服务你是不需要考虑保护的,我们的目的是保护用户的隐私数据)

2.3、元数据加密ME

Android 9引入对存在硬件支持的元数据加密的支持

采用Metadata Encryption时,启动时出现的单个密钥会加密未通过FBE进行加密的任何内容,包括目录布局、文件大小、权限和创建/修改时间。

该密钥受Keymaster保护,而Keymaster受到启动时验证功能的保护。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第3张图片

(那这个意思就是干了FBEMetadata Encryption没有保护到的东西?为啥目录布局、文件大小、权限和创建/修改时间这些不能通过FBE?因为这些不是文件,元数据是指得数据的结构和信息,这个让我想起了当年玩数据库的时候的meta数据。)

三、FBE密钥框架

3.1、FBE TOP HW Architecture

Android FBE特性依赖UFS和TEE,如果芯片支持高安子系统,还依赖高安子系统。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第4张图片

TEE或高安子系统提供基于硬件环境的KMS(Key Management Service),该服务提供密钥操作

  • 如密钥创建(Key Generation)、
  • 密钥派生(Key Derivation)、
  • 密钥编程(Key Programming)等。

UFS包括UFS Core和UFS Device,UFS Controller工作在UFS Core内部,用于接收来自AP的数据和命令。

3.2、FBE TOP SW Architecture

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第5张图片

在不考虑平台高安子系统的前提下,可以从User space-Kernel space、REE-TEE等多个维度来划分FBE整体框架。

3.3、FBE设计思路

FBE将userdata partition划分为Uncrypted Storage、System DE Storage、User DE Storage和User CE Storage等4个区域:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第6张图片

不同的Storage使用不同密钥。其中,

  • System DE Storage对应SYSTEM_DE_KEY,
  • User DE Storage对应USER_DE_KEY,
  • User CE Storage对应USER_CE_KEY。

3.4、挂载文件fstab

下图是Android AOSP的挂载文件device/linaro/dragonboard/fstab.common:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第7张图片

● fileencryption

格式"fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]]",最多包含3个以英文冒号为分割参数。

● contents_encryption_mode

加密文件内容算法,可选值有"aes-256-xts"和"adiantum"。从Android 11开始,允许留空以默认加密算法,即"aes-256-xts"。

● filenames_encryption_mode

加密文件名算法,可选值有"aes-256-cts"、“aes-256-heh"和"adiantum”。如果不指定,当"contents_encryption_mode"为"aes-256-xts",该参数默认为"aes-256-cts"。如果"contents_encryption_mode"为"adiantum"时,该参数默认为"adiantum"。

● v1 & v2 flag

v2是第二版加密策略,且第二版加密策略使用更安全、更灵活的密钥派生函数。如果设备搭载Android 11或更高版本,默认选择第二版,如果设备搭载Android 10或更低版本,默认选择第一版。

● inlinecrypt_optimized

针对无法高效处理大量密钥的内嵌加密硬件进行优化的加密格式。仅为每个CE或DE密钥派生一个文件内容加密密钥,而不是为每个文件派生一个,且初始向量IV生成也会相应调整。

● emmc_optimized

与inlinecrypt_optimized类似,初始向量IV限制为32位,该标记仅在符合JEDEC eMMC v5.2规范的内嵌加密硬件上使用,因此仅支持32位IV。在其他内嵌加密硬件上,使用inlinecrypt_optimized,此标记一律不得在基于UFS的存储设备上使用(UFS规范允许使用64位IV)。

● wrappedkey_v0

在支持内嵌加密硬件的设备上,允许为FBE使用硬件封装的密钥。此标记只能与inlinecrypt挂载选项以及标记inlinecrypt_optimized或标记emmc_optimized结合使用。

四、VOLD对密钥的处理

一、 Vold简介

Android中Vold是volume Daemon,即Volume守护进程,用来管理Android中存储类的热拔插事件。这里的热插拔涉及的场景如:

1. 手机usb以MTP或者传输照片方式插拔PC端后磁盘数据的挂卸载;

2. 设备开关机过程中存储设备各分区的挂卸载;

3. T卡插拔识别过程中文件系统挂卸载。

在各场景做mount过程中,涉及到的磁盘数据的安全加密(FDE/FBE),文件节点与目录的创建,文件系统的垃圾清理等模块,也由Vold进行控制。

VOLD子系统对密钥的处理主要可以分为4步,

  • “Mount userdata partition”、
  • “Retrieve or Generate Key”、
  • “Install key into Linux Kernel Keyring”
  • “Encryption Policy”。

4.1、Mount userdata partition

Init进程是Android系统启动的第一个进程调用mount_all命令挂载userdata partition,该命令在system/core/init/builtins.cpp内实现,对应函数do_mount_all。

该命令读取并解析fstab挂载文件,在挂载userdata partition后发送event。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第8张图片

4.2、Retrieve or Generate Key

Init进程是Android系统启动的第一个进程。类似mount的处理流程,调用installkey命令创建或提取FBE Class Key,该命令在system/core/init/builtins.cpp内实现,对应函数do_installkey:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第9张图片

该函数首先判断是否为文件加密方式,如果是,则执行vdc命令,从而正式进入加密流程

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第10张图片

/system/bin/vdc进程向VOLD发送参数"cryptfs"等,最终调用fscrypt_initialize_systemwide_keys函数,该函数是VOLD子系统处理密钥的入口函数。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第11张图片

  • 首先调用get_data_file_encryption_options读取并解析挂载文件fstab,获取加密模式、加密算法和加密标志等。
  • 其次,函数retrieveOrGenerateKey的处理可以分为系统首次启动和非首次启动两种场景。
    • 当系统首次启动时,将FBE Class Key(encrypted_key)和Keymaster_key(KEK)以KeyBlob形式,并落盘到userdata partition。
    • 当系统非首次启动时,从userdata partition分别提取FBE Class Key和Keymaster_key对应KeyBlob到TEEOS的Keymaster TA进行解密。

4.2.1、解析挂载文件fstab

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第12张图片

函数ParseOptionsForApiLevel读取并解析挂载文件fstab,并填充EncryptionOptions结构体:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第13张图片

4.2.2、Retrieve or Generate Key

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第14张图片

当系统首次启动时,将FBE Class Key(encrypted_key)和Keymaster_key(KEK)以KeyBlob形式,并落盘到userdata partition。

当系统非首次启动时,从userdata partition分别提取FBE Class Key和Keymaster_key对应KeyBlob到TEEOS的Keymaster TA进行解密。

4.3、Install key into Linux Kernel Keyring

将FBE Class Key安装到Linux Kernel Keyring的入口函数是install_storage_key:
【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第15张图片

VOLD子系统下发IOCTL命令FS_IOC_ADD_ENCRYPTION_KEY到Linux Kernel Keyring,返回长度为128bit的FBE Class Key Identifier:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第16张图片

函数fscrypt_ioctl_add_key首先接收来自User Space的VOLD子系统的参数。其次可以分为系统首次启动和非首次启动两种场景进行处理。

当系统首次启动时,将Encrypted FBE Class Key保存在Linux Kernel Keyring

当系统非首次启动时,从Linux Kernel Keyring提取Encrypted FBE Class Key,最终返回FBE Class Key Identifier到VOLD子系统。这里,返回的Key Identifier使用fscrypt_key_specifier结构体来描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第17张图片

4.4、Encryption Policy

4.4.1、Encryption Policy Overview

Android FBE Encryption Policy与mkdir命令参数"encryption"的配置有关:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第18张图片

● “Encryption=Require”

强制设置和校验目录Encryption Policy,必须严格匹配。

● “Encryption=None”

不设置或不校验目录Encryption Policy,即该目录不需要加密。

● “Encryption=Attempt”

尝试设置/校验目录Encryption Policy,即使设置/校验失败,不进行任何处理。

● “Encryption=DeleteNecessary”

尝试设置/校验目录Encryption Policy,如果设置/校验失败,清空目录,并再次强制设置和校验。

4.4.2、Setup Encryption Policy

Init进程是Android系统启动的第一个进程,调用mkdir命令创建目录并设置加密策略,该命令在system/core/init/builtins.cpp内实现,对应函数do_mkdir。

在这里插入图片描述

最终调用到函数EnsurePolicy设置目录的加密策略:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第19张图片

从挂载文件fstab可知,Android FBE选择V2加密策略。接下来初始化文件内容加密模式、文件名加密模式、加密标志和密钥标识符(Key Identifier)。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第20张图片

VOLD子系统使用结构体fscrypt_policy_v2描述加密策略:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第21张图片

五、Linux Kernel对密钥的处理

5.1、内核对FBE Class Key处理框架

fscrypt用于Linux文件系统加密管理工具

  • 负责管理元数据、
  • 密钥生成、
  • 密钥封装
  • PAM 集成,
  • 并提供用于创建和修改加密目录的统一界面。

fscrypt 内核部分已集成到诸如ext4文件系统中。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第22张图片

blk-mq是 Linux 块设备层多队列机制,它将Linux Kernel存储栈中请求层的单队列改成多队列以提升性能。如果blk-mq支持内联加密(Inline Encryption),它能够在存储栈中向下传递加密上下文。在Linux Kernel源码的commit中是这样解释的:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第23张图片

这段话的含义是,必须通过某种方式让存储设备驱动程序知道应该用于加密/解密请求的加密上下文上层(如Filesystem or Fscrypt)知道情况并且管理加密上下文

当上层提交 BIO 到块层,该BIO最终到达的设备驱动程序支持内联加密,则设备驱动程序已经表明BIO加密上下文。

回落到代码上具体改动是将结构体struct bio_crypt_ctx添加到struct bio中,用来表示加密上下文,同时引入各种用于操作 bio_crypt_ctx并使 bio/request合并逻辑知晓 bio_crypt_ctx 的函数。

● Fscrypt从Kernel Keyring提取FBE Class Key。

● F2FS将Wrapped key和Encryption Policy保存在encryption context。

● KSM负责管理ICE Keyslot,维护Keyslot状态机。

● TEEOS Keymaster TA负责对ICE Keyslot执行Program和Evict操作。

5.2、Fscrypt

下面这段话是Linux Kernel对fscrypt的描述:

在这里插入图片描述
在这里插入图片描述

Fscrypt是一个库,文件系统可以通过它以支持文件和目录的透明加密功能fscrypt运行在文件系统级别,而不是块级别,这允许它使用不同的密钥加密不同的文件,并在同一文件系统上拥有未加密的文件。必须注意的是,除Filename外,fscrypt不会加密文件系统的元数据。

Fscrypt不作为本文档介绍的重点,仍然回到和FBE密钥处理相关的流程。接下来分析fscrypt如何处理目录/文件的加密策略。从4.4.2章节可知,VOLD下发IOCTL命令FS_IOC_SET_ENCRYPTION_POLICY到Linux Kernel,并调用函数fscrypt_ioctl_set_policy继续处理加密策略:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第24张图片

该函数的处理逻辑并不复杂,首先从VOLD子系统获取Encryption Policy,并将Encryption Policy保存到目录/文件的inode,保存前会先比较是否已经设置Encryption Policy,如果是,判断两次设置是否一致,不一致则报错。

5.3、F2FS filesystem

F2FS,Flash Friendly File System,专门为基于NAND存储设备设计的新型开源flash文件系统,特别针对NAND闪存存储介质进行了友好设计。

F2FS将整个卷切分成大量的Segments,每个Segment的大小固定为2MB。连续若干个Segments构成Section,连续若干个Section构成Zone。F2FS文件系统将整个卷切分成6个区域,除了超级块(Superblock,简称SB)外,其余每个区域都包含多个Segments,其结构如下图所示:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第25张图片

5.3.1、Segments

连续的Blocks集合成Segments,一个Segment的大小是512个Blocks(2MB),每个Segment都有一个Segment Summary Block元数据结构,描述了Segment 中的每个Block的所有者(该块所属的文件及块在文件内的偏移)。

Segment Summary主要用于在执行Cleaning操作时识别哪些Blocks中的数据需要转移到新的位置,以及在转移之后如何更新Blocks的索引信息。一个Block就可以完全存储512个Blocks的summary信息,每个blocks都有一个1 bit的额外空间用于其它目的。

5.3.2、Superblock

F2FS 的 f2fs_super_block 存储在设备的第二个块中,仅包含只读数据,称为超级块 Superblock 。一旦文件系统创建,SB 的信息就不会再改变,SB 描述了文件系统有多大、Segment 有多大、Section有多大、Zone 有多大以及分配了多少空间给各个部分的“元数据”区域以及其他少量的细节信息。

SB 位于文件系统分区的开头,有两个备份以避免文件系统 crash 无法恢复的情况发生。它包含基本的分区信息和默认的 F2FS 参数。

5.3.3、Main Area

Main Area被4KB大小的block所填充,这些block可以分配给文件的data或者文件的node,是F2FS文件系统的主要数据保存区域。

5.4、KSM

KeySlot Manager,密钥槽管理器,下面是Linux Kernel对KSM的描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第26张图片

由此可知,KSM是Linux kernel用于维护ICE(Inline Crypto Engine)内部keyslot硬件密钥槽的状态机,由结构体blk_keyslot_manager来描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第27张图片

该结构体的重点是成员struct blk_ksm_ll_ops ksm_ll_ops,定义对ICE Keyslot的操作函数集

成员函数keyslot_program用于对Keyslot执行Program操作,成员函数keyslot_evict用于对Keyslot执行Evict操作。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第28张图片

5.4.1、keyslot_program

以keyslot_program回调函数cqhci_crypto_keyslot_program@drivers/mmc/host/cqhci-crypto.c为例来说明如何对ICE Keyslot执行Program操作,且芯片平台厂商可以客制化。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第29张图片

该函数将参数key指向的加密上下文编程到处于idle状态的keyslot中,将编程成功keyslot index保存到参数slot。通过这种方式实现了"密钥可用不可见",即密钥被保存在ICE硬件Keyslot内,软件只可以获取保存密钥的keyslot index。

5.4.2、keyslot_evict

以keyslot_evict回调函数cqhci_crypto_keyslot_program@drivers/mmc/host/cqhci-crypto.c为例来说明如何对ICE Keyslot执行evict操作,且芯片平台厂商可以客制化。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第30张图片

根据参数key指向的加密上下文,获取在ICE硬件的keyslot index,并请求TEEOS Keymaster TA, 加解密的操作由硬件来完成。

根据keyslot index对ICE硬件内部keyslot执行evict操作通过这种方式实现了"密钥可用不可见",即密钥被保存在ICE硬件Keyslot内,软件只可以根据密钥keyslot index执行evict操作。

六、TEEOS对密钥的处理

注:以Google Trusty来分析TEEOS对AES对称密钥的处理流程。

6.1、Trusty TEE Architecture

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第31张图片

Google Trusty是一种安全OS,可为Android提供可信执行环境(TEE)。

Trusty OS和Android OS在同一处理器上运行,通过硬件和软件与系统的其余组件进行隔离(本质上就是寄存器,硬件隔离,基于ARM的安全框架),且Trusty与Android彼此并行运行(分时复用)。

Trusty可以访问设备主处理器和内存的全部功能,但完全隔离。隔离可以保护Trusty免受用户安装的恶意应用以及可能在Android中发现的潜在漏洞的侵害。(安全都可以,但是非安全只能在非安全的地儿待着。)

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第32张图片

运行时,Trusty 应用在 Trusty 内核下以隔离进程的形式在非特权模式下运行。每个进程都会利用 TEE 处理器的内存管理单元功能在各自的虚拟内存沙盒中运行。 (就是每个TA都会有自己的独立的空间,这个部分需要看一下安全内存管理那一片,在TEEOS专栏内)

6.2、Trusty Keymaster Architecture

Android Keystore API和Keymaster HAL提供一组加密原语,允许使用访问受控、硬件支持的密钥来实现协议

  • Keymaster HAL是OEM提供的可动态加载的库
  • Keystore服务使用它来提供硬件支持的加密服务。

为确保安全,HAL实现不会在用户空间甚至内核空间中执行任何敏感操作敏感操作委托给通过某些内核接口达到的TEEOS,总的框架如下图所示:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第33张图片

Android设备中,Keymaster HAL的客户端包含App、frameworks、KeyStore daemon,其目的不是实现安全敏感型算法,而是对发送到TEEOS的请求进行编排和解排真正实现安全敏感计算的是位于TEEOS的Keymaster TA。下图是Google对Keymaster架构的描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第34张图片

6.3、Keymaster Feature

下面是Google对Keymaster feature的定义:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第35张图片

可以看出,Keymaster功能强大。回归到FBE密钥框架领域,FBE密钥派生依赖Keymaster TA的Key generation特性,该特性与Key characteristics、Purpose、Client binding、Root of trust binding和version binding多重因素有关。

6.3.1、Key characteristics

无论是FBE Class key,还是加密FBE Class key的KEK,均采用AES对称算法,下面是Keymaster支持AES对称算法种类的描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第36张图片

所以,请求Keymaster派生密钥时,需要提供key characteristics:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第37张图片

6.3.2、Key Purpose

系统首次启动时需要创建FBE Class key和KEK,并以Keyblob形式落盘在userdata partition,这种场景下需要使用Keymaster加密功能

系统非首次启动时,从userdata partition提取Keyblob以获取FBE Class key和KEK,这种场景下需要使用Keymaster解密功能。

所以,向Keymaster发送请求时,需要指定密钥目的:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第38张图片

6.3.3、Client binding

Keymaster要求产生的密钥需要和对应的应用进行绑定,绑定参数是APP_ID或ADD_DATA:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第39张图片

6.3.4、Root of trust binding

下图是Google对Root of trust的描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第40张图片

6.3.5、version binding

下图是Google对version binding的描述:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第41张图片

6.4、FBE key hierarchy

下图是Android FBE密钥体系:

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第42张图片

在密钥派生系统中,主要包含"FileContens Encryption Key"、“FileName Encryption Key"和"Key Identifier”。

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第43张图片

Linux Kernel KSM模块提供回调函数可以使用blk_crypto_ll_ops::keyslot_program将FileContents Encryption Key编程到ICE硬件Keyslot内,使用blk_crypto_ll_ops::derive_sw_secret进行密钥派生。

6.5、Keymaster派生FBE Class key

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第44张图片

该函数处理逻辑并不复杂,最终FBE Class key以Keyblob形式落盘到userdata partition

七、Inline Crypto Engine

基于软件的加密解决方案使用CPU来执行加密和解密任务,虽然这种方法提供了相当多的性能,但由于需要不断提高存储速度,因此存在不足。

为了克服性能下降,JEDEC等标准机构向主机控制器内添加基于硬件的内联加密功能内联意味着硬件加密引擎位于主机控制器内部,并动态加密和解密数据。
在这里插入图片描述

就Android设备而言,内联加密引擎ICE位于UFS内部。当AP从DDR写数据到UFS Device时,需要对数据流进行加密。当AP从UFS Device读数据到DDR时,需要对数据流进行解密。下图是包含AES加解密引擎的UFS Controller内部逻辑框图:

在这里插入图片描述

【转】Linux内核安全技术(三):Android系统安全技术---FBE密钥框架和技术详解_第45张图片

八、总结

本文首先介绍了用户隐私数据保护方案,包括全盘加密FDE、文件加密FBE和元数据加密ME。

其次本着以点带面的原则,以密钥管理为主线详细梳理了VOLD子系统、Linux Kernel和TEEOS的密钥处理流程,

最后对内联加密引擎ICE进行了介绍。

希望读者可以通过这篇文档对Android文件加密FBE有整体认识,受限于篇幅,更受限于芯片厂商专利等诸多因素,很多技术细节和方案无法更详细展开,希望在后续文章中能够结合开源方案和代码可以更深入剖析FBE技术细节,如Linux Kernel Keyring、Fscrypt、文件IO等。

(简直泰裤辣!!!!!!!!!!!!!)

DEK加密保护userdata partition

KEK采用AES_CBC算法加密DEK

HBK和用户密钥创建KEK
密隐私数据的密钥叫做 DEK(Data Encryption Key),但是 DEK 不应该明文存放,否则如果从硬盘获取了 DEK,和密文,那么数据就会泄密。所以要对 DEK 再次加密,这就要用到 root key;root key 是对 DEK 加密的密钥,经过加密的 DEK 存放在磁盘上就没有问题了,经过加密的 DEK 称之为 wrapped key。Root key 是由 mater key 产生的(2.),而 master key 在初始化过程中由 master key part 运算产生(1.),并且仅仅存在于的 crypto unit 之上。

读取加密数据的过程是这样的:操作系统会把密文和经过加密的 DEK,发送给 HPCS(4&5)。因为 HPCS 中存储了 root key,因此它会使用 root key 对加了密的 DEK 进行解密(3),有了明文的 DEK,就可以解密密文,然后送回给系统了(6)。

注意,Root Key 和 Master Key 从来就没有离开过 Hyper Protect Crypto unit,因此从操作系统的角度来看,管理员永远不知道 DEK 是什么,IBM 管理员也无从知道。

在谷歌来说,通过Keymaster(架构)、Keyslot等结合硬件派生出解密DEK的RootKey,在TEE侧解密出明文的DEK,然后解密partition。

参考资料

Full Disk Encryption https://source.android.com/docs/security/features/encryption/full-disk

File-Based Encryption https://source.android.com/docs/security/features/encryption/file-based

Metadata Encryption https://source.android.com/docs/security/features/encryption/metadata

Hardware-Wrapped Keys https://source.android.com/docs/security/features/encryption/hw-wrapped-keys

Android AOSP https://cs.android.com/android/platform/superproject

Linux AOSP https://elixir.bootlin.com/linux/v5.15.111/source

Google Trusty https://source.android.com/docs/security/features/trusty

Google Keystore https://source.android.com/docs/security/features/keystore

Google Trusty Code https://github.com/haitao52198/TrustyOS/tree/master/AndroidTrustyOS

Inline Encryption https://www.synopsys.com/designware-ip/technical-bulletin/emmc-and-ufs-inline-encryption-2017q4.html

你可能感兴趣的:(安全相关,android,安全,linux)