Документация Требования безопасности и меры предосторожности Шифрование оперативной памяти в VeraCrypt

# Шифрование оперативной памяти в VeraCrypt

## Введение

Шифрование ОЗУ в VeraCrypt направлено на защиту ключей шифрования диска, хранящихся в энергонезависимой памяти, от определённых типов атак. Основные цели шифрования:

- Защита от атак при "холодной" загрузке компьютера (Cold Boot).
- Добавление уровня обфускации (запутывания кода), чтобы значительно усложнить восстановление мастер-ключей шифрования из дампов памяти, будь то в режиме реального времени или в автономном режиме.

### Реализация

Краткое описание того, как достигается шифрование оперативной памяти:

1. При запуске Windows драйвер VeraCrypt выделяет область памяти размером 1 МиБ. Если это не удаётся, размер уменьшается вдвое до тех пор, пока распределение не завершится успешно (минимальный размер – 8 КиБ). Все эти переменные размещаются в невыгружаемом пространстве памяти ядра.
2. Затем эта область памяти заполняется случайными байтами, сгенерированными CSPRNG на основе ChaCha20.
3. Генерируются два случайных 64-битных целых числа: `HashSeedMask` и `CipherIVMask`.
4. Для каждого мастер-ключа тома алгоритм шифрования ОЗУ получает уникальный ключ из комбинации области памяти и уникальных значений, извлечённых из памяти, подлежащей шифрованию. Это обеспечивает отдельный ключ для каждой зашифрованной области памяти. Использование ключей и IV, зависящих от местоположения, предотвращает лёгкое извлечение мастер-ключей из дампов памяти.
5. Мастер-ключи расшифровываются для каждого запроса, что требует быстрого алгоритма расшифровки. Для этого используется ChaCha12.
6. После монтирования тома его мастер-ключи немедленно шифруются по описанному алгоритму.
7. Для каждого запроса ввода-вывода для тома мастер-ключи расшифровываются только на время этого запроса, а затем надёжно удаляются.
8. При размонтировании тома зашифрованные мастер-ключи надёжно удаляются из памяти.
9. При завершении работы или перезагрузке Windows область памяти, выделенная во время запуска, надёжно очищается.

### Защита от атак при "холодной" перезагрузке ПК (Cold Boot)

Предотвращение атак при "холодной" загрузке достигается благодаря использованию большой страницы памяти для формирования (деривации) ключа. Это гарантирует, что злоумышленники не смогут восстановить мастер-ключ, поскольку части этой большой области памяти, скорее всего, будут повреждены и их нельзя будет восстановить после завершения работы. Более подробную информацию об атаках с "холодной" загрузкой и методах их предотвращения см. в следующих документах:

- Cold Boot Attacks (BlackHat)
- RAM Hijacks

### Несовместимость с режимом гибернации и быстрым запуском Windows

Шифрование оперативной памяти в VeraCrypt несовместимо с функциями гибернации и быстрого запуска Windows. Перед активацией шифрования ОЗУ эти функции будут отключены VeraCrypt, чтобы обеспечить безопасность и функциональность механизма шифрования.

### Выбор алгоритма

Выбор алгоритмов основывался на балансе между безопасностью и производительностью:

- t1ha2: Некриптографическая хеш-функция, выбранная из-за её чрезвычайно высокой скорости хеширования. Это очень важно, поскольку ключи извлекаются для каждого запроса шифрования/дешифрования из области памяти размером 1 МиБ. Также соблюдаются строгие лавинные критерии, что имеет решающее значение для данного варианта использования.
- ChaCha12: Этот алгоритм выбран вместо ChaCha20 по соображениям производительности; он обеспечивает достаточную надёжность шифрования при сохранении высокой скорости шифрования/дешифрования.

### Ключевые алгоритмы

Для шифрования оперативной памяти основополагающими являются два основных алгоритма:

#### 1. VcGetEncryptionID

