EDKII之安全启动详细介绍
文章目录
- 安全启动简介
- 安全启动流程介绍
- 签名过程
- BIOS实现
- 小结
安全启动简介
安全启动(Secure Boot)是一种计算机系统的安全功能,旨在确保系统启动过程中只能加载经过数字签名的受信任的操作系统和启动加载程序。通过使用安全启动,系统可以防止恶意软件在启动过程中植入并运行,提高系统的安全性。
安全启动的工作原理通常包括以下几个步骤:
- 启动固件验证:在计算机启动时,启动固件(如UEFI固件)会验证操作系统引导加载程序的数字签名,确保其来自受信任的发布者。
- 操作系统验证:启动加载程序会验证操作系统内核和驱动程序的数字签名,以确保它们没有被篡改。
- 启动链验证:整个启动链中的每个组件都会被验证,包括引导加载程序、内核、驱动程序等。
- 安全启动状态:如果所有组件的数字签名验证通过,系统将进入安全启动状态,允许操作系统正常加载和运行。
通过安全启动,系统可以有效防止恶意软件在启动过程中进行植入和篡改,提高系统的整体安全性。安全启动通常与UEFI固件结合使用,是现代计算机系统中的重要安全功能之一。
BIOS启动过程中会执行BootLoader来加载系统,最常用的就是GRUB,它可能是一个名为bootx64.efi的UEFI应用。BIOS启动的最后会将控制权交给这个bootx64.efi,并由后者来启动系统。但是这里存在一个问题,如何保证这个应用真的是我们需要的呢?如果该应用被修改甚至替换了,导致执行一些我们不希望其执行的代码,则是一个非常严重的安全漏洞。
安全启动流程介绍


Platform Key (PK) - PK 是用于在硬件平台层和硬件平台拥有者建立起的信任关系 ,规定一个硬件平台只能被一个拥有者所拥有,即 PK 只能存在一个 ,与拥有者相关的公钥被存储在 FLASH 里面的 PK 变量里面,同时,拥有者的私钥可以来对 PK, KEK, db, dbx 进行签名和管理。
Key Exchange Key (KEK) - KEK 是用于在硬件平台和操作系统之间建立信任关系 ,KEK 的公钥可以在主板的 FLASH 存在多个不同项,即 KEK 可以存在多个 ,每一项对应一种可以被启动的操作系统,同样,KEK 的私钥可以来对 db, dbx 进行签名和管理。
Database (db) - db 是用于对 被许可的 EFI 文件予以加载的数据签名库 ,和 KEK 一样, db 的公钥可以存在很多项 。(在 UEFI 平台里面,操作系统加载文件就是一个 EFI 文件)
Database Excluded (dbx) - dbx 是一个 黑名单数据签名库 ,只要谁的 EFI 签名在这,谁就被屏蔽掉, dbx 的公钥也可以存在很多项 。后面不会使用这个。
测试方法:
建立 PK,KEK,db 密钥对,同时还需要创建EFI list。


- 加载PK。 ROOTCA.cer

加载KEK.CER,同样方法加载DB.CER
众所周知,进入EFI SHELL下,当不开启Secure Boot的时候 是可以执行efi 文件的,但是当我们打开Secure Boot 就不是所有efi 文件可以加载

