Freigeben über


Sichere MOR-Implementierung

Zusammenfassung

  • Verhalten von MorLock, Revision 2

Letzte Aktualisierung

  • August 2020

Gilt für:

  • Windows 10

  • OEMs und BIOS-Anbieter, die das Credential Guard-Feature von Windows 10 unterstützen möchten.

Offizielle Spezifikationen

Übersicht

In diesem Thema werden das Verhalten und die Verwendung für die MemoryOverwriteRequestControlLock UEFI-Variable, Revision 2, beschrieben.

Um erweiterte Speicherangriffe zu verhindern, wird die vorhandene BIOS-Sicherheitsminderung MemoryOverwriteRequestControl verbessert, um die Sperrung zur Verteidigung gegen neue Bedrohungen zu unterstützen. Das Bedrohungsmodell wird erweitert, um den Hostbetriebssystem-Kernel als Gegner einzuschließen, daher sind ACPI und UEFI-Runtime-Dienste, die auf Kernelberechtigungsebene ausgeführt werden, nicht vertrauenswürdig. Ähnlich wie bei Implementierungen für den sicheren Start sollte MorLock in einem privilegierten Firmwareausführungskontext implementiert werden, der nicht vom Hostbetriebssystem-Kernel manipuliert werden kann (z. B. Systemverwaltungsmodus, TrustZone, BMC usw.). Die Schnittstelle basiert auf UEFI-Variablendiensten, die in der UEFI-Spezifikation, Version 2.5, Abschnitt 7.2 mit dem Namen "Variable Services" beschrieben werden.

Diese Entschärfung, die als MorLock bezeichnet wird, muss auf allen neuen Systemen implementiert werden und nicht nur auf Systeme mit Trusted Platform Modules beschränkt werden. Revision 2 fügt eine neue Funktion hinzu, die entsperrt wird, um Probleme mit der Startleistung zu vermeiden, insbesondere bei großen Speichersystemen.

Bezüglich der ACPI-_DSM Steuerungsmethode zum Festlegen des MOR-Bitzustands (wie in Abschnitt 6 von PC Client Work Group Platform Reset Attack Mitigation Specification, Version 1.10 (PDF-Download)) beschrieben, empfehlen wir, diese _DSM Methode aus modernen BIOS-Implementierungen zu entfernen.

Wenn jedoch ein BIOS diese _DSM-Methode implementiert, muss es den Zustand von MorLock respektieren. Wenn das MorLock-Objekt mit oder ohne Schlüssel gesperrt ist, muss diese _DSM Methode MOR nicht ändern und einen Wert von 1 zurückgeben, der "General Failure" entspricht. Es ist kein ACPI-Mechanismus definiert, um MorLock Revision 2 zu entsperren.

Beachten Sie, dass Windows diese _DSM Methode seit Windows 7 nicht direkt aufgerufen hat und sie als veraltet betrachtet. Einige BIOS ruft diese _DSM Methode indirekt auf, wenn Windows ACPI-_PTS als Implementierung der MOR Auto Detection of Clean Shutdown aufruft (siehe Abschnitt 2.3 der PC Client Work Group Platform Reset Attack Mitigation Specification, Version 1.10 (PDF-Download)).

Diese ACPI-_PTS Implementierung der MOR-Autoerkennung ist sicherheitsverhindert und sollte NICHT verwendet werden.

MemoryOverwriteRequestControlLock

BIOS mit der verbesserten Entschärfung erstellt diese UEFI-Variable während des frühen Starts:

VendorGuid: {BB983CCF-151D-40E1-A07B-4A17BE168292}

Name: MemoryOverwriteRequestControlLock

Attribute: NV+BS+RT

GetVariable-Wert im Datenparameter : 0x0 (entsperrt); 0x1 (ohne Schlüssel gesperrt); 0x2 (mit Schlüssel gesperrt)

SetVariable-Wert im Datenparameter : 0x0 (entsperrt); 0x1 (gesperrt)

Sperren mit SetVariable