Вычисляет уникальный идентификатор для набора буферов оперативной памяти, подлежащих шифрованию.

        – Ввод: pCryptoInfo, переменная CRYPTO_INFO для шифрования/дешифрования
        – Вывод: 64-битное целое число, идентифицирующее переменную pCryptoInfo
        – Шаги:
          – Вычисление суммы адресов виртуальной памяти полей ks и ks2 в pCryptoInfo: encID = ((uint64) pCryptoInfo->ks) + ((uint64) pCryptoInfo->ks2)
          – Возврат результата

#### 2. VcProtectMemory

Шифрует буфер оперативной памяти, используя уникальный идентификатор, сгенерированный VcGetEncryptionID.

        – Ввод:
          – encID, уникальный идентификатор памяти, подлежащей шифрованию
          – pbData, указатель на память, которую нужно зашифровать
          – pbKeyDerivationArea, область памяти, выделяемая драйвером при запуске
          – HashSeedMask и CipherIVMask, два 64-битных случайных целых числа при запуске
        – Вывод:
          – Отсутствует; память в pbData шифруется на месте
        – Шаги:
          – Формирование hashSeed: hashSeed = (((uint64) pbKeyDerivationArea) + encID) ^ HashSeedMask
          – Вычисление 128-битного хеша: hash128 = t1h2 (pbKeyDerivationArea,hashSeed)
          – Разложение hash128 на два 64-битных целых числа: hash128 = hash128_1 || hash128_2
          – Создание 256-битного ключа для ChaCha12: chachaKey = hash128_1 || hash128_2 || (hash128_1 OR hash128_2) || (hash128_1 + hash128_2)
          – Шифрование chachaKey с помощью ChaCha12, используя hashSeed как IV: ChaCha256Encrypt (chachaKey, hashSeed, chachaKey)
          – Формирование 64-битного IV для ChaCha12: chachaIV = (((uint64) pbKeyDerivationArea) + encID) ^ CipherIVMask
          – Шифрование памяти в pbData с помощью ChaCha12: ChaCha256Encrypt (chachaKey, chachaIV, pbData)
          – Надёжное стирание временных значений

Важно отметить, что поскольку ChaCha12 – это потоковый шифр, процессы шифрования и дешифрования идентичны, и функция `VcProtectMemory` может использоваться для обоих.

Для более глубокого понимания и ознакомления с кодовой базой посетите репозиторий VeraCrypt и изучите упомянутые функции в файле `src/Common/Crypto.c`.

### Дополнительные меры безопасности

Начиная с версии 1.24, в VeraCrypt встроен механизм, который обнаруживает установку новых устройств в систему, когда активно системное шифрование. При установке нового устройства мастер-ключи немедленно удаляются из памяти, что приводит к BSOD ("синему экрану смерти") в Windows. Это защищает от атак с помощью специализированных устройств для извлечения памяти из работающих систем. Однако для максимальной эффективности эта функция должна применяться вместе с шифрованием оперативной памяти.
Чтобы включить эту функцию, в меню Система выберите пункт Установки и активируйте опцию Удалять ключи шифрования из ОЗУ при подключении нового устройства.

### Технические ограничения, связанные с гибернацией и быстрым запуском

Функции гибернации и быстрого запуска Windows сохраняют содержимое оперативной памяти на жёстком диске. В контексте шифрования оперативной памяти VeraCrypt поддержка этих функций представляет собой серьёзную проблему.
Для обеспечения безопасности большáя область памяти, используемая для формирования ключа при шифровании ОЗУ, должна храниться в зашифрованном формате, отдельно от обычного шифрования VeraCrypt, применяемого к текущему диску. Это отдельное зашифрованное хранилище также должно быть разблокируемым тем же паролем, который использовался для предзагрузочной аутентификации. Более того, этот процесс должен произойти на ранней стадии загрузки, прежде чем появится доступ к файловой системе, что требует хранения необработанных зашифрованных данных в определённых секторах другого диска.
Хотя это технически осуществимо, сложность и недружественность такого решения к пользователям делают его непрактичным для стандартных применений. Поэтому при включении шифрования оперативной памяти отключаются гибернация и быстрый запуск Windows.