概述
简介
FDE(Full Disk Encryption,完全
FDE 原理
FDE 加密
FDE 数据流

FDE 的
名词解释
| 缩写 | 全称/解释 |
|---|---|
| FDE | Full Disk Encrypt,完全 |
| LUKS | Linux Unified Key Setup,Linux 统一 |
| TEE | Trusted Execution Environment,可信 |
| AVB | Android Verified Boot,安卓 |
| Superblock | 超级 |
| salt | 盐值,一段 |
FDE 工具
Cryptsetup
Cryptsetup 是
工作原理
当

dm-crypt
dm-crypt 是 Linux 系统
工作原理
dm-crypt 是
当

X5 FDE用户密码管理
在
Cryptsetup 官方
方案,使用 user password 为 外部 输入,例如 保存 在 文件系统 中 的 user password 文件。 本文
介绍 的 方案 user passwd 由 TEE 派生 出来,不 保存 在 存储介质。
两者
注意: X5 推荐
方案
一: Cryptsetup 官方 方案
cryptsetup -c aes-xts-plain64 -s 256 -h sha256 -q luksFormat /dev/mmcblk0p1 -d /etc/fde_default.bin
cryptsetup -c aes-xts-plain64 -s 256 luksOpen /dev/mmcblk0p1 luksdata -d /etc/fde_default.bin
方案
二: 通过 TEE 派生 user passwd
X5 通过
user passwd 由TEE派生
出来 user passwd 不
保存 在 存储介质,只是 在 Cryptsetup 初始化 的 时候 使用
getdmkey --km | cryptsetup -c aes-xts-plain64 -s 256 -h sha256 -q luksFormat /dev/mmcblk0p1
getdmkey --km | cryptsetup -c aes-xts-plain64 -s 256 -h sha256 luksOpen /dev/mmcblk0p1 luksdata
cryptsetup 命令
-c, --cipher: 指定加密算法,例如 aes-xts-plain64是 dm-crypt 中常用 的 一种 加密算法 配置,它 指定 了 以下内容 aes: 使用 AES 对称加密算法, xts: 使用 XTS 加密模式,适用 于 磁盘 加密 等 场景 plain: 表示没有 额外 的 额外 层次 加密 或 包装
-s, --key-size: 指定密钥 长度(单位: 比特),如 128 位 或 256 位。通常 建议 使用 256 位 的 密钥 大小 --hash: 指定哈希 算法,如 sha256 或 sha512,用于 生成 加密 密钥 的 哈希 值。 -d, --key-file: 指定密钥 文件 的 路径 -q, --batch-mode: 批处理模式 下 运行 cryptsetup 命令,操作 将 不会 进行 任何 交互式 提示,所有 的 确认 和 用户 输入 都 被 自动 跳过 luksFormat: 用于格式化 一个 磁盘分区 或 设备 为 LUKS 加密 格式 luksOpen: 解锁 LUKS 加密卷,将 其 映射 为 一个 设备 luksdata: 指定 device mapper 映射的 节点 名,用户 可以 指定 为 任意 名称,此处 使用 luksdata仅作为 演示
X5 FDE 使用方法
当前 X5 支持 system 分区
system 分区
加密 可 参考 如下 方案 用户
分区 加密 支持 key-hobot 和 key-file 方案
system 分区加密
方案原理
该
编译
阶段: 在 编译 system FDE 镜像 时,FDE 相关 的 配置 信息 保存 到 了 vbmeta 分区 uboot 阶段: uboot 从 vbmeta 分区
获取 system FDE 信息,并 把 此 信息 通过 bootargs 传递 到 kernel kernel 阶段: 由 kernel 的 dm-crypt 框架
解析 bootargs,完成 system 分区 的 解密
在 bootargs 中
dm-mod.create="dm-crypt,,0,ro,0 510976 crypt aes-cbc-essiv:sha256 bf05fb0da6bc94f6b550e23a093d5fd2 0 $(SYSTEM_PART) 0 1 allow_discards
使用方法
把 system 分区的验证方式改为 crypt
根据device/horizon/x5/board_x5_evb_debug_config.mk 为例
# system 配置
# 指定根文件系统类型和预编译的文件系统路径
export HR_SYSTEM_TYPE="buildroot"
export HR_SYSTEM_DIR=${HR_TOP_DIR}/system/buildroot/prebuilt
# 根文件系统的分区名,需要和分区表配置对应
export HR_SYSTEM_PART_NAME="system"
# system verify method: dm-verity, crypt
export HR_SYSTEM_VERIFY="crypt"
注意: 修改./bd.sh lunch 选择
制作 system FDE 镜像
当前FDE key由
注意: 如何AES-128-ECB,nopad)
在 kernel 的 dm-crypt 框架
要dr-fde:,如下
dm-mod.create="dm-crypt,,0,ro,0 510976 crypt aes-cbc-essiv:sha256 dr-fde:bf05fb0da6bc94f6b550e23a093d5fd2 0 $(SYSTEM_PART) 0 1 allow_discards
user root key
user root key位于 device/horizon/x5/board_cfg/soc/bl2_cfg/user_root.key ,长度16字节
生成
用户 key 用户 可以 更换user root key,例如:随机 生成 新 的 key,操作 如下
cd device/horizon/x5/board_cfg/soc/bl2_cfg/
dd if=/dev/random of=./user_root.key bs=1 count=16
烧写 key
user root key的
烧写 请 参考 烧写efuse
注意: 没
编译与启动
执行 ./bd.sh 重新
其中,system FDE镜像build/tools/partition_tools/pack_avb_img.sh
注意:
system FDE镜像
的 制作 需要sudo权限 必须
为 secure boot 启动,且 开启 AVB 验证,否则 不会 触发 system 分区 的 解密 而 导致 根 文件系统 挂载 失败 system的
加密 信息 保存 在vbmeta分区,因此 必须OTA升级 或 烧录 时 必须 同时 升级vbmeta/boot/system分区,并且 这 三个 分区 镜像 是 在 同 一次 编译 出 产生 的
用户分区加密: key-hobot 方案
实现
新增分区
在device/horizon/x5/board_cfg/soc/x5-soc-debug-gpt.json 为例(用户
diff --git a/board_cfg/soc/x5-soc-debug-gpt.json b/board_cfg/soc/x5-soc-debug-gpt.json
index 10500f3..22a3421 100644
--- a/board_cfg/soc/x5-soc-debug-gpt.json
+++ b/board_cfg/soc/x5-soc-debug-gpt.json
@@ -39,6 +39,10 @@
"part_type": "GOLDEN",
"size": "700m"
},
+ "data": {
+ "size": "50m"
+ },
"userdata": {
"fs_type": "ext4",
"size": "50m"
注意:
若
新增 包含 内容 的 分区,则 该 分区 在 分区表 中 的 前 一个 分区 必须 为 非空(即 实际 会 生成 .img 镜像文件)。如果 是 新增 空 分区,则 不 受此 限制。 新增
的 分区 名称 中 不得 包含 下划线 _,否则分区 名称 将 在 编译 脚本 中 被 截断,从而 导致 异常。 如果
把 原有 分区 改成 FDE,需要 在 system/buildroot/prebuilt/boot-utils-runtime/etc/hb-fstab中删除 对应 分区 的 mount 规则,否则 会 mount 失败。
在 hb-crypttab 中添加 FDE 相关配置
路径 system/buildroot/prebuilt/boot-utils-runtime/etc/hb-crypttab 添加 data 分区
# <target name> <source device> <key file> <options>
data /dev/block/platform/by-name/data --key-hobot cipher=aes-xts-plain64,size=512,ext4=y
配置<target name> <source device> <key file> <options>, 参数
target name: 加密分区 名,也 是 在/dev/mapper/下 的 名字 source device: 设备路径,当前 会 对 分区 设备 自动 创建 by-name 链接,by-name 路径 都 在 /dev/block/platform/by-name下,例如对应 eMMC 分区 设备,会 链接 到 /dev/mmcblk\*p\*key file:--key-hobot表示使用TEE派生 出来 的 user passwd;另外 也 可以 指定 key 路径, 例如 /etc/fde_default.binoptions:其他参数设置。 cipher=aes-xts-plain64: 表示指定 加密算法,注意 需要 和 cryptsetup 的 -c参数匹配 size=512: 表示key size,注意需要 和 cryptsetup 的 -s参数匹配 hash=sha512: 表示对key做HASH,对应 cryptsetup 的 -h参数ext4=y: 表示加密 分区 的 文件系统 格式,加密 初始化 之后 需要 对 分区 格式化 之后 才能 挂载
注意: 如果system/buildroot/prebuilt/boot-utils-runtime/etc/fde_default.bin
在根文件系统中创建挂载节点目录
修改 system 编译build/mk_system.sh,增加 data 分区
function build_unpack()
{
...(省略)...
# 创建分区挂载目录
mkdir -p ${SYSTEM_BUILD_DIR}/{app,log,userdata,usr/hobot,data,private}
...(省略)...
}
重新
编译与启动
执行 ./bd.sh 重新
如下/dev/mapper 下

查看
[ 27.455427] CRYPTSETUP: cipher value: aes-xts-plain64
[ 27.460926] CRYPTSETUP: /dev/block/platform/by-name/data
[ 27.485172] INFO: fde luksFormat /dev/block/platform/by-name/data starting
[ 27.505462] CRYPTSETUP: key:--key-hobot src:/dev/block/platform/by-name/data dst:data
[ 40.135874] CRYPTSETUP: data
[ 40.142366] mount -t ext4 /dev/mapper/data /data
[ 40.235217] ext2fs_open2:
[ 40.235270] Bad magic number in super-block
[ 40.243783] fsck.ext4: Superblock invalid, trying backup blocks...
[ 40.267239]
The
[ 40.267259] super
[ 40.271303] block
[ 40.273973] udevd[1265]: conflicting device node '/dev/mapper/data' found, link to '/dev/dm-0' will not be created
[ 40.278746] could not be read or does not describe a valid ext2/ext3/ext4
[ 40.298703] filesystem
[ 40.298709] . If the
[ 40.302940] printk: fsck.ext4: 14 output lines suppressed due to ratelimiting
[ 40.332572] Creating filesystem with 34816 1k blocks and 8720 inodes
[ 40.338968] Filesystem UUID: e57ae31f-6f33-4c02-a2c0-6d714aeebb57
[ 40.345097] Superblock backups stored on blocks:
[ 40.345105]
[ 40.349845] 8193
[ 40.352905] ,
[ 40.354750] 24577
[ 40.361360] Allocating group tables:
[ 41.841061] printk: mkfs.ext4: 22 output lines suppressed due to ratelimiting
[ 41.885513] Pass 1: Checking
[ 41.885533] inode
[ 41.888517] s,
[ 41.890479] block
[ 41.892236] s, and sizes
[ 41.904447] Pass 2: Checking
[ 41.904464] directory
[ 41.907447] structure
[ 41.914925] Pass 3: Checking
[ 41.914939] directory
[ 41.949896] printk: fsck.ext4: 6 output lines suppressed due to ratelimiting
[ 41.966145] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Quota mode: disabled.
用户分区加密: key-file 方案
方案原理
该fdedata 为例,介绍
编译
阶段: 使用 指定 key 文件 对 用户 分区 镜像 进行 加密 启动
阶段: 启动 脚本 根据 配置文件,对 用户 分区 解密,并 挂载 到 指定 目录
使用方法
1. 新增分区与编译脚本
在fdedata 分区,以 device/horizon/x5/board_cfg/soc/x5-soc-debug-gpt.json 为例(用户
"fdedata": {
"fs_type": "ext4",
"part_type": "GOLDEN",
"size": "32m",
"fde_type": "key-file"
},
参数
fs_type: 文件系统格式,目前 仅 支持 对 ext4 格式 分区 加密 size: 分区大小 fde_type: 用于在 编译 阶段 指定 分区 加密 类型,目前 仅 支持 指定 key-file方式
注意: 如果/,由于 rootfs 默认
2. 加解密 key 文件
默认system/buildroot/prebuilt/boot-utils-runtime/etc/fde_default.bin,用户
示例: 通过
注意: key 文件大小
以 AES-128 对应 key 长度 16字节
dd if=/dev/urandom of=system/buildroot/prebuilt/boot-utils-runtime/etc/fde_default.bin bs=1 count=16
新增 fdedata 分区system/buildroot/prebuilt/boot-utils-runtime/etc/hb-crypttab。
# <target name> <source device> <key file> <options>
fdedata /dev/block/platform/by-name/fdedata /etc/fde_default.bin dm_crypt,cipher=aes-xts-plain,size=256,mntext4=/userdata/test
配置文件[分区名] [分区路径] [key文件路径] [参数]
参数
dm_crypt: 表示使用 dm-crypt 加密 用户 分区 cipher: 加密算法模式,注意 此处 应 与 编译 脚本 一致,X5 SDK 默认 使用 aes-xts-plainsize: 密钥长度,支持 256/512 mntext4: 使用 ext4 格式挂载 点 路径
3. 新增加密分区编译脚本
为了build/mk_fde.sh,用户mk_[分区名].sh,以fdedata 为例,需mk_fdedata.sh。
注意:脚本
用户
#...(省略代码)...
function build_all()
{
echo -e "\033[33m[INFO]: Starting Build User FDE Part [${PART_NAME}].\033[0m"
echo "Part Name: ${PART_NAME}"
echo "SRC Folder: ${user_part_dir}"
echo "Fs Type: ${user_fs_type}"
echo "FDE Type: ${fde_type}"
# The user adds custom actions here. Begin
# 用户在此添加自定义操作
# End
# Build EXT4 image
if [ "${user_fs_type}" = "ext4" ]; then
[ ! -d $user_part_dir ] && mkdir -p ${user_part_dir}
${HR_PARTITION_TOOL_PATH}/mk_avb_fs.sh ${PART_NAME} ${user_part_dir}
fi
#...(省略代码)...
在 xbuild.sh 增加 fdedata 的
+++ b/xbuild.sh
@@ -126,6 +126,11 @@ function build_app
build_component "app" "${HR_LOCAL_DIR}/mk_app.sh" "$@"
}
+function build_fdedata
+{
+ build_component "fdedata" "${HR_LOCAL_DIR}/mk_fdedata.sh" "$@"
+}
+
function truncate_fill_image
{
part_size=$(get_part_attr "${1}" "size")
@@ -408,7 +413,7 @@ function build_all
build_pack "$opt"
}
-avail_func=("all" "lunch" "miniboot" "uboot" "factory" "boot" "hbre" "system" "app" "pack" "otapackage")
+avail_func=("all" "lunch" "miniboot" "uboot" "factory" "boot" "hbre" "system" "app" "pack" "otapackage" "fdedata")
if [ $# -eq 0 ];then
build_all all
4. 用户加密分区源文件
用户custom/[分区名]
注意: X5 SDK 默认
以fdedata 为例,用户custom/fdedata,并
custom/
└── fdedata
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── f.txt
5. 编译
全
在 SDK 根目录sudo ./bd.sh,将
将
custom/fdedata目录打包 为 ext4 格式 镜像 使用 key 文件
对 ext4 镜像 镜像 加密,生成 out/product/fdedata.img将
out/product/fdedata.img打包进 固件 镜像 emmc_disk.simg
分区
用户sudo ./bd.sh [分区名]
注意: 编译
启动验证
系统启动/etc/init.d/S95forcefde.sh,将/etc/hb-crypttab,使用fdedata 为例:
其
# <target name> <source device> <key file> <options>
fdedata /dev/block/platform/by-name/fdedata /etc/fde_default.bin dm_crypt,cipher=aes-xts-plain,size=256,mntext4=/userdata/test
启动log如下:
[ 4.799535] udevd[302]: conflicting device node '/dev/mapper/fdedata' found, link to '/dev/dm-1' will not be created
[ 4.857102] INSECURE MODE FOR /etc/fde_default.bin
[ 4.863015] CRYPTSETUP: cipher value: aes-xts-plain
[ 4.863393] Mount Point: /userdata/test
[ 4.866874] CRYPTSETUP: /dev/block/platform/by-name/fdedata
[ 4.914790] CRYPTSETUP: dm_crypt params --type plain -c aes-xts-plain -s 256
[ 4.914908] CRYPTSETUP: dm_crypt key -d /etc/fde_default.bin
[ 4.976727] CRYPTSETUP: fdedata
系统fdedata 解密/dev/mapper/fdedata。最后/userdata/test
root@buildroot:~# mount | grep fdedata
/dev/mapper/fdedata on /userdata/test type ext4 (rw,relatime)