Secure Boot 签名认证的大致过程
2018-03-15 10:03 linux
申请 EA 签名证书
需要如实填写公司信息, 签名证书并不便宜, 比如 DigiCert 的三年 $499.
参考: 获取代码签名证书
编译
这一步我们来编译带有签名的 shim 文件, 在 Ubuntu 16.04 64 位系统里操作.
获取源码
$ sudo apt install git
$ git clone --branch 14 https://github.com/rhboot/shim
使用最新的版本, 14
配置编译环境
安装以下依赖包:
- gcc
- gnu-efi
- libelf-dev
- make
$ sudo apt install gnu-efi:i386 libelf-dev gcc make
生成自己的私䄴
使用 make-certs
脚本生成密钥.
然后将公䄴复制到 shim/pub.cer:
$ cp -v deepin-uefi-ca.der shim/pub.cer
修改 Makefile
14 版里面的 Makefile 对 Ubuntu 系统的支持有点儿小问题, 需要先修正一下:
$ sed -ie '/^EFI_PATH/s|/gnuefi||' -e 's/ --no-undefined$//' Makefile
编译生成 32 位 shim 文件
$ mkdir -v inst32
$ setarch linux32 make ARCH=ia32 VENDOR_CERT_FILE=pub.cer -j4 | tee inst32/build.log
$ setarch linux32 make ARCH=ia32 DESTDIR=inst32 EFIDIR=deepin install | tee inst32/install.log
编译生成 64 位 shim 文件
编译之前清空一下之前的环境:
$ make clean
再编译 64 位的:
$ mkdir -v inst64
$ make VENDOR_CERT_FILE=pub.cer -j4 | tee inst64/build.log
$ make DESTDIR=inst64 EFIDIR=deepin install | tee inst64/install.log
将生成的 shim 文件从 ELF 格式转为 cab 格式
首先安装工具:
$ sudo apt install lcab
现在依次转换32位的和64位的 shim ELF 文件
$ lcab shimx64.efi shimx64-unsigned.cab
$ lcab shimia32.efi shimia32-unsigned.cab
对生成的 shim cab 文件 做签名
先安装 DigiCert 的签名工具
安装 SafeNetAuthenticationClient-x32-x64.exe
, 然后插入 USB Key,
打开 SafeNet Authentication Client
应该就可以看到这个 Key 的授权用户了.
更新 winqual.exe 时间标签
使用 key/ 目录里的工具, 具体用法可以参数 key/readme.pdf.
signtool timestamp /t http://timestamp.verisign.com/scripts/timestamp.dll winqual.exe
正常情况下, 会提示:
Successfully timestamped: winqual.exe
签名
signtool sign /a shimia32-unsigned.cab
rename shimia32-unsigned.cab shimia32-signed.cab
signtool sign /a shimx64-unsigned.cab
rename shimx64-unsigned.cab shimx64-signed.cab
测试生成的 shim 文件
参考: UEFI 提交申请的预提交测试
提交 shim 文件
将之前使用EA证书签了名的 shim cab 文件上传到 microsoft sysdev dashboard
review shim
参考: Reviews of shim
给 grub2 签名
首先安装签名工具:
$ sudo apt install sbsigntool
然后生成 grub2 efi 文件:
$ grub2/grub-mkimage -o grubx64-unsigned.efi -O x86_64-efi \
-p /EFI/deepin ntfs hfs appleldr \
boot cat efi_gop efi_uga elf fat hfsplus iso9660 linux keylayouts memdisk \
minicmd part_apple ext2 extcmd xfs xnu part_bsd part_gpt search \
search_fs_file chain btrfs loadbios loadenv lvm minix minix2 reiserfs \
memrw mmap msdospart scsi loopback normal configfile gzio all_video efi_gop \
efi_uga gfxterm gettext echo boot chain eval ls test sleep png gfxmenu \
linuxefi
上面只是包含了一部分 grub mod, 可以根据需要删减或者追加模块, 要注意的是, linuxefi
这个模块是
必须要包含的.
要注意的是 debian sid 里面包含的 grub2.02+dfsg1-3 这个版本, debian/patches/no_insmod_on_sb.patch 里面加入的以下部分代码是多余的:
+#ifdef GRUB_MACHINE_EFI
+ if (grub_efi_secure_boot ())
+ {
+ grub_error (GRUB_ERR_ACCESS_DENIED,
+ "Secure Boot forbids loading module from %s", filename);
+ return 0;
+ }
+#endif
+
最后, 给 grub2 efi 签名:
$ sbsign --key deepin-uefi-ca.key --cert deepin-uefi-ca.crt --output grubx64.efi grubx64-unsigned.efi
给 kernel 签名
以 vmlinuz-4.15.0-1-amd64 为例:
$ sbsign --key deepin-uefi-ca.key --cert deepin-uefi-ca.crt --output vmlinuz-4.15.0-1-amd64-signed vmlinuz-4.15.0-1-amd64
用 grub2 引导签了名的内核时, 会打印一条消息:
EFI stub: UEFI Secure Boot is enabled.