共用方式為


安全 MOR 實作

摘要

  • MorLock 的行為,修訂 2

上次更新

  • 2020 年 8 月

適用於

  • Windows 10

  • 想要支援 Windows 10 Credential Guard 功能的 OEM 和 BIOS 廠商。

官方規格

概觀

本主題描述 UEFI 變數的行為和使用方式 MemoryOverwriteRequestControlLock ,修訂 2。

為了防止進階記憶體攻擊,已改善現有的系統 BIOS 安全性風險降低 MemoryOverwriteRequestControl ,以支援鎖定以防止新的威脅。 威脅模型會擴充為包含主機 OS 核心作為敵人,因此不信任在核心許可權層級執行的 ACPI 和 UEFI 運行時間服務。 類似於安全開機實作,MorLock 應該在主機 OS 核心無法竄改的特殊許可權韌體執行內容中實作(例如,系統管理模式、TrustZone、BMC 等等)。 介面是以 UEFI 變數服務為基礎,如 UEFI 規格 2.5 第 7.2 節 7.2 所述,名為「變數服務」。

此防護功能稱為 MorLock,必須在所有新的系統上實作,而且不僅限於具有受信任平臺模組的系統。 修訂 2 新增了新功能、 解除鎖定,以減輕開機效能考慮,特別是在大型記憶體系統上。

關於設定 MOR 位狀態的 ACPI _DSM控制方法(如計算機用戶端工作組平臺重設攻擊風險降低規格第 1.10 版第 6 節中所述,我們建議您從新式 BIOS 實作中移除此_DSM方法。

不過,如果 BIOS 實作這個_DSM方法,就必須遵守 MorLock 的狀態。 如果 MorLock 已鎖定且沒有索引鍵,這個_DSM方法必須無法變更 MOR,並傳回對應至「一般失敗」的 1 值。 未定義 ACPI 機制來解除鎖定 MorLock 修訂 2。

請注意,自 Windows 7 以來,Windows 尚未直接叫用這個_DSM方法,並認為它已被取代。 當 Windows 叫用 ACPI _PTS 做為自動偵測清除關機的 MOR 自動偵測時,某些 BIOS 間接 叫用這個_DSM方法(如計算機用戶端工作群組平臺重設攻擊風險降低規格第 2.3 節中所述,版本 1.10 (PDF 下載) 中所述

此 ACPI _PTS MOR 自動偵測實作的安全性不足,不應使用。

MemoryOverwriteRequestControlLock

包含改良風險降低的 BIOS 會在早期開機期間建立此 UEFI 變數:

VendorGuid: {BB983CCF-151D-40E1-A07B-4A17BE168292}

名稱MemoryOverwriteRequestControlLock

屬性: NV+BS+RT

Data 參數中的 GetVariable 值:0x0(已解除鎖定):0x1(沒有密鑰鎖定)、0x2(使用密鑰鎖定)

Data 參數中的 SetVariable 值:0x0(已解除鎖定):0x1 (鎖定)

使用 SetVariable 鎖定

在每次開機時,BIOS 都應該初始化為0x00的單一位元組值(表示已解除鎖定),再於MemoryOverwriteRequestControlLock開機裝置選取 (BDS) 階段 (DRIVER###,SYSPREP#,BOOT##, *RECOVERY*, ...)。 針對 MemoryOverwriteRequestControlLock (和 MemoryOverwriteRequestControl),BIOS 應防止刪除變數和屬性,必須釘選到 NV+BS+RT。

當 先在Data中傳遞有效的非零值來呼叫SetVariableMemoryOverwriteRequestControlLock,和 MemoryOverwriteRequestControl 的存取模式MemoryOverwriteRequestControlLock會變更為唯讀,表示它們已鎖定。

修訂 1 實作只接受 單一位元組的 0x00 或 0x01 MemoryOverwriteRequestControlLock

修訂 2 會另外接受代表共用秘密金鑰的 8 位元組值。 如果在 SetVariable指定任何其他值,呼叫會失敗,狀態為EFI_INVALID_PARAMETER。 若要產生該金鑰,請使用高品質的 entropy 來源,例如信賴平臺模組或硬體隨機數產生器。

設定金鑰之後,呼叫端和韌體都應該將此金鑰的復本儲存在機密性保護的位置,例如 IA32/X64 上的 SMRAM 或具有受保護記憶體的服務處理器。

取得系統狀態

在修訂 2 中,當和 MemoryOverwriteRequestControl 變數遭到鎖定時MemoryOverwriteRequestControlLock,會先使用常數時間演算法來檢查 SetVariable (針對這些變數)的叫用。 如果兩個索引鍵都存在且相符,變數就會轉換回未鎖定的狀態。 在第一次嘗試或未登錄任何密鑰之後,後續嘗試設定此變數會失敗,並EFI_ACCESS_DENIED以防止暴力密碼破解攻擊。 在此情況下,系統重新啟動應該是解除鎖定變數的唯一方法。

操作系統會藉由呼叫 GetVariable 來偵測MemoryOverwriteRequestControlLock是否存在及其狀態。 系統接著可以將 值設定MemoryOverwriteRequestControlLock為 0x1,以鎖定 的目前值MemoryOverwriteRequestControl。 或者,它可以指定金鑰,以在從記憶體安全地清除秘密數據之後,在未來啟用解除鎖定。

呼叫 GetVariableMemoryOverwriteRequestControlLock 傳回0x0、0x1或0x2,表示未鎖定、未鎖定密鑰或鎖定金鑰狀態。

設定 MemoryOverwriteRequestControlLock 不會認可快閃 (只要變更內部鎖定狀態)。 取得變數會傳回內部狀態,且永遠不會公開密鑰。

作業系統的範例使用方式:

if (gSecretsInMemory)
{
    char data = 0x11;
    SetVariable(MemoryOverwriteRequestControl, sizeof(data), &data);
}

// check presence
status = GetVariable(MemoryOverwriteRequestControlLock, &value);  

if (SUCCESS(status))
{
    // first attempt to lock and establish a key
    // note both MOR and MorLock are locked if successful

    GetRNG(8, keyPtr);
    status = SetVariable(MemoryOverwriteRequestControlLock, 8, keyPtr);

    if (status != EFI_SUCCESS)
    {
        // fallback to revision 1 behavior
        char data = 0x01;
        status = SetVariable(MemoryOverwriteRequestControlLock, 1, &data);
        if (status != EFI_SUCCESS) { // log error, warn user }
    }
}
else
{
    // warn user about potentially unsafe system
}

// put secrets in memory

// … time passes …

// remove secrets from memory, flush caches

SetVariable(MemoryOverwriteRequestControlLock, 8, keyPtr);

MorLock 實作流程

這些流程圖會顯示實作的預期行為:

初始化

morlock 初始化。

SetVariable 流程

morlock 程式設計流程。

SetVariable 的解除鎖定狀態流程

morlock 解除鎖定的流程。

SetVariable 的鎖定狀態流程

morlock 鎖定的流程。

GetVariable 的流程

morlock getvariable。

另請參閱

適用於SoC平臺上所有 Windows 版本的 UEFI 需求

電腦用戶端工作組平臺重設攻擊風險降低規格,版本 1.10 (PDF 下載)

保護 BitLocker 免受冷攻擊(和其他威脅)

在EDKII中支援 UEFI TPM2 的 BIOS 以外的教學課程

使用 Credential Guard 保護衍生的網域認證

UEFI 規格