boot 加密介绍

Linux 内核镜像是操作系统的核心部分,它负责管理硬件、执行进程调度、内存管理和其他系统级任务,因此,它的安全性对于操作系统的整体安全性至关重要。

Kernel 加密的目的

  • 防止未授权访问:加密内核镜像可以防止未经授权的用户查看内核文件,确保系统的机密性和完整性。

  • 防止篡改:攻击者可能会注入恶意代码或后门,导致系统被完全控制

  • 增强启动链的安全性:提高启动过程的安全性,防止恶意修改启动加载过程

Kernel 加密造成的影响

  • 性能开销:加密和解密操作需要计算资源,可能会导致启动过程的延迟或系统性能下降。

  • 密钥管理:管理加密密钥是一项挑战,尤其是在嵌入式设备上,密钥的泄露可能导致整个系统的安全性受损。

  • 兼容性问题:加密的内核镜像可能会在某些硬件或配置下存在兼容性问题,尤其是在支持加密的 bootloader 上。

boot 加密使用方法

boot 加密原理

在 FIT (Flattened Image Tree) 镜像中,cipher 参数用于指定与加密相关的选项。FIT 镜像通常用于嵌入式系统中,它支持多种加密方法来保护内核镜像、设备树、根文件系统等文件。通过配置 cipher 参数,FIT 镜像能够在加密和解密过程中指定加密算法、密钥管理等细节。

X5 支持对 Kernel (即 boot 分区) 加密。采用 AES 对称加密方式,默认不开启。 通过使用 FIT 包添加 cipher 参数的形式开启 boot 加密。

cipher 参数包含以下属性

  • algo : 加密使用的算法,支持多种算法,使用逗号隔开,例如 aes,sha256,rsa2048

  • key-name-hint : 加密使用的密钥文件

  • iv-name-hint : 加密使用的 IV 文件

X5 BSP 根据使用场景预置了 its 文件。路径 device/horizon/x5/board_cfg/soc/boot_its目录。

its文件 是否支持 Recovery 是否开启 boot 加密
x5-common.its N N
x5-recovery.its Y N
x5-enc-common.its N Y
x5-enc-recovery.its Y Y

x5-common.itsx5-enc-common.its 为例,二者差异是增加了 cipher 属性如下

26c26,32
<                       */
---
...(部分省略代码)...
>                       cipher {
>                               algo = "aes128";
>                               key-name-hint = "fit_enc_key";
>                               iv-name-hint = "fit_enc_iv";
>                       };
...(部分省略代码)...

由编译脚本 build/mk_boot.sh 根据使用场景选择不同的 its 文件,并调用 mkimage 工具制作 FIT 镜像

function pack_boot_fit()
{
	# ...(部分省略代码)...
	if [ "${HR_RECOVERY_MODE}" = "yes" ];then      # 支持 Recovery
		if [ "${HR_BOOT_ENC}" = "true" ];then      # 开启 boot 加密
			cp -a "${HR_BOARD_CONF_DIR}"/boot_its/x5-enc-recovery.its "${KERNEL_DEPLOY_DIR}/x5.its"
			"${MKIMAGE_PREFIX}"/mkimage -f "${KERNEL_DEPLOY_DIR}"/x5.its \
				"${HR_TARGET_PRODUCT_DIR}"/boot.img -k "${HR_BOARD_CONF_DIR}"/key_files
		else                                       # 关闭 boot 加密
			cp -a "${HR_BOARD_CONF_DIR}"/boot_its/x5-recovery.its "${KERNEL_DEPLOY_DIR}/x5.its"
			"${MKIMAGE_PREFIX}"/mkimage -f "${KERNEL_DEPLOY_DIR}"/x5.its \
				"${HR_TARGET_PRODUCT_DIR}"/boot.img
		fi
	else                                           # 关闭 Recovery
		if [ "${HR_BOOT_ENC}" = "true" ];then      # 开启 boot 加密
			cp -a "${HR_BOARD_CONF_DIR}"/boot_its/x5-enc-common.its "${KERNEL_DEPLOY_DIR}/x5.its"
			"${MKIMAGE_PREFIX}"/mkimage -f "${KERNEL_DEPLOY_DIR}"/x5.its \
				"${HR_TARGET_PRODUCT_DIR}"/boot.img -k "${HR_BOARD_CONF_DIR}"/key_files
		else                                       # 关闭 boot 加密
			cp -a "${HR_BOARD_CONF_DIR}"/boot_its/x5-common.its "${KERNEL_DEPLOY_DIR}/x5.its"
			"${MKIMAGE_PREFIX}"/mkimage -f "${KERNEL_DEPLOY_DIR}"/x5.its \
				"${HR_TARGET_PRODUCT_DIR}"/boot.img
		fi
	fi

	# ...(部分省略代码)...
}

