Аппаратное хранилище ключей

Наличие доверенной среды выполнения (TEE) в системе на кристалле (SoC) дает возможность устройствам Android предоставлять аппаратно-поддерживаемые, надежные службы безопасности для ОС Android, служб платформы и даже сторонних приложений (в виде специфичных для Android расширений стандартной архитектуры криптографии Java, см. KeyGenParameterSpec ).

Глоссарий

Ниже представлен краткий обзор компонентов Keystore и их взаимосвязей.

AndroidKeyStore
API Android Framework и компонент, используемые приложениями для доступа к функционалу хранилища ключей. Это реализация стандартных API криптографической архитектуры Java, которая также добавляет расширения, специфичные для Android, и состоит из кода Java, который выполняется в пространстве собственных процессов приложения. AndroidKeyStore обрабатывает запросы приложения на работу с хранилищем ключей, перенаправляя их демону хранилища ключей.
демон хранилища ключей
Системный демон Android, предоставляющий доступ ко всем функциям хранилища ключей через API Binder . Этот демон отвечает за хранение ключевых блоков, созданных базовой реализацией KeyMint (или Keymaster), которые содержат секретный ключевой материал в зашифрованном виде, что позволяет хранилищу ключей хранить их, но не использовать и не раскрывать.
Служба KeyMint HAL
Сервер AIDL, реализующий HAL IKeyMintDevice , предоставляющий доступ к базовому TA KeyMint.
Доверенное приложение KeyMint (TA)
Программное обеспечение, работающее в безопасном контексте, чаще всего в TrustZone на базе ARM SoC, обеспечивает все безопасные криптографические операции. Это приложение имеет доступ к исходным данным ключей и проверяет все условия контроля доступа к ключам, прежде чем разрешить их использование.
LockSettingsService
Компонент системы Android, отвечающий за аутентификацию пользователя по паролю и отпечатку пальца. Он не является частью Keystore, но важен, поскольку Keystore поддерживает концепцию привязанных ключей аутентификации : ключей, которые могут быть использованы только после аутентификации пользователя. LockSettingsService взаимодействует с Gatekeeper TA и Fingerprint TA для получения токенов аутентификации, которые он предоставляет демону хранилища ключей и которые используются KeyMint TA.
Привратник ТА
Компонент, работающий в защищенной среде, который отвечает за аутентификацию паролей пользователей и генерацию токенов аутентификации, используемых для подтверждения ТА KeyMint того, что аутентификация была выполнена для конкретного пользователя в определенный момент времени.
ТА по отпечаткам пальцев
Компонент, работающий в защищенной среде, который отвечает за аутентификацию отпечатков пальцев пользователя и генерацию токенов аутентификации, используемых для подтверждения ТА KeyMint того, что аутентификация была выполнена для конкретного пользователя в определенный момент времени.

Архитектура

API хранилища ключей Android и лежащий в его основе KeyMint HAL предоставляют базовый, но достаточный набор криптографических примитивов, позволяющий реализовывать протоколы с использованием аппаратно поддерживаемых ключей с контролируемым доступом.

KeyMint HAL — это предоставляемая OEM-производителем служба, используемая службой Keystore для предоставления аппаратно-поддерживаемых криптографических сервисов. Для обеспечения безопасности данных закрытого ключа реализации HAL не выполняют никаких конфиденциальных операций ни в пространстве пользователя, ни даже в пространстве ядра. Вместо этого служба KeyMint HAL, работающая в Android, делегирует конфиденциальные операции TA, работающему в какой-либо безопасной среде, обычно путём маршаллинга и демаршаллинга запросов в формате, определяемом реализацией.

Итоговая архитектура выглядит так:

Доступ к KeyMint

Рисунок 1. Доступ к KeyMint.

API KeyMint HAL — низкоуровневый интерфейс, используемый внутренними компонентами платформы и недоступный разработчикам приложений. Более высокоуровневый API Java, доступный приложениям, описан на сайте для разработчиков Android .

Контроль доступа

Хранилище ключей Android представляет собой центральный компонент для хранения и использования аппаратных криптографических ключей как для приложений, так и для других компонентов системы. Таким образом, доступ к любому отдельному ключу обычно ограничен приложением или компонентом системы, создавшим этот ключ.

Домены хранилища ключей

Для поддержки такого контроля доступа ключи идентифицируются в хранилище ключей с помощью дескриптора ключа . Этот дескриптор указывает домен , к которому принадлежит дескриптор, а также идентификатор в этом домене.

