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

[UEFI架构]必不可少的SecurityArch

在UEFI架构下,gEfiSecurityArchProtocolGuid作为一个必须实现的Protocol,gEfiSecurity2ArchProtocolGuid作为一个Option Protocol;

首先看看SecurityStubDxe的驱动内容如何

EFI_STATUS EFIAPI SecurityStubInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; // // Make sure the Security Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiSecurity2ArchProtocolGuid); ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiSecurityArchProtocolGuid); // // Install the Security Architectural Protocol onto a new handle // Status = gBS->InstallMultipleProtocolInterfaces ( &mSecurityArchProtocolHandle, &gEfiSecurity2ArchProtocolGuid, &mSecurity2Stub, &gEfiSecurityArchProtocolGuid, &mSecurityStub, NULL ); ASSERT_EFI_ERROR (Status); Defer3rdPartyImageLoadInitialize ();

驱动本体看起来比较简单,安装gEfiSecurityArchProtocolGuid/gEfiSecurity2ArchProtocolGuid 两个 Protocol;

而Defer3rdPartyImageLoadInitialize中则会安装gEfiDeferredImageLoadProtocolGuid Protocol,并且在DxeSmmReadyToLock中检查是否有第三方的Module在 EndOfDxe 到 SmmReadyToLock 这个时间段被执行过, 如果有,那么这个系统认定为不可信状态,直接进入CpuDeadLoop,不在继续启动了;那一个正确的执行顺序应该是 EndOfDxe -> SmmReadyToLock -> 3rd Module;

