Implementazione sicura di MOR
Riepilogo
- Comportamento di MorLock, revisione 2
Ultimo aggiornamento
- Agosto 2020
Si applica a
Windows 10
Oem e fornitori di BIOS che vogliono supportare la funzionalità Credential Guard di Windows 10.
Specifiche ufficiali
Letture consigliate
Post di blog: Protezione di BitLocker da attacchi ad accesso sporadico (e altre minacce)
White paper: un tour oltre il BIOS con il supporto TPM2 UEFI in EDKII
Proteggere le credenziali di dominio derivate con Credential Guard
Panoramica
Questo argomento descrive il comportamento e l'utilizzo per la MemoryOverwriteRequestControlLock
variabile UEFI, revisione 2.
Per evitare attacchi di memoria avanzati, la mitigazione della sicurezza BIOS del sistema esistente MemoryOverwriteRequestControl è migliorata per supportare il blocco per difendere contro le nuove minacce. Il modello di minaccia viene espanso per includere il kernel del sistema operativo host come avversario, pertanto i servizi di runtime ACPI e UEFI in esecuzione a livello di privilegi kernel non sono attendibili. Analogamente alle implementazioni di avvio sicuro, MorLock deve essere implementato in un contesto di esecuzione del firmware con privilegi che non può essere manomesso dal kernel del sistema operativo host, ad esempio modalità di gestione del sistema, TrustZone, BMC e così via. L'interfaccia è basata su servizi variabili UEFI, descritti nella specifica UEFI versione 2.5, sezione 7.2 denominata "Servizi variabili".
Questa mitigazione, denominata MorLock, deve essere implementata in tutti i nuovi sistemi e non solo per i sistemi con moduli di piattaforma attendibili. La revisione 2 aggiunge una nuova funzionalità, sblocco, per attenuare i problemi di prestazioni di avvio, soprattutto nei sistemi di memoria di grandi dimensioni.
Per quanto riguarda il metodo di controllo ACPI _DSM per impostare lo stato di bit MOR (come descritto nella sezione 6 della specifica di mitigazione degli attacchi della piattaforma di ripristino della piattaforma di lavoro client PC, versione 1.10 (download PDF), è consigliabile rimuovere questo metodo _DSM dalle implementazioni moderne del BIOS.
Tuttavia, se un BIOS implementa questo metodo _DSM, deve rispettare lo stato di MorLock. Se MorLock è bloccato, con o senza una chiave, questo metodo _DSM deve non modificare MOR e restituire un valore pari a "Errore generale". Non è definito alcun meccanismo ACPI per sbloccare MorLock revisione 2.
Si noti che Windows non ha richiamato direttamente questo metodo _DSM da Windows 7 e lo considera deprecato. Alcuni BIOS richiamano indirettamente questo metodo _DSM quando Windows richiama i _PTS ACPI come implementazione del rilevamento automatico MOR di Arresto pulito (come descritto nella sezione 2.3 della specifica di mitigazione degli attacchi di reimpostazione degli attacchi del gruppo di lavoro client PC, versione 1.10 (download PDF).
Questa _PTS'implementazione del rilevamento automatico MOR è scarsa e non deve essere usata.
MemoryOverwriteRequestControlLock
IL BIOS contenente la mitigazione migliorata crea questa variabile UEFI durante l'avvio iniziale:
VendorGuid:{BB983CCF-151D-40E1-A07B-4A17BE168292}
Nome:MemoryOverwriteRequestControlLock
Attributi: NV+BS+RT
Valore GetVariable nel parametro Data : 0x0 (sbloccato); 0x1 (bloccato senza chiave); 0x2 (bloccato con chiave)
Valore SetVariable nel parametro Data : 0x0 (sbloccato); 0x1 (bloccato)
Blocco con SetVariable
In ogni avvio, IL BIOS verrà inizializzato MemoryOverwriteRequestControlLock
in un valore a byte singolo di 0x00 (che indica lo sblocco) prima della fase di selezione del dispositivo di avvio (BDS) (DRIVER#, SYSPREP#, BOOT#, *RECOVERY*, ...). Per MemoryOverwriteRequestControlLock
(e MemoryOverwriteRequestControl
), IL BIOS impedisce l'eliminazione della variabile e degli attributi deve essere aggiunto a NV+BS+RT.
Quando SetVariable per MemoryOverwriteRequestControlLock
viene chiamato passando un valore diverso da zero valido in Dati, la modalità di accesso per entrambi MemoryOverwriteRequestControlLock
e MemoryOverwriteRequestControl
viene modificata in sola lettura, indicando che sono bloccati.
Le implementazioni della revisione 1 accettano solo un singolo byte di 0x00 o 0x01 per MemoryOverwriteRequestControlLock
.
La revisione 2 accetta inoltre un valore a 8 byte che rappresenta una chiave privata condivisa. Se viene specificato qualsiasi altro valore in SetVariable, la chiamata ha esito negativo con lo stato EFI_INVALID_PARAMETER. Per generare tale chiave, usare un'origine di entropia di alta qualità, ad esempio il generatore di numeri casuali della piattaforma attendibile o hardware.
Dopo aver impostato una chiave, il chiamante e il firmware devono salvare copie di questa chiave in una posizione protetta da riservatezza, ad esempio SMRAM in IA32/X64 o un processore di servizi con archiviazione protetta.
Recupero dello stato del sistema
Nella revisione 2, quando le variabili e MemoryOverwriteRequestControl
sono bloccate, le MemoryOverwriteRequestControlLock
chiamate di SetVariable (per tali variabili) vengono prima controllate sulla chiave registrata usando un algoritmo di tempo costante. Se entrambe le chiavi sono presenti e corrispondono, le variabili passano nuovamente a uno stato sbloccato. Dopo questo primo tentativo o se non viene registrata alcuna chiave, i tentativi successivi di impostare questa variabile non riescono con EFI_ACCESS_DENIED per evitare attacchi di forza bruta. In tal caso, il riavvio del sistema sarà l'unico modo per sbloccare le variabili.
Il sistema operativo rileva la presenza di MemoryOverwriteRequestControlLock
e il relativo stato chiamando GetVariable. Il sistema può quindi bloccare il valore corrente impostando MemoryOverwriteRequestControl
il MemoryOverwriteRequestControlLock
valore su 0x1. In alternativa, può specificare una chiave per abilitare lo sblocco in futuro dopo che i dati segreti sono stati eliminati in modo sicuro dalla memoria.
Chiamata di GetVariable per MemoryOverwriteRequestControlLock
restituisce 0x0, 0x1 o 0x2 per indicare lo sblocco, il blocco senza chiave o lo stato di blocco con gli stati della chiave.
L'impostazione MemoryOverwriteRequestControlLock
non esegue il commit su flash (modifica solo lo stato di blocco interno). Ottenere la variabile restituisce lo stato interno e non espone mai la chiave.
Esempio di utilizzo dal sistema operativo:
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);
Flusso di implementazione di MorLock
Questi diagrammi di flusso mostrano il comportamento previsto dell'implementazione:
Inizializzazione
Flusso setVariable
Flusso di stato sbloccato per SetVariable
Flusso di stato bloccato per SetVariable
Flusso per GetVariable
Vedi anche
Requisiti UEFI applicabili a tutte le edizioni di Windows nelle piattaforme SoC
Protezione di BitLocker da attacchi ad accesso sporadico (e altre minacce)
Tour Beyond BIOS con il supporto TPM2 UEFI in EDKII
Proteggere le credenziali di dominio derivate con Credential Guard