Implémentation mor sécurisée
Résumé
- Comportement de MorLock, révision 2
Dernière mise à jour
- Août 2020
S’applique à
Windows 10
Fabricants d’OEM et de BIOS qui souhaitent prendre en charge la fonctionnalité Credential Guard de Windows 10.
Spécifications officielles
Lectures recommandées
Billet de blog : Protection de BitLocker contre les attaques à froid (et d’autres menaces)
Livre blanc : Visite guidée au-delà du BIOS avec le support UEFI TPM2 dans EDKII
Protéger les informations d’identification de domaine dérivées avec Credential Guard
Vue d’ensemble
Cette rubrique décrit le comportement et l’utilisation de la MemoryOverwriteRequestControlLock
variable UEFI, révision 2.
Pour éviter les attaques avancées en mémoire, l’atténuation de la sécurité du BIOS du système existant MemoryOverwriteRequestControl est améliorée pour prendre en charge le verrouillage pour se défendre contre les nouvelles menaces. Le modèle de menace est développé pour inclure le noyau du système d’exploitation hôte en tant qu’adversaire. Les services ACPI et UEFI Runtime s’exécutant au niveau des privilèges du noyau ne sont donc pas approuvés. Comme pour les implémentations de démarrage sécurisé, MorLock doit être implémenté dans un contexte d’exécution de microprogramme privilégié qui ne peut pas être falsifié par le noyau du système d’exploitation hôte (par exemple, mode de gestion du système, TrustZone, BMC, etc.). L’interface repose sur les services de variables UEFI, qui sont décrits dans la spécification UEFI version 2.5, section 7.2 nommée « Services variables ».
Cette atténuation, appelée MorLock, doit être implémentée sur tous les nouveaux systèmes et non seulement limitée aux systèmes dotés de modules de plateforme approuvée. La révision 2 ajoute une nouvelle fonctionnalité, déverrouillage, pour atténuer les problèmes de performances de démarrage, en particulier sur les systèmes de mémoire volumineux.
En ce qui concerne la méthode de contrôle _DSM ACPI pour définir l’état du bit MOR (comme décrit dans la section 6 de la spécification d’atténuation des attaques de réinitialisation de la plateforme du groupe de travail PC, version 1.10 (téléchargement PDF)), nous vous recommandons de supprimer cette méthode _DSM des implémentations BIOS modernes.
Toutefois, si un BIOS implémente cette méthode _DSM, il doit respecter l’état de MorLock. Si morLock est verrouillé, avec ou sans clé, cette méthode _DSM ne doit pas changer mor et retourner une valeur de 1 correspondant à « Échec général ». Aucun mécanisme ACPI n’est défini pour déverrouiller MorLock révision 2.
Notez que Windows n’a pas appelé directement cette méthode _DSM depuis Windows 7 et qu’il est déconseillé. Certains BIOS appellent indirectement cette méthode _DSM lorsque Windows appelle ACPI _PTS comme implémentation de la détection automatique MOR d’arrêt propre (comme décrit dans la section 2.3 de la spécification d’atténuation des attaques de réinitialisation de la plateforme de groupe de travail du client PC, version 1.10 (téléchargement PDF)).
Cet ACPI _PTS implémentation de la détection automatique MOR est insuffisante en matière de sécurité et ne doit pas être utilisée.
MemoryOverwriteRequestControlLock
Le BIOS contenant l’atténuation améliorée crée cette variable UEFI au démarrage précoce :
VendorGuid : {BB983CCF-151D-40E1-A07B-4A17BE168292}
Nom : MemoryOverwriteRequestControlLock
Attributs : NV+BS+RT
Valeur GetVariable dans le paramètre de données : 0x0 (déverrouillé) ; 0x1 (verrouillé sans clé) ; 0x2 (verrouillé avec la clé)
Valeur SetVariable dans le paramètre De données : 0x0 (déverrouillé) ; 0x1 (verrouillé)
Verrouillage avec SetVariable
Sur chaque démarrage, le BIOS doit initialiser MemoryOverwriteRequestControlLock
vers une valeur d’octet unique de 0x00 (indiquant le déverrouillage) avant la phase de sélection de périphérique de démarrage (BDS) (DRIVER#####, SYSPREP##, BOOT##, *RECOVERY*, ...). Pour MemoryOverwriteRequestControlLock
(et MemoryOverwriteRequestControl
), le BIOS doit empêcher la suppression de la variable et des attributs doivent être épinglés à NV+BS+RT.
Lorsque SetVariable pour MemoryOverwriteRequestControlLock
est d’abord appelé en passant une valeur non nulle valide dans Les données, le mode d’accès pour les deux MemoryOverwriteRequestControlLock
et MemoryOverwriteRequestControl
est remplacé en lecture seule, indiquant qu’ils sont verrouillés.
Les implémentations de révision 1 n’acceptent qu’un octet unique de 0x00 ou 0x01 pour MemoryOverwriteRequestControlLock
.
La révision 2 accepte également une valeur de 8 octets qui représente une clé secrète partagée. Si une autre valeur est spécifiée dans SetVariable, l’appel échoue avec l’état EFI_INVALID_PARAMETER. Pour générer cette clé, utilisez une source d’entropie de haute qualité, telle que le module de plateforme approuvée ou le générateur de nombres aléatoires matériels.
Après avoir défini une clé, l’appelant et le microprogramme doivent enregistrer des copies de cette clé dans un emplacement protégé par confidentialité, tel que SMRAM sur IA32/X64 ou un processeur de service avec un stockage protégé.
Obtention de l’état du système
Dans la révision 2, lorsque les variables et MemoryOverwriteRequestControl
les MemoryOverwriteRequestControlLock
variables sont verrouillées, les appels de SetVariable (pour ces variables) sont d’abord vérifiés par rapport à la clé inscrite à l’aide d’un algorithme à temps constant. Si les deux clés sont présentes et correspondent, les variables revient à un état déverrouillé. Après cette première tentative ou si aucune clé n’est inscrite, les tentatives suivantes de définition de cette variable échouent avec EFI_ACCESS_DENIED pour empêcher les attaques par force brute. Dans ce cas, le redémarrage du système est le seul moyen de déverrouiller les variables.
Le système d’exploitation détecte la présence et MemoryOverwriteRequestControlLock
son état en appelant GetVariable. Le système peut ensuite verrouiller la valeur actuelle en MemoryOverwriteRequestControl
définissant la MemoryOverwriteRequestControlLock
valeur sur 0x1. Vous pouvez également spécifier une clé pour activer le déverrouillage à l’avenir une fois que les données secrètes ont été vidées en toute sécurité de la mémoire.
Appel de GetVariable pour MemoryOverwriteRequestControlLock
les retours 0x0, 0x1 ou 0x2 pour indiquer déverrouillé, verrouillé sans clé ou verrouillé avec des états de clé.
Le paramètre MemoryOverwriteRequestControlLock
ne s’applique pas au flash (modifie simplement l’état de verrouillage interne). L’obtention de la variable retourne l’état interne et n’expose jamais la clé.
Exemple d’utilisation par le système d’exploitation :
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);
Flux d’implémentation MorLock
Ces organigrammes montrent le comportement attendu de votre implémentation :
Initialisation
Flux SetVariable
Flux d’état déverrouillé pour SetVariable
Flux d’état verrouillé pour SetVariable
Flux pour GetVariable
Voir aussi
Exigences UEFI qui s’appliquent à toutes les éditions Windows sur les plateformes SoC
Protection de BitLocker contre les attaques à froid (et d’autres menaces)
Visite guidée au-delà du BIOS avec le support UEFI TPM2 dans EDKII
Protéger les informations d’identification de domaine dérivées avec Credential Guard