Приложения Android обращаются к Keystore, используя стандартную архитектуру криптографии Java, которая идентифицирует ключи по строковому псевдониму. Этот метод идентификации внутренне сопоставляется с доменом APP Keystore; также включается UID вызывающего объекта для устранения неоднозначности ключей из разных приложений, предотвращая доступ одного приложения к ключам другого.

Внутри фреймворка код также получает уникальный числовой идентификатор ключа после его загрузки. Этот числовой идентификатор используется в качестве идентификатора для дескрипторов ключей в домене KEY_ID . Однако контроль доступа по-прежнему осуществляется: даже если одно приложение обнаружит идентификатор ключа другого приложения, оно не сможет использовать его в обычных условиях.

Однако приложение может предоставить доступ к ключу другому приложению (идентифицируемому по UID). Эта операция предоставления доступа возвращает уникальный идентификатор, который используется в качестве идентификатора для дескрипторов ключей в домене GRANT . Контроль доступа по-прежнему осуществляется: даже если третье приложение обнаружит идентификатор ключа получателя, оно не сможет его использовать.

Хранилище ключей также поддерживает два других домена для дескрипторов ключей, которые используются для других компонентов системы и недоступны для ключей, созданных приложением:

  • Домен BLOB указывает на отсутствие идентификатора ключа в дескрипторе ключа; вместо этого дескриптор ключа содержит сам ключевой блок, а клиент управляет его хранением. Это используется клиентами (например, vold ), которым требуется доступ к хранилищу ключей до монтирования раздела данных.
  • Домен SELINUX позволяет системным компонентам совместно использовать ключи, при этом доступ регулируется числовым идентификатором, соответствующим метке SELinux (см. политику SELinux для keystore_key ).

Политика SELinux для keystore_key

Значения идентификаторов, используемые для дескрипторов ключей Domain::SELINUX , настраиваются в файле политики SELinux keystore2_key_context . Каждая строка в этих файлах сопоставляет числовое значение с меткой SELinux, например:

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share Keystore keys.
102            u:object_r:wifi_key:s0

Компонент, которому необходим доступ к ключу с идентификатором 102 в домене SELINUX , должен иметь соответствующую политику SELinux. Например, чтобы разрешить wpa_supplicant получать и использовать эти ключи, добавьте следующую строку в hal_wifi_supplicant.te :

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

Числовые идентификаторы ключей Domain::SELINUX разделены на диапазоны для поддержки различных разделов без коллизий:

Раздел Диапазон Файлы конфигурации
Система 0 ... 9,999 /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
Расширенная система 10 000 ... 19 999 /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
Продукт 20 000 ... 29 999 /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
Продавец 30 000 ... 39 999 /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

Для системного раздела определены следующие конкретные значения:

Идентификатор пространства имен Метка SEPolicy UID Описание
0 su_key Н/Д Ключ суперпользователя. Используется только для тестирования сборок userdebug и eng. Не применимо к пользовательским сборкам.
1 shell_key Н/Д Пространство имён, доступное для оболочки. В основном используется для тестирования, но может использоваться и в пользовательских сборках из командной строки.
100 vold_key Н/Д Предназначено для использования vold.
101 odsign_key Н/Д Используется демоном подписи на устройстве.
102 wifi_key AID_WIFI(1010) Используется подсистемой Wi-Fi Android, включая wpa_supplicant .
103 locksettings_key Н/Д Используется LockSettingsService
120 resume_on_reboot_key AID_SYSTEM(1000) Используется системным сервером Android для поддержки возобновления работы после перезагрузки.

Векторы доступа

Хранилище ключей позволяет контролировать, какие операции можно выполнять с ключом, а также контролировать общий доступ к ключу. Разрешения keystore2_key описаны в файле KeyPermission.aidl .

Системные разрешения

Помимо управления доступом на уровне ключа, описанного в политике SELinux для keystore_key , в следующей таблице описываются другие разрешения SELinux, необходимые для выполнения различных системных операций и операций по обслуживанию:

Разрешение Значение
add_auth Требуется для добавления токенов аутентификации в хранилище ключей; используется поставщиками аутентификации, такими как Gatekeeper или BiometricManager .
clear_ns Требуется для удаления всех ключей в определенном пространстве имен; используется в качестве операции обслуживания при удалении приложений.
list Требуется системой для перечисления ключей по различным свойствам, таким как владение или привязка к аутентификации. Это разрешение не требуется вызывающим объектам, перечисляющим свои собственные пространства имён (охватывается разрешением get_info ).
lock Требуется для уведомления хранилища ключей о том, что устройство заблокировано, что, в свою очередь, исключает суперключи, обеспечивая недоступность ключей аутентификации.
unlock Требуется для уведомления хранилища ключей о том, что устройство разблокировано, восстанавливая доступ к суперключам, которые защищают ключи, связанные с аутентификацией.
reset Требуется для сброса хранилища ключей к заводским настройкам, удаления всех ключей, которые не являются жизненно важными для функционирования ОС Android.