Bei jedem Start initialisiert MemoryOverwriteRequestControlLock DAS BIOS einen Einzelbytewert von 0x00 (die entsperrt sind) vor der BDS-Phase (DRIVER####, SYSPREP###, BOOT####, BOOT###, *RECOVERY*, ...). Für MemoryOverwriteRequestControlLock (und MemoryOverwriteRequestControl) verhindert BIOS das Löschen der Variablen und Attribute muss an NV+BS+RT angeheftet werden.

Wenn "SetVariable " MemoryOverwriteRequestControlLock zum ersten Mal aufgerufen wird, indem ein gültiger Wert ungleich Null in "Data" übergeben wird, wird der Zugriffsmodus für beide und MemoryOverwriteRequestControlLock MemoryOverwriteRequestControl in schreibgeschützt geändert, was angibt, dass sie gesperrt sind.

Revision 1-Implementierungen akzeptieren nur ein einzelnes Byte von 0x00 oder 0x01 für MemoryOverwriteRequestControlLock.

Revision 2 akzeptiert zusätzlich einen 8-Byte-Wert, der einen freigegebenen geheimen Schlüssel darstellt. Wenn ein anderer Wert in SetVariable angegeben wird, schlägt der Aufruf mit dem Status EFI_INVALID_PARAMETER fehl. Um diesen Schlüssel zu generieren, verwenden Sie eine qualitativ hochwertige Entropiequelle, z. B. das Trusted Platform Module oder den Hardware-Zufallszahlengenerator.

Nach dem Festlegen eines Schlüssels sollten sowohl der Aufrufer als auch die Firmware Kopien dieses Schlüssels an einem vertraulich geschützten Speicherort speichern, z. B. SMRAM auf IA32/X64 oder einem Dienstprozessor mit geschütztem Speicher.

Abrufen des Systemzustands

Wenn die MemoryOverwriteRequestControlLock Variablen in MemoryOverwriteRequestControl Revision 2 gesperrt sind, werden Aufrufe von SetVariable (für diese Variablen) zuerst anhand eines Konstantenzeitalgorithmus anhand des registrierten Schlüssels überprüft. Wenn beide Schlüssel vorhanden sind und übereinstimmen, wechseln die Variablen zurück zu einem nicht gesperrten Zustand. Nach diesem ersten Versuch oder wenn kein Schlüssel registriert ist, schlagen nachfolgende Versuche, diese Variable festzulegen, mit EFI_ACCESS_DENIED fehl, um Brute-Force-Angriffe zu verhindern. In diesem Fall ist der Systemneustart die einzige Möglichkeit, die Variablen zu entsperren.

Das Betriebssystem erkennt das Vorhandensein und MemoryOverwriteRequestControlLock den Zustand durch Aufrufen von GetVariable. Das System kann dann den aktuellen Wert MemoryOverwriteRequestControl sperren, indem der MemoryOverwriteRequestControlLock Wert auf 0x1 festgelegt wird. Alternativ kann ein Schlüssel angegeben werden, um die Entsperrung in Zukunft zu aktivieren, nachdem geheime Daten sicher aus dem Speicher gelöscht wurden.

Aufrufen von "GetVariable " für MemoryOverwriteRequestControlLock Rückgaben 0x0, 0x1 oder 0x2, um entsperrt, gesperrt ohne Schlüssel oder mit Schlüsselzuständen anzugeben.

Die Einstellung MemoryOverwriteRequestControlLock wird nicht auf Flash festgelegt (ändert nur den internen Sperrzustand). Das Abrufen der Variablen gibt den internen Zustand zurück und macht den Schlüssel nie verfügbar.

Beispielverwendung durch das Betriebssystem:

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-Implementierungsfluss

Diese Flussdiagramme zeigen das erwartete Verhalten Ihrer Implementierung:

Initialisierung

Morlockinitialisierung.

SetVariable-Fluss

Morlockprogrammierungsfluss.

Entsperrter Zustandsfluss für SetVariable

Morlock entsperrter Fluss.

Gesperrter Zustandsfluss für SetVariable

Morlock gesperrter Fluss.

Ablauf für GetVariable

morlock getvariable.

Weitere Informationen

UEFI-Anforderungen, die für alle Windows-Editionen auf SoC-Plattformen gelten

PC Client Work Group Platform Reset Attack Mitigation Specification, Version 1.10 (PDF Download)

Schutz von BitLocker vor kalten Angriffen (und anderen Bedrohungen)

Eine Tour jenseits des BIOS mit der UEFI TPM2-Unterstützung in EDKII

Schützen abgeleiteter Domänenanmeldeinformationen mit Credential Guard

UEFI-Spezifikationen