开启 boot 加密

boot 加密默认不开启,开启方法: 在板级配置文件中添加 export HR_BOOT_ENC="true"

用户根据使用配置文件修改,以 device/horizon/x5/board_x5_evb_debug_config.mk 为例。

diff --git a/board_x5_evb_debug_config.mk b/board_x5_evb_debug_config.mk
index 3981858..3443367 100644
--- a/board_x5_evb_debug_config.mk
+++ b/board_x5_evb_debug_config.mk
@@ -8,7 +8,7 @@ export HR_TARGET_MODE="debug"

 # 板级名称,对应每一个新的硬件型号
 export HR_BOARD_TYPE="soc"
+export HR_BOOT_ENC="true"
 # 编译out目录

注意: 修改配置文件后需 ./bd.sh lunch 选择对应配置文件,使配置选项生效

boot 密钥存储

boot 加密密钥存储

boot 密钥的安全存储是防止恶意攻击的首要步骤。 X5 BSP boot 加密使用的 key 和 iv 文件路径 device/horizon/x5/board_cfg/soc/key_files/fit_enc_key.bindevice/horizon/x5/board_cfg/soc/key_files/fit_enc_iv.bin

用户可根据实际使用替换为自己使用的 key。

注意:key 和 iv 文件内容以 ASCII 字符形式保存

uboot 获取密钥

在嵌入式系统启动流程中,Uboot 需要在启动过程中对内核镜像进行解密。而解密操作需要密钥。为了保证内核镜像的安全性,密钥通常不应硬编码在 U-Boot 或内核源代码中。相反,密钥应保存在 U-Boot 启动环境中,以便在启动时读取。这个过程涉及密钥的存储、检索、解密操作的执行等多个方面。

X5 Uboot 获取密钥有以下两种方式

方式1: 通过 dts 获取

在一些嵌入式平台上,U-Boot 使用设备树来描述硬件配置和资源,设备树(Device Tree)本质上是一个数据结构,U-Boot 使用它来识别硬件组件并进行初始化。也可以利用设备树来存储用于解密内核的密钥信息。

使用方法

X5 Uboot 设备树文件路径 uboot/arch/arm/dts/x5.dtsi,在根节点上添加 cipher 节点,并修改启动 key 和 iv 属性即可,如下:

cipher {
        key-aes128-fit_enc_key-fit_enc_iv {
                key = "2222222222222222";
                iv =  "1111111111111111";
        };
};

注意: 设备树通常是未加密的,这可能会导致密钥暴露

方式2: 通过 RPMB 获取

相比较方式1 从 dts 获取密钥,更安全的做法是将密钥存储在硬件安全模块中,对于 eMMC 存储介质,可使用 RPMB 存储密钥。

RPMB 介绍

eMMC 中有一个特殊的存储区域,称为 RPMB(Replay Protected Memory Block),这是一个加密保护的区域,用于存储敏感数据。其主要特点是数据保护和防重放攻击,通过加密和签名来确保存储数据的完整性和安全性。

RPMB 的特性

  • 防篡改:RPMB 区域的数据被加密存储,且无法被普通的读写操作直接访问。任何对 RPMB 区域的读取和写入操作都需要经过密钥认证。

  • 密钥保护:RPMB 使用一个密钥(通常由硬件生成并存储在设备内)来加密存储的数据。这个密钥是受保护的,无法直接读取。

  • 防重放攻击:RPMB 提供了防止重放攻击的机制,确保每个写操作都具有唯一性,避免了数据被重复提交的风险。

  • 独立区域:RPMB 是 eMMC 存储卡的一个独立区域,通常与其他存储区域(如用户数据存储区)隔离开来。

使用方法

要开启 U-boot 通过 RPMB 读取 key 和 iv,需要开启 U-boot 选项 CONFIG_DROBOT_BOOT_KEY_IN_RPMB

注意

key 对应保存在 RPMB 中的名字要与 its 中的一致,即 fit_enc_key,iv 对应的名字是fit_enc_iv,写入的 key 和 iv 以 ASCII 形式表示

RPMB 的使用请参考secure storage