VOID Defer3rdPartyImageLoadInitialize ( VOID ) { EFI_STATUS Status; EFI_HANDLE Handle; EFI_EVENT Event; VOID *Registration; Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiDeferredImageLoadProtocolGuid, &mDeferredImageLoad, NULL ); ASSERT_EFI_ERROR (Status); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, EndOfDxe, NULL, &gEfiEndOfDxeEventGroupGuid, &Event ); ASSERT_EFI_ERROR (Status); EfiCreateProtocolNotifyEvent ( &gEfiDxeSmmReadyToLockProtocolGuid, TPL_CALLBACK, DxeSmmReadyToLock, NULL, &Registration ); } VOID EFIAPI DxeSmmReadyToLock ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; VOID *Interface; Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); if (EFI_ERROR (Status)) { return; } gBS->CloseEvent (Event); if (mImageLoadedAfterEndOfDxe) { // // Platform should not dispatch the 3rd party images after signaling EndOfDxe event // but before publishing DxeSmmReadyToLock protocol. // DEBUG (( DEBUG_ERROR, "[Security] 3rd party images must be dispatched after DxeSmmReadyToLock Protocol installation!\n" )); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE) ); ASSERT (FALSE); CpuDeadLoop (); } }

我们继续看安装的gEfiSecurityArchProtocolGuid到底有什么作用

EFI_STATUS EFIAPI SecurityStubAuthenticateState ( IN CONST EFI_SECURITY_ARCH_PROTOCOL *This, IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File ) { EFI_STATUS Status; Status = ExecuteSecurity2Handlers ( EFI_AUTH_OPERATION_AUTHENTICATION_STATE, AuthenticationStatus, File, NULL, 0, FALSE ); if (Status == EFI_SUCCESS) { Status = ExecuteSecurityHandlers (AuthenticationStatus, File); } return Status; } ExecuteSecurity2Handlers ( IN UINT32 AuthenticationOperation, IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL, IN VOID *FileBuffer, IN UINTN FileSize, IN BOOLEAN BootPolicy ) { ...... // // Directly return successfully when no handler is registered. // if (mNumberOfSecurity2Handler == 0) { return EFI_SUCCESS; } // // Run security handler in same order to their registered list // for (Index = 0; Index < mNumberOfSecurity2Handler; Index++) { // // If FileBuffer is not NULL, the input is Image, which will be handled by EFI_AUTH_IMAGE_OPERATION_MASK operation. // If FileBuffer is NULL, the input is not Image, which will be handled by EFI_AUTH_NONE_IMAGE_OPERATION_MASK operation. // Other cases are ignored. // if (((FileBuffer != NULL) && ((mSecurity2Table[Index].Security2Operation & EFI_AUTH_IMAGE_OPERATION_MASK) != 0)) || ((FileBuffer == NULL) && ((mSecurity2Table[Index].Security2Operation & EFI_AUTH_NONE_IMAGE_OPERATION_MASK) != 0))) { // // Execute registered handlers based on input AuthenticationOperation // if ((mSecurity2Table[Index].Security2Operation & AuthenticationOperation) != 0) { Status = mSecurity2Table[Index].Security2Handler ( AuthenticationStatus, File, FileBuffer, FileSize, BootPolicy );

从ExecuteSecurity2Handlers 中可以看到,如果mNumberOfSecurity2Handler>0,则根据条件执行对应的mSecurity2Table[Index].Security2Handler;

EFI_STATUS EFIAPI RegisterSecurity2Handler ( IN SECURITY2_FILE_AUTHENTICATION_HANDLER Security2Handler, IN UINT32 AuthenticationOperation ) { EFI_STATUS Status; ASSERT (Security2Handler != NULL); // // Make sure AuthenticationOperation is valid in the register order. // ASSERT (CheckAuthentication2Operation (mCurrentAuthOperation2, AuthenticationOperation)); mCurrentAuthOperation2 = mCurrentAuthOperation2 | AuthenticationOperation; // // Check whether the handler lists is enough to store new handler. // if (mNumberOfSecurity2Handler == mMaxNumberOfSecurity2Handler) { // // Allocate more resources for new handler. // Status = ReallocateSecurity2HandlerTable (); ASSERT_EFI_ERROR (Status); } // // Register new handler into the handler list. // mSecurity2Table[mNumberOfSecurity2Handler].Security2Operation = AuthenticationOperation; mSecurity2Table[mNumberOfSecurity2Handler].Security2Handler = Security2Handler; mNumberOfSecurity2Handler++; return EFI_SUCCESS; }

mNumberOfSecurity2Handler 则通过 RegisterSecurity2Handler 调用会递增;至于谁来调用RegisterSecurity2Handler,暂时先放置一边;

先来看看谁调用SecurityArch Protocol 里边的FileAuthentication,实际上在LoadImage的时候就调用了;

EFI_STATUS CoreLoadImageCommon ( IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN VOID *SourceBuffer OPTIONAL, IN UINTN SourceSize, IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, IN OUT UINTN *NumberOfPages OPTIONAL, OUT EFI_HANDLE *ImageHandle, OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, IN UINT32 Attribute ) { ...... if (gSecurity2 != NULL) { // // Verify File Authentication through the Security2 Architectural Protocol // SecurityStatus = gSecurity2->FileAuthentication ( gSecurity2, OriginalFilePath, FHand.Source, FHand.SourceSize, BootPolicy );

在Defer3rdPartyImageLoad中有如果是 FV里边的Image,则直接返回成功,后边则会继续调用ExecuteSecurity2Handlers来处理;

if (FileFromFv (File)) { return EFI_SUCCESS; }

那针对第三方驱动,如果已经EndOfDxe了,则也会返回成功,后边则会继续调用ExecuteSecurity2Handlers来处理;如果在EndOfDxe之前,则通过QueueImage放置在mDeferred3rdPartyImage中,并返回EFI_ACCESS_DENIED,暂时不执行;

if (mEndOfDxe) { mImageLoadedAfterEndOfDxe = TRUE; // // The image might be first time loaded after EndOfDxe, // So ImageInfo can be NULL. // if (ImageInfo != NULL) { ImageInfo->Loaded = TRUE; } return EFI_SUCCESS; } else { // // The image might be second time loaded before EndOfDxe, // So ImageInfo can be non-NULL. // if (ImageInfo == NULL) { QueueImage (File, BootPolicy); } return EFI_ACCESS_DENIED; }

那么3rdImage 什么时候执行 ?

VOID EFIAPI PlatformBootManagerBeforeConsole ( VOID ) { ...... // // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers // the preparation of S3 system information. That logic has a hard dependency // on the presence of the FACS ACPI table. Since our ACPI tables are only // installed after PCI enumeration completes, we must not trigger the S3 save // earlier, hence we can't signal End-of-Dxe earlier. // EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); ...... // // Prevent further changes to LockBoxes or SMRAM. // Any TPM 2 Physical Presence Interface opcode must be handled before. // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); // // Dispatch deferred images after EndOfDxe event and ReadyToLock // installation. // EfiBootManagerDispatchDeferredImages ();

在Bds阶段PlatformBootManagerBeforeConsole 会首先执行 EndOfDxe, 然后 SmmReadyToLock, 这时才会执行3rdImage, EfiBootManagerDispatchDeferredImages 通过LoadImage -> StartImage来执行;那这个时候LoadImage仍然会调用SecurityArch Protocol 里边的FileAuthentication,这时已经属于EndOfDxe了,则会继续调用ExecuteSecurity2Handlers来处理;

总结:

1.LoadImage时会调用SecurityArch Protocol, ExecuteSecurity2Handlers 可以用来针对Image进行一些安全机制相关的处理

2.如果在EndOfDxe之前,3rd Image则会保存到Deferred List 里边, 最后调用顺序为 EndOfDxe -> SmmReadyToLock -> 3rd Image Start Image

http://www.jsqmd.com/news/980293/

相关文章:

  • AI技术写作规范:如何避免虚构与失实内容
  • 如何轻松掌控AMD Ryzen处理器?这款免费调试工具让你成为硬件专家!
  • 【C++初阶】析构函数超详解(误区、语法、调用时机、析构顺序)
  • Horizon UAG部署后连接服务器还是红叉?别慌,教你一步步排查(从日志分析到FQDN解析)
  • 萤石 ERTC 如何一站式解决智能家居各类通话需求?
  • SolidWorks许可回收误杀率,对比三款横评
  • 计算机毕业设计之django基于Python的bs架构的进门审批管理系统设计与开发
  • 2026长治市黄金回收铂金回收白银回收彩金回收机构实力:项链+戒指+手镯+吊坠专业鉴定上门服务及联系方式推荐 - 亦辰小黄鸭
  • Web数据供应链:从爬虫到AI可信数据资产的四层架构
  • 每日一Go-76(架构篇)|多集群部署 / 容灾 / Failover / Backup / 热迁移
  • 别再只搜Star数了!用GitHub Topics和高级搜索,5分钟找到真正适合你的开源项目
  • 7.5元包邮的RC522读卡器,手把手教你用Arduino Uno复制小区门禁卡(附完整接线图与代码)
  • Python新手必看:用input()和eval()处理用户输入,一个函数搞定五种数学运算
  • 生成式AI发展现状与中长期技术演进趋势分析
  • 《医院HIS药房模块实战避坑系列》之一:月中药品调价+跨价退药账务处理全解析
  • 别再只用print了!Python格式化输出M和N运算结果的3种高级技巧
  • 本地运行的QQ账号绑定信息扫描器(2025绿色单文件版)
  • 企业AI知识库开发服务商推荐,2026年最新测评
  • AI建站工具全流程攻略:从零开始搭建可商用网站
  • 别再为Aspose.Words水印发愁了!手把手教你用JD-GUI搞定19.1版本本地化部署
  • 2026昭通市黄金回收铂金回收白银回收彩金回收机构实力:项链+戒指+手镯+吊坠专业鉴定上门服务及联系方式推荐 - 亦辰小黄鸭
  • HarmonyOS6 map.calculateDistance vs Haversine:两种距离计算方案对比
  • 跨境多店铺管理混乱,先排查浏览器环境边界
  • 人文综合素养类赛事解析,文科生的竞赛新赛道
  • 使用Perfetto网页直接抓取trace 注意事项
  • 餐饮扫码点餐系统源码:支持外卖+自取、多店独立运营,Java后端+Vue3前端
  • PostgreSQL 技术日报 (6月8日)|索引预取迭代,AI 安全功能上新
  • 从Mathtype到BibTeX:让你的IEEE LaTeX写作效率翻倍的几个隐藏技巧
  • pac4j-jwt 身份验证绕过漏洞分析
  • 上市公司空气流通系数(2000-2025)