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
Empfohlene Literatur
Blogbeitrag: Schutz von BitLocker vor kalten Angriffen (und anderen Bedrohungen)
Whitepaper: Eine Tour jenseits des BIOS mit der UEFI TPM2-Unterstützung in EDKII
Schützen abgeleiteter Domänenanmeldeinformationen mit Credential Guard
Ü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
SetVariable-Fluss
Entsperrter Zustandsfluss für SetVariable
Gesperrter Zustandsfluss für SetVariable
Ablauf für 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