Когда впервые подключаешь TPM-чип к системе, кажется, что это просто очередной криптопроцессор. Но стоит разобраться в механизмах работы этого устройства глубже, как понимаешь: перед тобой целая экосистема безопасности, охватывающая буквально каждый уровень загрузки и работы операционной системы. От физической шины LPC до удалённой аттестации облачных нод. И Linux научился извлекать из этого максимум.

Физика подключения и драйверная архитектура

TPM физически подключается к материнской плате через Low Pin Count или Serial Peripheral Interface. Дискретные чипы от Infineon, Nuvoton, STMicroelectronics висят на этих шинах и общаются с процессором через Command Response Buffer. CRB, по сути, это структурированный набор регистров управления плюс буфер данных для передачи команд. Спецификация TCG PC Client Platform TPM Profile строго определяет этот интерфейс.

В ядре Linux за связь с чипом отвечает целый набор драйверов. Основной модуль tpm_tis работает с TPM 1.2 и TPM 2.0 через FIFO-интерфейс. Драйвер tpm_crb появился для поддержки Command Response Buffer в TPM 2.0. Для ARM64 архитектуры всё интереснее: там используется tpm_crb_ffa, который регистрируется в подсистеме FF-A и задействует Secure Monitor Call для взаимодействия с прошивкой TrustZone. Получается, что ARM-системы вызывают TPM не напрямую, а через безопасную среду выполнения.

Конфигурация ядра определяет, какие драйверы будут скомпилированы. Опция CONFIG_TCG_TPM включает базовую поддержку, CONFIG_TCG_TIS активирует TIS-драйвер, CONFIG_TCG_CRB отвечает за CRB. Без правильно настроенного ядра TPM останется невидимым для системы. Бывало, компилировал кастомное ядро для встраиваемой платы, забыл включить CONFIG_ACPI, и TPM просто не определялся, пока не понял, что без ACPI BIOS event log недоступен, а значит, и PCR 0-7 валидировать невозможно.

Доступ к TPM в Linux реализован через три интерфейса. Первый, /dev/tpm0, даёт прямой доступ, но монополизирует чип для одного клиента. Второй, /dev/tpmrm0, использует внутриядерный Resource Manager, который управляет потоком команд и обеспечивает многоклиентский доступ без конфликтов. Это рекомендуемый метод. Третий вариант, демон tpm2-abrmd в пользовательском пространстве, реализует спецификацию TAB/RM через DBus для управления сессиями и Unix pipes для команд. Но разработчики systemd открыто не рекомендуют его использование, отдавая предпочтение ядерному Resource Manager, что говорит о тенденции переносить критичные функции непосредственно в ядро для стабильности.

Безопасность шины остаётся слабым местом. Физические атаки типа TPM Genie, интерпозеры, перехватывающие данные между CPU и TPM на низкоскоростной шине, успешно применялись против BitLocker и Linux-шифрования. Ядро попыталось решить эту проблему через опцию CONFIG_TCG_TPM2_HMAC, требующую поддержку шифрования сеансов AES-128-CFB для операций HMAC. Но возникла проблема совместимости: старые TPM вроде Intel PTT не поддерживают AES-128-CFB, что приводило к ошибкам инициализации драйвера. В итоге, несмотря на повышение безопасности, функцию отключили по умолчанию в ядре 6.18 с бэкпортом до 6.10+. Вечный компромисс между защитой и совместимостью.

Генерация ключей и иерархия доверия

TPM создаёт ключи внутри себя, используя аппаратный генератор случайных чисел, и они никогда не покидают чип в незашифрованном виде. Ядро Linux интегрирует это через подсистему Trusted Keys. Процесс начинается с создания первичного ключа из null seed. Null seed, по сути, это семя, которое меняется каждый раз при сбросе TPM. Ядро создаёт primary elliptic curve key от этого null seed, и если TPM сбрасывают, все сессионные ключи, завязанные на старый seed, перестают работать. Это защита от атак со сбросом TPM.

