安全 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
時,和 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
。 或者,它可以指定金鑰,以在從記憶體中安全地清除秘密資料之後,在未來啟用解除鎖定。
呼叫 GetVariable 以 MemoryOverwriteRequestControlLock
傳回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 實作流程
這些流程圖會顯示實作的預期行為:
初始化
SetVariable 流程
SetVariable 的解除鎖定狀態流程
SetVariable 的鎖定狀態流程
GetVariable 的流程
另請參閱
適用于 SoC 平臺上所有 Windows 版本的 UEFI 需求
電腦用戶端工作組平臺重設攻擊風險降低規格,版本 1.10 (PDF 下載)
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應