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 der MemoryOverwriteRequestControlLock UEFI-Variablen, Revision 2, beschrieben.

Um erweiterte Speicherangriffe zu verhindern, wurde die vorhandene System-BIOS-Sicherheitsminderung MemoryOverwriteRequestControl verbessert, um sperren zu unterstützen, um neue Bedrohungen zu schützen. Das Bedrohungsmodell wird erweitert, um den Hostbetriebssystemkern als Kontrahenten einzubeziehen, sodass ACPI und UEFI Runtime Services, die auf Kernelberechtigungsebene ausgeführt werden, nicht vertrauenswürdig sind. Ähnlich wie bei Secure Boot-Implementierungen sollte MorLock in einem privilegierten Firmwareausführungskontext implementiert werden, der nicht vom Hostbetriebssystemkern 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 namens MorLock muss auf allen neuen Systemen implementiert werden und muss nicht nur auf Systeme mit Trusted Platform Modules beschränkt werden. Revision 2 fügt eine neue Funktion hinzu, entsperren, um Probleme bei der Startleistung zu verringern, insbesondere bei großen Speichersystemen.

In Bezug auf die ACPI-_DSM-Steuerungsmethode zum Festlegen des MOR-Bitzustands (wie in Abschnitt 6 der Spezifikation zum Zurücksetzen von Angriffen auf PC-Arbeitsgruppenplattform, Version 1.10 (PDF-Download) beschrieben), wird empfohlen, diese _DSM Methode aus modernen BIOS-Implementierungen zu entfernen.

Wenn ein BIOS diese _DSM Methode implementiert, muss es jedoch den Zustand von MorLock berücksichtigen. Wenn morLock mit oder ohne Schlüssel gesperrt ist, muss diese _DSM-Methode MOR nicht ändern und einen Wert von 1 zurückgeben, der "Allgemeiner Fehler" entspricht. Es ist kein ACPI-Mechanismus zum Entsperren von MorLock Revision 2 definiert.

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

Diese ACPI-_PTS Implementierung der automatischen MOR-Erkennung ist sicherheitsdefekt und sollte NICHT verwendet werden.

MemoryOverwriteRequestControlLock

DAS BIOS, das die verbesserte Entschärfung enthält, erstellt diese UEFI-Variable während des frühen Startvorgangs:

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 muss das BIOS vor der BDS-Phase (Boot Device Selection, BDS) auf einen Einzelbytewert von 0x00 (entsperrt) initialisieren MemoryOverwriteRequestControlLock (DRIVER#####, SYSPREP###, BOOT####, *RECOVERY*, ...). Für MemoryOverwriteRequestControlLock (und MemoryOverwriteRequestControl) verhindert das BIOS das Löschen der Variablen, und attribute müssen an NV+BS+RT angeheftet werden.

Wenn SetVariable für MemoryOverwriteRequestControlLock zuerst aufgerufen wird, indem ein gültiger Wert ungleich 0 in Data übergeben wird, wird der Zugriffsmodus für beide MemoryOverwriteRequestControlLockMemoryOverwriteRequestControl und in schreibgeschützt geändert, was angibt, dass sie gesperrt sind.

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

Revision 2 akzeptiert zusätzlich einen Wert von 8 Byte, der einen gemeinsam genutzten geheimen Schlüssel darstellt. Wenn ein anderer Wert in SetVariable angegeben wird, schlägt der Aufruf mit status EFI_INVALID_PARAMETER fehl. Verwenden Sie zum Generieren dieses Schlüssels eine hochwertige Entropiequelle wie das Trusted Platform-Modul oder den Hardware-Zufallszahlengenerator.

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

Abrufen des Systemzustands

Wenn in Revision 2 die MemoryOverwriteRequestControlLock Variablen und MemoryOverwriteRequestControl gesperrt sind, werden Aufrufe von SetVariable (für diese Variablen) zunächst mithilfe eines Konstantzeitalgorithmus mit dem registrierten Schlüssel überprüft. Wenn beide Schlüssel vorhanden und übereinstimmen, wechseln die Variablen zurück in einen entsperrten Zustand. Nach diesem ersten Versuch oder wenn kein Schlüssel registriert wurde, 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 von MemoryOverwriteRequestControlLock und seinen Zustand, indem GetVariable aufgerufen wird. Das System kann dann den aktuellen Wert von sperren, MemoryOverwriteRequestControl 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 Arbeitsspeicher gelöscht wurden.

Der Aufruf von GetVariable für MemoryOverwriteRequestControlLock gibt 0x0, 0x1 oder 0x2 zurück, um entsperrt, ohne Schlüssel oder mit Schlüsselzuständen gesperrt anzugeben.

Durch die Einstellung MemoryOverwriteRequestControlLock wird kein Commit zum Flashen ausgeführt (nur der interne Sperrzustand wird geändert). 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-Implementierungsflow

Diese Flussdiagramme zeigen das erwartete Verhalten Ihrer Implementierung:

Initialisierung

Morlock-Initialisierung.

SetVariabler Flow

Morlock-Programmierflow.

Unentschlossener Zustandsfluss für SetVariable

morlock unlocked flow.

Gesperrter Zustandsfluss für SetVariable

Morlock-Gesperrter Flow.

Flow 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 über das BIOS hinaus mit der UEFI TPM2-Unterstützung in EDKII

Schützen abgeleiteter Domänenanmeldeinformationen mit Credential Guard

UEFI-Spezifikationen