Безопасная реализация MOR
Сводка
- Поведение MorLock, редакция 2
Последнее обновление
- Август 2020 г.
Применяется к
Windows 10
Изготовители оборудования и поставщики BIOS, которые хотят поддерживать функцию Credential Guard Windows 10.
Официальные спецификации
Рекомендуемые материалы
Запись блога: Защита BitLocker от холодных атак (и других угроз)
Технический документ. Обзор за пределами BIOS с поддержкой TPM2 UEFI в EDKII
Защита извлеченных учетных данных домена с помощью Credential Guard
Общие сведения
В этом разделе описывается поведение и использование переменной MemoryOverwriteRequestControlLock
UEFI версии 2.
Чтобы предотвратить расширенные атаки на память, в существующей системе улучшена защита bios MemoryOverwriteRequestControl для поддержки блокировки для защиты от новых угроз. Модель угроз расширена, чтобы включить ядро ОС узла в качестве злоумышленника, поэтому службы среды выполнения ACPI и UEFI, выполняемые на уровне привилегий ядра, не являются доверенными. Как и реализации безопасной загрузки, MorLock следует реализовать в привилегированном контексте выполнения встроенного ПО, который не может быть изменен ядром ОС узла (например, режим управления системой, TrustZone, BMC и т. д.). Интерфейс основан на службах переменных UEFI, которые описаны в спецификации UEFI версии 2.5, раздел 7.2 с именем "Службы переменных".
Это устранение рисков, называемое MorLock, должно быть реализовано во всех новых системах, а не только в системах с доверенными платформенными модулями. В редакции 2 добавлена новая возможность разблокировки для снижения проблем с производительностью загрузки, особенно в системах с большим объемом памяти.
Что касается метода управления ACPI _DSM для настройки битового состояния MOR (как описано в разделе 6 спецификации по устранению рисков атак с помощью рабочей группы клиента ПК версии 1.10 (скачать PDF)), рекомендуется удалить этот метод _DSM из современных реализаций BIOS.
Однако если BIOS реализует этот метод _DSM, он должен учитывать состояние MorLock. Если MorLock заблокирован с ключом или без нее, этот метод _DSM не должен изменять MOR и возвращать значение 1, соответствующее "Общий сбой". Для разблокировки MorLock версии 2 не определен механизм ACPI.
Обратите внимание, что Windows не вызывает этот метод _DSM напрямую с Windows 7 и считает его устаревшим. Некоторые BIOS косвенно вызывает этот метод _DSM, когда Windows вызывает ACPI _PTS как реализацию автоматического обнаружения mor для чистого завершения работы (как описано в разделе 2.3 спецификации по устранению рисков для сброса платформы клиента ПК версии 1.10 (скачать PDF)).
Этот acPI _PTS реализации автоматического обнаружения MOR является недостаточным и не должен использоваться.
MemoryOverwriteRequestControlLock
BIOS, содержащий улучшенную меру устранения рисков, создает эту переменную UEFI во время ранней загрузки:
VendorGuid:{BB983CCF-151D-40E1-A07B-4A17BE168292}
Имя:MemoryOverwriteRequestControlLock
.
Атрибуты: NV+BS+RT
Значение GetVariable в параметре Data: 0x0 (разблокировано); 0x1 (блокировка без ключа); 0x2 (заблокирован ключом)
Значение SetVariable в параметре Data : 0x0 (разблокировано); 0x1 (заблокировано)
Блокировка с помощью SetVariable
При каждой загрузке BIOS должна инициализироваться MemoryOverwriteRequestControlLock
до однобайтового значения 0x00 (указывает на разблокировано) перед этапом выбора загрузочного устройства (BDS) (DRIVER######, SYSPREP####, BOOT####, *RECOVERY*, ...). Для MemoryOverwriteRequestControlLock
(и MemoryOverwriteRequestControl
) BIOS должен предотвратить удаление переменной, а атрибуты должны быть закреплены в NV+BS+RT.
При первом вызове метода SetVariable для MemoryOverwriteRequestControlLock
путем передачи допустимого ненулевого значения в data режим доступа для обоих MemoryOverwriteRequestControlLock
и MemoryOverwriteRequestControl
меняется на режим только для чтения, что указывает, что они заблокированы.
Реализации редакции 1 принимают только один байт 0x00 или 0x01 для MemoryOverwriteRequestControlLock
.
Редакция 2 также принимает 8-байтовое значение, представляющее общий секретный ключ. Если в SetVariable указано любое другое значение, вызов завершается ошибкой с состоянием EFI_INVALID_PARAMETER. Чтобы создать этот ключ, используйте источник энтропии высокого качества, например доверенный платформенный модуль или аппаратный генератор случайных чисел.
После настройки ключа вызывающий объект и встроенное ПО должны сохранять копии этого ключа в защищенном конфиденциальном расположении, например SMRAM в IA32/X64 или в обработчике службы с защищенным хранилищем.
Получение состояния системы
В редакции 2 при MemoryOverwriteRequestControlLock
блокировке переменных и MemoryOverwriteRequestControl
вызовы SetVariable (для этих переменных) сначала проверяются на соответствие зарегистрированного ключа с помощью алгоритма постоянного времени. Если оба ключа присутствуют и совпадают, переменные возвращаются в состояние разблокировки. После этой первой попытки или если ключ не зарегистрирован, последующие попытки задать эту переменную завершаются сбоем с EFI_ACCESS_DENIED, чтобы предотвратить атаки методом подбора. В этом случае перезагрузка системы должна быть единственным способом разблокировки переменных.
Операционная система определяет наличие MemoryOverwriteRequestControlLock
и его состояние, вызывая Метод GetVariable. Затем система может заблокировать текущее значение , MemoryOverwriteRequestControl
задав MemoryOverwriteRequestControlLock
значение 0x1. Кроме того, он может указать ключ для включения разблокировки в будущем после безопасной очистки секретных данных из памяти.
Вызов Метода GetVariable для MemoryOverwriteRequestControlLock
возвращает 0x0, 0x1 или 0x2, чтобы указать состояние разблокировано, заблокировано без ключа или заблокировано с состоянием ключа.
Параметр MemoryOverwriteRequestControlLock
не фиксирует вспышку (просто изменяет состояние внутренней блокировки). Получение переменной возвращает внутреннее состояние и никогда не предоставляет ключ.
Пример использования операционной системой:
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
На этих блок-схемах показано ожидаемое поведение реализации:
Инициализация
Поток SetVariable
Поток незаблокированного состояния для SetVariable
Поток заблокированного состояния для SetVariable
Поток для GetVariable
См. также раздел
Требования UEFI, которые применяются ко всем выпускам Windows на платформах SoC
Защита BitLocker от холодных атак (и других угроз)
Обзор за пределами BIOS с поддержкой UEFI TPM2 в EDKII
Защита извлеченных учетных данных домена с помощью Credential Guard
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по