Condividi tramite


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

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

inizializzazione morlock.

SetVariable flow

flusso di programmazione morlock.

Flusso di stato sbloccato per SetVariable

flusso sbloccato con morlock.

Flusso di stato bloccato per SetVariable

morlock bloccato flusso.

Flow per GetVariable

morlock getvariable.

Vedi anche

Requisiti UEFI applicabili a tutte le edizioni di Windows nelle piattaforme SoC

Specifica di mitigazione degli attacchi per la reimpostazione della piattaforma del gruppo di lavoro client PC versione 1.10 (download PDF)

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

Specifiche UEFI