Anolis商密OS最佳实践之内核模块签名商密化
商密软件栈SIG :基于 Anolis OS,在整个系统软件层面(包括硬件,固件,bootloader,内核以及 OS)实现以国密算法为主的全栈国密操作系统,结束一直以来国密算法生态碎片化的状况,在技术方面打造社区和生态,在资质合规方面致力于为行业提供基于国密的信息安全标准。
作者:李艺林(伯纪),商密软件栈SIG核心成员。
欢迎更多开发者加入商密软件栈SIG:
网址:https://openanolis.cn/sig/crypto
邮件列表:tc@lists.openanolis.cn
接回上文,我们体验了 IMA 的商密化后,今天我们继续实践内核模块签名商密化。
开始之前,我们仍然需要准备与 IMA 类似的环境,配置 ShangMi 源,下载内核源码,生成商密密钥和证书。不过这次生成的密钥是用于签名内核模块,在内核模块签名我们选择使用根证书 ca.crt 直接签名,因此可以不需要生成 cert.pem 证书。
内核模块签名简介
Linux 支持只加载认证了的内核模块,开启这个功能时,可以阻止来源不明和没有认证的内核模块加载到内核,用以保护系统的安全性,这个认证也是通过数字签名来保证的,不同于 IMA 的签名,Linux 内核模块的签名是以特定的数据格式追加在文件结尾的,使用的算法通常是国际算法。
涉及到签名的场景就可以使用商密算法来替换掉国际算法,要使内核模块签名支持使用商密算法,也需对签名工具和内核本身做修改,签名工具和内核同时需要支持解析使用商密算法的 PKCS#7 数字签名,同样的,应用层商密基础能力由 BabaSSL 提供,sign-file 调用 BabaSSL 完成使用商密算法的签名。
编译内核
生成了 CA 证书之后,我们同样需要把 CA 根证书内置到内核,这就需要重新编译内核。
下载Anolis OS的ANCK内核源码
首先下载 Anolis OS 的 ANCK 内核代码,其开发分支为devel-4.19
git clone git@codeup.openanolis.cn:codeup/kernel/cloud-kernel.git -b devel-4.19
编译内核
按如下方法编译并安装集成了商密 CA 证书的内核:
# 安装编译依赖
yum install -y bison flex elfutils-libelf-devel bc make gcc
# 用上一步生成好的ca.crt作为sm2_cert.pem,使用默认配置编译内核
cp -f ca.crt <kernel_src>/certs/sm2_cert.pem
# 进入内核源码目录,使用默认配置编译内核
cd <kernel_src>
# 如果您是arm的镜像,请将arch/arm64/configs/anolis_defconfig作为.config;
# 如果是x86的,请将arch/x86/configs/anolis_defconfig作为.config。以x86为例
cp -f arch/x86/configs/anolis_defconfig .config
# 配置系统的可信跟证书为/certs/sm2_cert.pem
sed -i 's/CONFIG_SYSTEM_TRUSTED_KEYS=\"\"/CONFIG_SYSTEM_TRUSTED_KEYS=\"certs\/sm2_cert.pem\"/' .config
make
# 安装modules
make modules_install
# 安装内核,这一步也会自动生成initramfs并更新grub.cfg
make install
# 查看vmlinuz
ls -l /boot/vmlinuz*
# 将新内核(比如vmlinuz-4.19.91+ )设置为缺省的启动内核
grubby --set-default /boot/vmlinuz-4.19.91+
reboot
内核模块签名商密实践
签名
接下来我们使用内核提供的sign-file工具,给一个内核模块ko文件加上商密签名,命令如下:
${kernel_src}/scripts/sign-file sm3 ca.key ca.crt ${kmod}.ko ${kmod}.ko.signed
验证签名
通过tail ${kmod}.ko.signed 看到~Module signature appended~字样说明模块已经有了签名。
然后你可以insmod你签名后的内核模块,来判断签名是否正确。通过cat /proc/modules来查看加载的内核模块是否签名。
- O: Out-of-tree module has been loaded
- E: Unsigned module has been loaded
如果你的模块签名正确,则通过cat /proc/modules可以看到对应的模块没有E标记,以 Out-of-tree 的 hello 为例,正确签名后是这样的:
# cat /proc/modules
hello 262144 0 - Live 0xffff000003520000 (O)
如果你的模块签名失败(包括未签名),则在cat /proc/modules可以看到E标记,比如:
# cat /proc/modules
nft_fib_inet 262144 1 - Live 0xffff0000034a0000 (E)
这时候可以通过dmesg查看对应的失败原因,比如PKCS#7signature not signed with a trusted key等。
Anolis 商密软件栈将持续致力于国内商密基础设施建设,做大商用密码的软硬件生态,打造如丝般顺滑的商密应用体验,为国内数据和网络安全保驾护航。