如何创建 UEFI 只读变量?

Posted

技术标签:

【中文标题】如何创建 UEFI 只读变量?【英文标题】:How to create a UEFI read only variable? 【发布时间】:2016-01-11 19:40:43 【问题描述】:

在引导 GRUB2 的 EFI 系统上,我想创建一个只读 EFI 变量。这可能吗?

谢谢, 垫子

【问题讨论】:

这是两个独立的问题,请缩减到一次只问一件事(另外一个单独发布)。 【参考方案1】:

根据Uefi Specification 2.7,通过不提供 EFI_VARIABLE_NON_VOLATILE 属性,可以直接在 ExitBootServices() 后创建只读 UEFI 变量。

参见章节'8.2 变量服务'SetVariable() 描述:

一旦执行 ExitBootServices(),只有具有 EFI_VARIABLE_RUNTIME_ACCESS 和 EFI_VARIABLE_NON_VOLATILE 设置可以 用 SetVariable() 设置。执行 ExitBootServices() 后,具有运行时访问权限但不是非易失性的变量是只读数据变量。

另见“8.2 变量服务”GetVariable() 相关定义:

//*******************************************************
// Variable Attributes
//*******************************************************
#define EFI_VARIABLE_NON_VOLATILE 0x00000001

【讨论】:

【参考方案2】:

根据UEFI Specification 2.5,没有直接创建只读 UEFI 变量的方法。

使用具有属性的变量可以获得预期的结果:EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 和 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS。

根据 UEFI Spec 2.5 的第 7.2 章(SetVariable 描述部分):

(...) 尝试删除使用 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 或 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 属性为其 规定的 AuthInfo 验证失败,或者当使用零的 DataSize 调用时将失败并显示 EFI_SECURITY_VIOLATION 状态。

根据第 7.2.1 章(使用 EFI_VARIABLE_AUTHENTICATION_2 描述符),在描述变量更新过程的长过程之后:

只有当所有这些检查都通过时,驱动程序才会更新变量的值。如果有任何检查 失败,固件必须返回 EFI_SECURITY_VIOLATION。

最后,没有身份验证就无法删除或修改使用 *_WRITE_ACCESS 属性创建的变量。 GetVariable 将返回正确的值,在属性中指示返回的变量在更新或删除之前需要身份验证。有关详细信息,请阅读 UEFI Spec 2.5 第 7.2.1 和 7.2.2 章。

【讨论】:

Authenticated 属性与只读变量无关。 Authenticated Variables 是可写的,你只需要用正确的密钥对你的有效载荷进行签名。只读属性可以通过不提供 EFI_VARIABLE_NON_VOLATILE 属性来实现,如下面的@Pshemy108 所回答。 同意,我的回答是 3 年前提供的,可能不符合最近的规范。我必须尽快重新审视它。随意编辑这个答案。

以上是关于如何创建 UEFI 只读变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何开启vmware uefi模式

如何使变量/对象在 Javascript 中只读? [复制]

如何更改只读权限以设置 MySQL 服务器系统变量的新值

如何制作uefi启动u盘安装系统

如何在VMWare Workstation启用UEFI来支持win10 9901

如何在 PHP 中创建最终变量?