签名过程
我们怎么签名Efi文件和启动项,怎么导入对应的证书呢?
```bash
#!/bin/bashecho -n "请输入一个通用名,比如公司名称或个人名字: "
read NAMEopenssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME PK/" -keyout PK.key \-out PK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME KEK/" -keyout KEK.key \-out KEK.crt -days 3650 -nodes -sha256
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=$NAME DB/" -keyout DB.key \-out DB.crt -days 3650 -nodes -sha256
openssl x509 -in PK.crt -out PK.cer -outform DER
openssl x509 -in KEK.crt -out KEK.cer -outform DER
openssl x509 -in DB.crt -out DB.cer -outform DERecho $(uuidgen) > myGUID.txtcert-to-efi-sig-list -g $GUID PK.crt PK.esl
cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl
cert-to-efi-sig-list -g $GUID DB.crt DB.esl
rm -f noPK.esl
touch noPK.eslsign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \-k PK.key -c PK.crt PK PK.esl PK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \-k PK.key -c PK.crt PK noPK.esl noPK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \-k PK.key -c PK.crt KEK KEK.esl KEK.auth
sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \-k KEK.key -c KEK.crt db DB.esl DB.auth
echo ""
echo "For use with KeyTool, copy the *.auth and *.esl files to a FAT USB"
echo "flash drive or to your EFI System Partition (ESP)."
echo "For use with most UEFIs' built-in key managers, copy the *.cer files."
echo ""
运行后生成一组密钥
`
``

使用密钥签名Efi文件,对于SecurityBoot就时需要将Grub.efi Boot.efi 去签名 让BIOS去LoadImage 时通过校验
sbsign --key db.key --cert db.crt --output grubx64sign.efi.signed grub64.efi
apt-get install sbsigntool

导入证书后, Sign过的efi 才能运行 否则会返回无权限。
当不添加DB 时去加载签名过的EFI 会显示 Image被签名但是不在DB中 。 PK是可以去校验签名 但是DB时我们的签名白名单支持库。

