当前位置: 首页 > news >正文

EDKII之安全启动详细介绍

文章目录

    • 安全启动简介
    • 安全启动流程介绍
    • 签名过程
    • BIOS实现
    • 小结

安全启动简介

安全启动(Secure Boot)是一种计算机系统的安全功能,旨在确保系统启动过程中只能加载经过数字签名的受信任的操作系统和启动加载程序。通过使用安全启动,系统可以防止恶意软件在启动过程中植入并运行,提高系统的安全性。

安全启动的工作原理通常包括以下几个步骤:

  1. 启动固件验证:在计算机启动时,启动固件(如UEFI固件)会验证操作系统引导加载程序的数字签名,确保其来自受信任的发布者。
  2. 操作系统验证:启动加载程序会验证操作系统内核和驱动程序的数字签名,以确保它们没有被篡改。
  3. 启动链验证:整个启动链中的每个组件都会被验证,包括引导加载程序、内核、驱动程序等。
  4. 安全启动状态:如果所有组件的数字签名验证通过,系统将进入安全启动状态,允许操作系统正常加载和运行。

通过安全启动,系统可以有效防止恶意软件在启动过程中进行植入和篡改,提高系统的整体安全性。安全启动通常与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。

在这里插入图片描述
在这里插入图片描述

  1. 加载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;
}
  1. 首先,函数会尝试从变量中读取签名数据库的数据。
  2. 如果成功读取到数据,函数会遍历签名列表,逐个比较签名数据,查找是否存在与给定签名匹配的条目。
  3. 如果找到匹配的签名,函数会将 IsFound 设置为 TRUE,表示找到了该签名。
  4. 如果在 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实现小结 安全启动简介 安全启动&#xff08;Secure Boot&#xff09;是一种计算机系统的安全功能&#xff0c;旨在确保系统启动过程中只能加载经过数字签名的受信任的操作系统和启动加载程序。通过使用安全启动&#xff0c…...

原生js上传图片

无样式上传图片 创建一个 FormData 对象&#xff1a;这个对象可以用于存储数据。 将文件添加到 FormData 对象&#xff1a;通过 append() 方法&#xff0c;将用户选择的文件添加到 formData 对象中。 使用 fetch 发送请求&#xff1a;使用 fetch API 或者其他方法将 FormDat…...

使用torch==2.5.1版本用的清华源遇到的坑

解决安装torch后,torch.cuda.is_available()结果为false的问题 清华源下载到的torch2.5.1版本的Lib\site-packages\torch\version.py 其中&#xff0c;清华源指的是&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorchhttps://mirrors.tuna.tsinghua.…...

泷羽Sec-星河飞雪-BurpSuite之解码、日志、对比模块基础使用

免责声明 学习视频来自 B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 泷羽sec官网&#xff1a;http…...

对拍详细使用方法

对拍的作用 对于我们在学校OJ&#xff0c;cf&#xff0c;牛客…各种只提供少量测试数据的题目&#xff0c;常常交上代码常常超时&#xff0c;能写出正确的暴力代码而题目要求的时间复杂度更低。然而这时你写出了能通过样例且时间复杂度更低的代码&#xff0c;但交上去就是错误…...

Python面向对象编程与模块化设计练习

需求&#xff1a; 编写一个BankAccount类&#xff0c;模拟银行账户功能&#xff1a; 属性&#xff1a;账户名、余额 方法&#xff1a;存款、取款、查询余额 使用模块将类和测试代码分离。 模块文件&#xff1a;bank_account.py 该模块包含 BankAccount 类。 class BankAccoun…...

Linux系统硬件老化测试脚本:自动化负载与监控

简介&#xff1a; 这篇文章介绍了一款用于Linux系统的自动化硬件老化测试脚本。该脚本能够通过对CPU、内存、硬盘和GPU进行高强度负载测试&#xff0c;持续运行设定的时长&#xff08;如1小时&#xff09;&#xff0c;以模拟长时间高负荷运行的环境&#xff0c;从而验证硬件的稳…...

搭建一个基于Web的文档管理系统,用于存储、共享和协作编辑文档

搭建一个基于Web的文档管理系统&#xff0c;用于存储、共享和协作编辑文档 本项目采用以下架构&#xff1a; NFS服务器: 负责存储文档资料。Web服务器: 负责提供文档访问和编辑功能。SELinux: 负责权限控制&#xff0c;确保文档安全。Git服务器: 负责存储文档版本历史&#x…...

排序学习整理(1)

1.排序的概念及运用 1.1概念 排序&#xff1a;所谓排序&#xff0c;就是使⼀串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作&#xff0c;以便更容易查找、组织或分析数据。 1.2运用 购物筛选排序 院校排名 1.3常见排序算法 2.实…...