История

В Android 5 и более ранних версиях Android имелся простой аппаратный API криптографических сервисов, предоставляемый аппаратным уровнем абстракции Keymaster (HAL) версий 0.2 и 0.3. Keystore обеспечивал операции цифровой подписи и верификации, а также генерацию и импорт пар асимметричных ключей подписи. Это уже реализовано на многих устройствах, но существует множество задач безопасности, которые невозможно легко решить с помощью одного лишь API подписи. В Android 6.0 API Keystore был расширен, предоставляя более широкий спектр возможностей.

Андроид 6.0

В Android 6.0 в Keymaster 1.0 были добавлены симметричные криптографические примитивы , AES и HMAC, а также система контроля доступа для аппаратных ключей. Контроль доступа задаётся при генерации ключа и применяется в течение всего срока его действия. Ключи можно ограничить так, чтобы они были доступны только после аутентификации пользователя и только для определённых целей или с определёнными криптографическими параметрами.

Помимо расширения спектра криптографических примитивов, Keystore в Android 6.0 добавил следующее:

  • Схема контроля использования, позволяющая ограничить использование ключей, чтобы снизить риск нарушения безопасности из-за неправильного использования ключей.
  • Схема контроля доступа, позволяющая ограничить доступ к ключам определенным пользователям, клиентам и определенному временному диапазону.

Андроид 7.0

В Android 7.0 в Keymaster 2 добавлена ​​поддержка аттестации ключей и привязки версии.

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

Привязка к версии привязывает ключи к версии операционной системы и уровню исправления. Это гарантирует, что злоумышленник, обнаружив уязвимость в старой версии системы или программного обеспечения TEE, не сможет откатить устройство к уязвимой версии и использовать ключи, созданные в новой версии. Кроме того, когда ключ с заданной версией и уровнем исправления используется на устройстве, обновлённом до новой версии или уровня исправления, ключ обновляется до того, как его можно будет использовать, а предыдущая версия ключа становится недействительной. По мере обновления устройства ключи перемещаются вперёд вместе с устройством, но любой возврат устройства к предыдущей версии делает ключи непригодными для использования.

Андроид 8.0

В Android 8.0 Keymaster 3 перешёл со старой структуры HAL на языке C на интерфейс HAL на языке C++, сгенерированный на основе определения на новом языке определения аппаратных интерфейсов (HIDL). В рамках этого изменения многие типы аргументов были изменены, хотя типы и методы имеют однозначное соответствие со старыми типами и методами структуры HAL.

Помимо этой версии интерфейса, Android 8.0 расширил функцию аттестации Keymaster 2, добавив поддержку аттестации ID . Аттестация ID предоставляет ограниченный и необязательный механизм для строгой аттестации идентификаторов оборудования, таких как серийный номер устройства, название продукта и идентификатор телефона (IMEI или MEID). Для реализации этого нововведения Android 8.0 изменил схему аттестации ASN.1, добавив аттестацию ID. Реализациям Keymaster необходимо найти безопасный способ извлечения соответствующих элементов данных, а также определить механизм для безопасного и постоянного отключения этой функции.

Андроид 9

В Android 9 обновления включали:

  • Обновление до Keymaster 4
  • Поддержка встроенных безопасных элементов
  • Поддержка безопасного импорта ключей
  • Поддержка шифрования 3DES
  • Изменения в привязке версий, чтобы boot.img и system.img имели отдельные установленные версии для обеспечения независимых обновлений.

Андроид 10

В Android 10 появилась версия Keymaster HAL 4.1, в которой добавлено:

  • Поддержка ключей, которые можно использовать только при разблокированном устройстве
  • Поддержка ключей, которые можно использовать только на ранних этапах загрузки
  • Дополнительная поддержка аппаратно упакованных ключей хранения
  • Дополнительная поддержка уникальной аттестации устройства в StrongBox

Андроид 12

В Android 12 появился новый KeyMint HAL, который заменяет Keymaster HAL, но обеспечивает схожую функциональность. Помимо всех вышеперечисленных функций, KeyMint HAL также включает в себя:

  • Поддержка ключевого соглашения ECDH
  • Поддержка пользовательских ключей аттестации
  • Поддержка ключей с ограниченным количеством использований

Android 12 также включает новую версию демона системы хранилища ключей, переписанную на Rust и известную как keystore2

Андроид 13

В Android 13 добавлена ​​версия KeyMint HAL v2, которая добавляет поддержку Curve25519 как для подписи, так и для согласования ключей.