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
Argomenti consigliati
Post di blog: Protezione di BitLocker da attacchi ad accesso sporadico (e altre minacce)
White paper: A Tour Beyond BIOS with the UEFI TPM2 Support 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 avanzati alla memoria, la mitigazione della sicurezza BIOS del sistema esistente MemoryOverwriteRequestControl è stata migliorata per supportare il blocco per difendersi dalle nuove minacce. Il modello di minaccia viene espanso per includere il kernel del sistema operativo host come antagonista, pertanto i servizi DI runtime ACPI e UEFI in esecuzione a livello di privilegio del kernel non sono attendibili. Analogamente alle implementazioni di avvio protetto, 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 nei sistemi con moduli della piattaforma trusted. La revisione 2 aggiunge una nuova funzionalità, sblocco, per attenuare i problemi di prestazioni di avvio, in particolare 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 di reimpostazione della piattaforma del gruppo di lavoro del client PC, versione 1.10 (download PDF), è consigliabile rimuovere questo metodo _DSM dalle implementazioni del BIOS moderne.
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 1 corrispondente 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 ACPI _PTS come implementazione del rilevamento automatico MOR dell'arresto pulito (come descritto nella sezione 2.3 della specifica di mitigazione degli attacchi di reimpostazione della piattaforma del gruppo di lavoro del client PC, versione 1.10 (download PDF)).
Questo ACPI _PTS'implementazione del rilevamento automatico mor è privo di problemi di sicurezza e non deve essere usato.
MemoryOverwriteRequestControlLock
IL BIOS contenente la mitigazione migliorata crea questa variabile UEFI durante l'avvio anticipato:
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 per la prima volta passando un valore diverso da zero valido in Dati, la modalità di accesso per e MemoryOverwriteRequestControlLock
MemoryOverwriteRequestControl
viene modificata in sola lettura, a indicare 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 un altro valore in SetVariable, la chiamata ha esito negativo con stato EFI_INVALID_PARAMETER. Per generare tale chiave, usare un'origine di entropia di alta qualità, ad esempio trusted platform module o generatore di numeri casuali hardware.
Dopo aver impostato una chiave, sia il chiamante che 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 a tempo costante. Se entrambe le chiavi sono presenti e corrispondono, le variabili tornano a uno stato sbloccato. Dopo questo primo tentativo o se non viene registrata alcuna chiave, i successivi tentativi di impostare questa variabile hanno esito negativo 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 di MemoryOverwriteRequestControl
impostando 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.
La chiamata a GetVariable per MemoryOverwriteRequestControlLock
restituisce 0x0, 0x1 o 0x2 per indicare lo sblocco, il blocco senza chiave o il blocco con stati della chiave.
L'impostazione MemoryOverwriteRequestControlLock
non esegue il commit in flash (modifica solo lo stato di blocco interno). Il recupero della variabile restituisce lo stato interno e non espone mai la chiave.
Esempio di utilizzo da parte del 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
SetVariable flow
Flusso di stato sbloccato per SetVariable
Flusso di stato bloccato per SetVariable
Flow 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 ueFI TPM2 in EDKII
Proteggere le credenziali di dominio derivate con Credential Guard