《深入探究 Java 中的 boolean 类型》

在 Java 编程语言的世界里&#xff0c;boolean 类型虽然看似简单&#xff0c;却在程序的逻辑控制和决策中起着至关重要的作用。本文将带你深入了解 Java 中的 boolean 类型&#xff0c;从其基本概念、用法到实际应用场景&#xff0c;以及一些常见的注意事项。 一、boolean 类型…...

智享 AI 自动无人直播系统:打破地域与时间枷锁中小微企业的营销破局利器

中小微企业&#xff0c;在商业浪潮中恰似逐浪扁舟&#xff0c;常面临营销成本高、推广渠道窄、专业人才缺等 “暗礁”&#xff0c;而智享 AI 自动无人直播系统恰如精准导航的灯塔&#xff0c;助其破浪前行、突出重围。 成本维度&#xff0c;传统直播人力成本让中小微企业望而却…...

接口测试工具:reqable

背景 在众多接口测试工具中挑选出一个比较好用的接口测试工具。使用过很多工具&#xff0c;如Postman、Apifox、ApiPost等&#xff0c;基本上是同类产品&#xff0c;一般主要使用到的功能就是API接口和cURL&#xff0c;其他的功能目前还暂未使用到。 对比 性能方面&#xff…...

同时多平台git配置:GitHub和Gitee生成不同的SSH Key

文章目录 GitHub和Gitee生成不同的SSH Key步骤1&#xff1a;生成SSH Key步骤2&#xff1a;配置SSH配置文件步骤3&#xff1a;查看SSH公钥步骤4&#xff1a;将SSH公钥添加到GitHub和Gitee步骤5&#xff1a;测试SSH连接步骤6&#xff1a;添加remote远程库 GitHub和Gitee生成不同的…...

刷题计划day24 回溯(三)【复原 IP 地址】【子集】【子集 II】

⚡刷题计划day24 回溯&#xff08;三&#xff09;继续&#xff0c;回溯一共会有五个专题&#xff0c;敬请期待关注&#xff0c;可以点个免费的赞哦~ 往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 题目一&#xff1a;复原 IP…...

从“找三角形”讲“等腰三角形”

【题目】 周长为11&#xff0c;且各边长均为整数的三角形有哪些&#xff1f; 【答案】 四种&#xff0c;边长分别为&#xff1a; 2 4 5 3 3 5 1 5 5 3 4 4 【解析】 讲解等腰三角形的概念时&#xff0c;传统方法一般向学生展示一个等腰三角形的实物模型&#xff0c;这…...

Java中的泛型方法和泛型类

在Java编程语言中&#xff0c;泛型&#xff08;Generics&#xff09;是一个强大的特性&#xff0c;它使得类、接口和方法能够灵活地操作各种数据类型&#xff0c;同时保持类型安全。泛型主要通过类型参数&#xff08;Type Parameters&#xff09;来实现&#xff0c;这些类型参数…...

springboot学习-spring-boot-data-jdbc分页/排序/多表查询的例子

上次使用的是JdbcTemplate实现的&#xff0c;是比较老的方式&#xff0c;重新用spring boot data jdbc和jdbc client 实现一遍。也比较一下这几种的编码差异。数据库方面JAVA给了太多选择&#xff0c;反而不好选了。 上次就试图直接用&#xff1a; public interface UserRepo…...

通信与网络基础

1.网络通信基本概念 通信&#xff1a;人、物通过某种介质和行为进行信息传递与交流 网络通信&#xff1a;终端设备之间通过计算机网络进行通信 两个终端通过网线传递文件 多个终端通过路由器传递文件 终端通过Internet下载文件 2.信息传递过程 图1-1 假定A计算机访问B的web…...

【3.存储系统】综合大题

【考点】存储系统综合大题 【2011年408真题】某计算机存储器按字节编址&#xff0c;虚拟(逻辑)地址空间大小为16 MB&#xff0c;主存(物理)地址空间大小为1 MB&#xff0c;页面大小为4 KB&#xff1b;Cache采用直接映射方式&#xff0c;共8行&#xff1b;主存与Cache之间交换的…...

【Linux】【字符设备驱动】深入解析

Linux字符设备驱动程序用于控制不支持随机访问的硬件设备&#xff0c;如串行端口、打印机、调制解调器等。这类设备通常以字符流的形式与用户空间程序进行交互。本节将深入探讨字符设备驱动的设计原理、实现细节及其与内核其他组件的交互。 1. 引言 字符设备驱动程序是Linux内…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...