Share via


安全 MOR 實作

摘要

  • MorLock 的行為,修訂 2

上次更新

  • 2020 年 8 月

適用於

  • Windows 10

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

官方規格

概觀

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

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

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

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

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

請注意,自 Windows 7 起,Windows 尚未直接叫用此_DSM方法,並將它視為已被取代。 某些 BIOS 會在 Windows 叫用 ACPI _PTS作為清除關機自動偵測的 MOR 自動偵測 (實作時 ,間接 叫用這個_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 應初始化 MemoryOverwriteRequestControlLock 為單一位元組值 0x00 (,) 指出 開機裝置選取 (BDS) 階段 (DRIVER##,SYSPREP#,BOOT#####,*RECOVERY*,...) 。 針對 MemoryOverwriteRequestControlLock (和 MemoryOverwriteRequestControl) ,BIOS 應防止刪除變數和屬性必須釘選到 NV+BS+RT。

Data中傳遞有效的非零值來呼叫SetVariableMemoryOverwriteRequestControlLock 時,和 MemoryOverwriteRequestControlMemoryOverwriteRequestControlLock 存取模式會變更為唯讀,表示已鎖定。

修訂 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 規格