Имя этого null primary key экспортируется через sysfs в /sys/class/tpm/tpm0/null_name. Пользовательское пространство может сертифицировать этот ключ через AIK и сравнить имя с тем, что передал загрузчик или другие компоненты. Если имя не совпадает, значит, TPM был сброшен или подменён. Это даёт цепочку доверия между загрузчиком, ядром и user-space.

Внутри TPM существует иерархия ключей. Endorsement Key, уникальный ключ производителя, обычно 2048-битный RSA или ECC, служит корнем идентификации TPM. Storage Root Key генерируется пользователем во время ownership takeover и используется для шифрования других ключей. Attestation Identity Keys создаются для подписания измерений и намеренно немигрируемые, чтобы сохранить приватность.

Создание ключа в Linux выглядит примерно так:

keyctl add trusted kmk "new 32 keyhandle=0x81000001" @u

Эта команда создаёт 32-байтовый ключ под SRK. Ключ автоматически шифруется и может быть сохранён в blob-файл. Загрузка происходит через:

keyctl add trusted kmk "load $(cat blob)" @u

Самое мощное, что есть в TPM, это sealing. Ключ можно запечатать к конкретным значениям PCR регистров. То есть ключ расшифруется только если текущие значения PCR точно совпадают с теми, что были при запечатывании. Изменили конфигурацию BIOS? PCR изменился, ключ не откроется. Подменили загрузчик? Та же история. Обновили ядро? Опять проблема.

Проблема обновлений серьёзная. Каждое изменение ядра или initramfs меняет PCR, и статически запечатанные ключи требуют миграции. Trusted Keys API предоставляет механизм обновления:

keyctl update keyid "update pcrinfo=$(cat pcrinfo)"

Это пересоздаёт ключ с новыми значениями PCR, но процесс административно тяжёлый. Шифрованные ключи (encrypted keys) используют AES и мастер-ключ, работают быстрее, но не имеют аппаратного корня, поэтому менее защищены.

Математика PCR extend и цепочка измерений

PCR регистры, это не просто ячейки памяти. Это криптографические аккумуляторы истории системы. Формула расширения определяет их уникальность:

PCR_new = HASH(PCR_old || new_measurement)

Старое значение PCR конкатенируется с новым измерением, и результат хешируется. Это необратимая операция. Напрямую перезаписать PCR нельзя, только расширить. Если последовательность измерений повторяется, итоговое значение PCR будет идентичным. Это позволяет валидировать состояние системы.

TPM 2.0 поддерживает банки PCR, каждый банк использует свой алгоритм хеширования: SHA-1, SHA-256, SHA-384. Один индекс PCR, например PCR[0], имеет отдельные значения для каждого алгоритма. Смена банка меняет алгоритм для будущих extend-операций, но делает все ключи, привязанные к старым PCR значениям, недоступными.

При загрузке системы UEFI измеряет прошивку и расширяет PCR 0. Затем идёт цепочка: BIOS измеряет загрузчик, загрузчик измеряет ядро, ядро измеряет initramfs. Каждый компонент расширяет соответствующий PCR. PCR 7 измеряет переменную SecureBoot (EV_EFI_VARIABLE_DRIVER_CONFIG), подтверждая, что платформа загрузилась в доверенном режиме. PCR 11 часто используется для Unified Kernel Images, когда systemd-stub расширяет его хешем UKI.

Вот как это выглядит в U-Boot:

tpm2 init && tpm2 startup TPM2_SU_CLEAR
mmc dev 2 1 && mmc read $loadaddr 0 0x2000
hash sha1 $loadaddr $filesize *0x40200000
tpm2 pcr_extend 0 0x40200000 sha1

Чтение текущих значений PCR:

tpm2_pcrread sha1:0,1,2

