共用方式為


安全 MOR 實作

總結

  • MorLock 的行為,修訂版 2

上次更新

  • 2020 年 8 月

適用對象

  • Windows 10

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

官方規格

概觀

本主題說明 UEFI 變數修訂 2 的 MemoryOverwriteRequestControlLock 行為和使用方式。

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

這種緩解措施稱為 MorLock,必須在所有新系統上實施,而不僅限於具有可信任平台模組的系統。 修訂版 2 新增了一項新功能 unlock,以減輕開機效能問題,尤其是在大型記憶體系統上。

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

不過,如果 BIOS 實作此_DSM方法,則必須遵循 MorLock 的狀態。 如果 MorLock 已鎖定,無論有沒有金鑰,此_DSM方法都必須無法變更 MOR,並傳回對應於「一般失敗」的值 1。 未定義 ACPI 機制來開鎖 MorLock 修訂版 2。

請注意,自 Windows 7 以來,Windows 沒有直接叫用此_DSM方法,並認為它已被取代。 當 Windows 叫用 ACPI _PTS 作為 MOR 自動偵測全新關機的實作時,某些 BIOS 會間接 叫用此_DSM方法 (如 電腦用戶端工作群組平臺重設攻擊風險降低規格 1.10 版的第 2.3 節所述) (PDF 下載) 。

此 ACPI _PTS MOR 自動偵測實作有安全性缺陷,不應使用。

記憶體覆寫請求控制鎖 (MemoryOverwriteRequestControlLock)

包含改進的緩解措施的 BIOS 會在早期啟動期間建立此 UEFI 變數:

供應商指南:{BB983CCF-151D-40E1-A07B-4A17BE168292}

名稱MemoryOverwriteRequestControlLock

屬性: NV+BS+RT

GetVariable 資料參數中的值:0x0(已解鎖);0x1(無鑰匙上鎖);0x2(用鑰匙鎖定)

資料參數中的SetVariable值:0x0(已解鎖);0x1(鎖定)

使用 SetVariable 鎖定

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

當第一次呼叫 SetVariable for MemoryOverwriteRequestControlLock 時,會在 Data 中傳遞有效的非零值,兩者的MemoryOverwriteRequestControlLockMemoryOverwriteRequestControl存取模式都會變更為唯讀,指出它們已鎖定。

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

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

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

取得系統狀態

在修訂版 2 中,當 MemoryOverwriteRequestControlLockMemoryOverwriteRequestControl 變數鎖定時,會先使用常數時間演算法針對已註冊的索引鍵,檢查 SetVariable(針對這些變數)的呼叫。 如果兩個金鑰都存在且相符,變數會轉換回解除鎖定狀態。 在第一次嘗試之後,或如果未註冊金鑰,則後續嘗試設定此變數會失敗,並返回EFI_ACCESS_DENIED以防止暴力破解攻擊。 在這種情況下,系統重新啟動應該是解鎖變數的唯一方法。

作業系統會呼叫 GetVariable 來偵測 的MemoryOverwriteRequestControlLock存在及其狀態。 然後,系統可以透過將 MemoryOverwriteRequestControlLock 值設為 0x1 來鎖定 MemoryOverwriteRequestControl 的當前值。 或者,它可以指定一個金鑰,以便在從記憶體中安全清除秘密資料後啟用未來解鎖。

呼叫 GetVariable 會傳回 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 流程

莫洛克編程流程。

SetVariable 的解除鎖定狀態流程

莫洛克解鎖了工作流。

SetVariable 的鎖定狀態流程

morlock 鎖定了流。

GetVariable 的流程

morlock getvariable。

另請參閱

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

PC 用戶端工作群組平台重設攻擊緩解規格,1.10 版 (PDF 下載)

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

探討在 EDKII 中支援 UEFI TPM2 的 BIOS 擴展功能

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

UEFI 規格