BIOS实现
在BIOS中加载EFI File会使用gbs->LoadImage去加载镜像,调用的的函数原型是 CoreLoadImageCommon
该函数就包含了安全校验`
Security2StubAuthenticate -->Defer3rdPartyImageLoad


使用证书签名文件后,可以看到会在EFI文件后面加一段密钥相关的二进制内容 里面就包含了使用的证书公钥等一些信息

BIOS中校验File中是否由DB/DBX的Signature,主要使用IsSignatureFoundInDatabase 去检查。
///
/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
/// for the authorized signature database.
///
#define EFI_IMAGE_SECURITY_DATABASE L"db"
///
/// Varialbe name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
/// for the forbidden signature database.
///
#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"EFI_STATUS
IsSignatureFoundInDatabase (IN CHAR16 *VariableName,IN UINT8 *Signature,IN EFI_GUID *CertType,IN UINTN SignatureSize,OUT BOOLEAN *IsFound)
{EFI_STATUS Status;EFI_SIGNATURE_LIST *CertList;EFI_SIGNATURE_DATA *Cert;UINTN DataSize;UINT8 *Data;UINTN Index;UINTN CertCount;//// Read signature database variable.//*IsFound = FALSE;Data = NULL;DataSize = 0;Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);if (Status != EFI_BUFFER_TOO_SMALL) {if (Status == EFI_NOT_FOUND) {//// No database, no need to search.//Status = EFI_SUCCESS;}return Status;}Data = (UINT8 *)AllocateZeroPool (DataSize);if (Data == NULL) {return EFI_OUT_OF_RESOURCES;}Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);if (EFI_ERROR (Status)) {goto Done;}//// Enumerate all signature data in SigDB to check if signature exists for executable.//CertList = (EFI_SIGNATURE_LIST *)Data;while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);if ((CertList->SignatureSize == sizeof (EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid (&CertList->SignatureType, CertType))) {for (Index = 0; Index < CertCount; Index++) {if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {//// Find the signature in database.//*IsFound = TRUE;//// Entries in UEFI_IMAGE_SECURITY_DATABASE that are used to validate image should be measured//if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) {SecureBootHook (VariableName, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);}break;}Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);}if (*IsFound) {break;}}DataSize -= CertList->SignatureListSize;CertList = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);}
Done:if (Data != NULL) {FreePool (Data);}return Status;
}
- 首先,函数会尝试从变量中读取签名数据库的数据。
- 如果成功读取到数据,函数会遍历签名列表,逐个比较签名数据,查找是否存在与给定签名匹配的条目。
- 如果找到匹配的签名,函数会将
IsFound设置为TRUE,表示找到了该签名。 - 如果在
EFI_IMAGE_SECURITY_DATABASE中找到了签名,还会调用SecureBootHook函数来处理安全启动相关的操作。
主要是将变量度量信息存入到TPM PCR中
SECUREBOOT_CONFIG_PRIVATE_DATA mSecureBootConfigPrivateDateTemplate = {SECUREBOOT_CONFIG_PRIVATE_DATA_SIGNATURE,{SecureBootExtractConfig,SecureBootRouteConfig,SecureBootCallback}
};HiiHandle = HiiAddPackages (&gSecureBootConfigFormSetGuid,DriverHandle,SecureBootConfigDxeStrings,SecureBootConfigBin,NULL);
Vfr中都使用Label 在C中动态更新页面:
多个Lable 都在C中去动态更新
label FORMID_ENROLL_PK_FORM;
label LABEL_END;
label FORMID_ENROLL_KEK_FORM;
label LABEL_END;
label SECUREBOOT_ENROLL_SIGNATURE_TO_DB;
label LABEL_END;
label SECUREBOOT_ENROLL_SIGNATURE_TO_DBX;
label LABEL_END;
label FORMID_ENROLL_PK_FORM;
label LABEL_END;
小结
Security Boot 就是一层对于LoadImage file 去进行签名验签的过程,来保证加载的系统是安全的
详细信息都可以参考EDKII 的源码
相关文章:
EDKII之安全启动详细介绍
文章目录 安全启动简介安全启动流程介绍签名过程BIOS实现小结 安全启动简介 安全启动(Secure Boot)是一种计算机系统的安全功能,旨在确保系统启动过程中只能加载经过数字签名的受信任的操作系统和启动加载程序。通过使用安全启动,…...
原生js上传图片
无样式上传图片 创建一个 FormData 对象:这个对象可以用于存储数据。 将文件添加到 FormData 对象:通过 append() 方法,将用户选择的文件添加到 formData 对象中。 使用 fetch 发送请求:使用 fetch API 或者其他方法将 FormDat…...
使用torch==2.5.1版本用的清华源遇到的坑
解决安装torch后,torch.cuda.is_available()结果为false的问题 清华源下载到的torch2.5.1版本的Lib\site-packages\torch\version.py 其中,清华源指的是: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorchhttps://mirrors.tuna.tsinghua.…...
泷羽Sec-星河飞雪-BurpSuite之解码、日志、对比模块基础使用
免责声明 学习视频来自 B 站up主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 泷羽sec官网:http…...
对拍详细使用方法
对拍的作用 对于我们在学校OJ,cf,牛客…各种只提供少量测试数据的题目,常常交上代码常常超时,能写出正确的暴力代码而题目要求的时间复杂度更低。然而这时你写出了能通过样例且时间复杂度更低的代码,但交上去就是错误…...
Python面向对象编程与模块化设计练习
需求: 编写一个BankAccount类,模拟银行账户功能: 属性:账户名、余额 方法:存款、取款、查询余额 使用模块将类和测试代码分离。 模块文件:bank_account.py 该模块包含 BankAccount 类。 class BankAccoun…...
Linux系统硬件老化测试脚本:自动化负载与监控
简介: 这篇文章介绍了一款用于Linux系统的自动化硬件老化测试脚本。该脚本能够通过对CPU、内存、硬盘和GPU进行高强度负载测试,持续运行设定的时长(如1小时),以模拟长时间高负荷运行的环境,从而验证硬件的稳…...
搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档
搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档 本项目采用以下架构: NFS服务器: 负责存储文档资料。Web服务器: 负责提供文档访问和编辑功能。SELinux: 负责权限控制,确保文档安全。Git服务器: 负责存储文档版本历史&#x…...
排序学习整理(1)
1.排序的概念及运用 1.1概念 排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作,以便更容易查找、组织或分析数据。 1.2运用 购物筛选排序 院校排名 1.3常见排序算法 2.实…...
《深入探究 Java 中的 boolean 类型》
在 Java 编程语言的世界里,boolean 类型虽然看似简单,却在程序的逻辑控制和决策中起着至关重要的作用。本文将带你深入了解 Java 中的 boolean 类型,从其基本概念、用法到实际应用场景,以及一些常见的注意事项。 一、boolean 类型…...
智享 AI 自动无人直播系统:打破地域与时间枷锁中小微企业的营销破局利器
中小微企业,在商业浪潮中恰似逐浪扁舟,常面临营销成本高、推广渠道窄、专业人才缺等 “暗礁”,而智享 AI 自动无人直播系统恰如精准导航的灯塔,助其破浪前行、突出重围。 成本维度,传统直播人力成本让中小微企业望而却…...
接口测试工具:reqable
背景 在众多接口测试工具中挑选出一个比较好用的接口测试工具。使用过很多工具,如Postman、Apifox、ApiPost等,基本上是同类产品,一般主要使用到的功能就是API接口和cURL,其他的功能目前还暂未使用到。 对比 性能方面ÿ…...
同时多平台git配置:GitHub和Gitee生成不同的SSH Key
文章目录 GitHub和Gitee生成不同的SSH Key步骤1:生成SSH Key步骤2:配置SSH配置文件步骤3:查看SSH公钥步骤4:将SSH公钥添加到GitHub和Gitee步骤5:测试SSH连接步骤6:添加remote远程库 GitHub和Gitee生成不同的…...
刷题计划day24 回溯(三)【复原 IP 地址】【子集】【子集 II】
⚡刷题计划day24 回溯(三)继续,回溯一共会有五个专题,敬请期待关注,可以点个免费的赞哦~ 往期可看专栏,关注不迷路, 您的支持是我的最大动力🌹~ 目录 题目一:复原 IP…...
从“找三角形”讲“等腰三角形”
【题目】 周长为11,且各边长均为整数的三角形有哪些? 【答案】 四种,边长分别为: 2 4 5 3 3 5 1 5 5 3 4 4 【解析】 讲解等腰三角形的概念时,传统方法一般向学生展示一个等腰三角形的实物模型,这…...
Java中的泛型方法和泛型类
在Java编程语言中,泛型(Generics)是一个强大的特性,它使得类、接口和方法能够灵活地操作各种数据类型,同时保持类型安全。泛型主要通过类型参数(Type Parameters)来实现,这些类型参数…...
springboot学习-spring-boot-data-jdbc分页/排序/多表查询的例子
上次使用的是JdbcTemplate实现的,是比较老的方式,重新用spring boot data jdbc和jdbc client 实现一遍。也比较一下这几种的编码差异。数据库方面JAVA给了太多选择,反而不好选了。 上次就试图直接用: public interface UserRepo…...
通信与网络基础
1.网络通信基本概念 通信:人、物通过某种介质和行为进行信息传递与交流 网络通信:终端设备之间通过计算机网络进行通信 两个终端通过网线传递文件 多个终端通过路由器传递文件 终端通过Internet下载文件 2.信息传递过程 图1-1 假定A计算机访问B的web…...
【3.存储系统】综合大题
【考点】存储系统综合大题 【2011年408真题】某计算机存储器按字节编址,虚拟(逻辑)地址空间大小为16 MB,主存(物理)地址空间大小为1 MB,页面大小为4 KB;Cache采用直接映射方式,共8行;主存与Cache之间交换的…...
【Linux】【字符设备驱动】深入解析
Linux字符设备驱动程序用于控制不支持随机访问的硬件设备,如串行端口、打印机、调制解调器等。这类设备通常以字符流的形式与用户空间程序进行交互。本节将深入探讨字符设备驱动的设计原理、实现细节及其与内核其他组件的交互。 1. 引言 字符设备驱动程序是Linux内…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