На симуляторе, если PCR ещё не расширялись, увидишь дефолтные значения, все нули или единицы. Операция extend меняет это.

После загрузки в игру вступает Integrity Measurement Architecture. IMA измеряет исполняемые файлы и системные компоненты при их доступе, добавляет записи в журнал измерений и, если TPM доступен, расширяет PCR 10. Журнал доступен через securityfs в /sys/kernel/security/ima/ascii_runtime_measurements. Каждая строка содержит индекс PCR, предыдущее значение PCR, название шаблона, алгоритм хеша, хеш измеренного объекта и путь к файлу.

IMA работает в трёх режимах: IMA-Measurement записывает измерения, IMA-Appraisal проверяет целостность файла через хеш или цифровую подпись в расширенных атрибутах, IMA-Audit пишет хеш в аудит-журнал. Политики IMA определяют, к каким файлам применять измерения, проверку или аудит. Правила политики встраиваются в ядро или загружаются динамически.

Extended Verification Module дополняет IMA, защищая метаданные файлов. Критичные данные вроде хешей IMA и атрибутов SELinux хранятся в xattr. Если диск извлечь из системы, эти атрибуты можно изменить оффлайн. EVM предотвращает это, вычисляя HMAC над защищаемыми атрибутами и сохраняя его в security.evm. HMAC генерируется с использованием приватного ключа, который сам является Trusted Key, зашифрованным Storage Primary Key TPM. Получается двойной уровень защиты: IMA контролирует содержимое, EVM защищает метаданные, и оба завязаны на аппаратный корень доверия.

Подписанные PCR-политики как решение

Статическое запечатывание к PCR значениям создаёт кошмар для администраторов. Каждое обновление ядра требует миграции ключей, иначе система не загрузится или диски не расшифруются. TPM 2.0 предлагает элегантное решение: подписанные PCR-политики.

Вместо привязки ключа к конкретному хешу состояния, ключ привязывается к подписанной политике. Политика, это набор условий для разблокировки, криптографически подписанный доверенным ключом. При расшифровке TPM проверяет подпись политики публичным ключом, зарегистрированным в TPM. Если подпись валидна, ключ разблокируется, даже если значение PCR изменилось.

Это работает так: создаёшь новый UKI, подписываешь его, обновляешь политику, подписываешь политику. При загрузке нового UKI, PCR 11 изменяется, но TPM видит валидную подпись политики и предоставляет доступ. Динамическое доверие без потери безопасности.

systemd-cryptenroll поддерживает это из коробки:

systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7+11 \
  --tpm2-public-key=policy.pub /dev/sdaX

Инструмент ukify генерирует подписанные UKI, интегрируя ядро, initramfs и командную строку в один образ с подписью. Это устраняет необходимость ручной миграции при каждом апдейте.

Цепочки удалённой аттестации

Удалённая аттестация решает вопрос: как проверить целостность системы издалека? Механизм построен на криптографической цепочке от Endorsement Key до PCR квоты.

Endorsement Key, уникальный для каждого TPM, сертифицируется производителем. Attestation Identity Key создаётся как дочерний ключ EK и используется для подписи квот PCR. AIK остаётся анонимным, поскольку для каждой аттестации можно генерировать новый ключ, не раскрывая EK напрямую. Это обеспечивает приватность.

Провизионирование AIK в Linux происходит в пользовательском пространстве. Ядро экспортирует имя primary key через sysfs. Пользовательское пространство использует это для запуска процедуры сертификации AIK, связывающей его с EK через команды TPM2_MakeCredential и TPM2_ActivateCredential. Успешное выполнение гарантирует, что AIK исходит от подлинного TPM.

Процесс аттестации выглядит так. Верификатор отправляет запрос с случайным нонсом, который называется qualification data. Нонс защищает от атак повторного воспроизведения. TPM генерирует квоту через команду TPM2_Quote, подписанную AIK, включающую текущие значения PCR, нонс и флаг TPM_GENERATED.

Одновременно агент аттестации извлекает журнал измерений IMA из securityfs. Этот журнал содержит детальную историю событий, приведших к текущему значению PCR 10. Комплект из подписанной квоты и ML отправляется верификатору как отчёт о целостности.

Верификатор выполняет несколько проверок. Первая: валидация подписи квоты публичным ключом AIK, убеждаясь, что она исходит от сертифицированного TPM. Вторая: верификатор пересчитывает агрегированный хеш всего полученного ML и сравнивает его с PCR 10 из подписанной квоты. Если совпадают, целостность ML подтверждена, он не был подделан. Третья: каждое отдельное измерение в ML сравнивается с предварительно сконфигурированным белым списком известных авторизованных хешей, чтобы обнаружить несанкционированное ПО.

Keylime, это система непрерывного мониторинга, которая уведомляет оператора при сбое аттестации measured boot или нарушении мониторинга целостности во время работы. Она превращает TPM из пассивного хранилища измерений в активный элемент защиты, отслеживая удалённые ноды на предмет компрометации в реальном времени.

Практический пример создания AIK и квоты:

tpm2_createek --ek-context ek.ctx --key-algorithm rsa
tpm2_createak --ek-context ek.ctx --ak-context ak.ctx \
  --key-algorithm rsa --hash-algorithm sha256
tpm2_quote --key-context ak.ctx --pcr-list sha256:0,1,2,3 \
  --message quote.msg --signature quote.sig --qualification NONCE123

Верификатор получает quote.msg, quote.sig и публичный ключ AIK, проверяет подпись, пересчитывает PCR из журнала и валидирует.

Многоуровневая защита и практические аспекты

Эффективность TPM-интеграции зависит от согласованности драйверов ядра, подсистем целостности IMA/EVM и высокоуровневых API вроде Trusted Keys. Всё работает комплементарно. IMA измеряет содержимое файлов, EVM защищает метаданные, Trusted Keys связывают секреты с аппаратным корнем доверия, удалённая аттестация проверяет это извне.

Физические угрозы остаются. Для систем с физическим доступом полностью автоматическая разблокировка LUKS создаёт уязвимость к атакам холодной перезагрузки. Злоумышленник просто включает украденный компьютер, TPM автоматически предоставляет ключ, данные доступны. Решение: многофакторное запечатывание TPM плюс PIN-код. Clevis и systemd-cryptenroll поддерживают это:

systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 \
  --tpm2-with-pin=yes /dev/sdaX

Комбинация доверенного состояния платформы и знания секрета пользователем. Баланс между удобством и безопасностью.

Важно понимать различие между Secure Boot и Trusted Boot. Secure Boot на основе подписей UEFI обеспечивает подлинность загрузки, гарантируя, что загружается только авторизованный код. Trusted Boot на основе измерений TPM обеспечивает проверяемость состояния, создавая неизменяемую историю целостности в PCRs. Это не избыточные механизмы, а последовательные слои защиты.

Администрирование требует понимания того, что PCR меняются при обновлениях. Переход к подписанным PCR-политикам стратегически правильный шаг. Современные инструменты systemd-cryptenroll позволяют системе принимать изменения в конфигурации при условии криптографической авторизации, что снижает административную нагрузку при рутинных обновлениях.

В итоге интеграция TPM 2.0 в Linux предоставляет комплексную архитектуру безопасности, охватывающую генерацию ключей, измерение целостности и удалённую аттестацию. Эффективность зависит от правильной настройки драйверов, активации нужных PCR-банков, конфигурации IMA/EVM политик и использования подписанных PCR-политик для гибкости при обновлениях. Ключи защищаются через Trusted Keys API и запечатываются к критическим PCR. Многоуровневая защита, где IMA измеряет содержимое, EVM защищает метаданные, а удалённая аттестация предоставляет криптографически проверяемое доказательство целостности системы.