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

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

Глоссарий

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

AndroidKeyStore
API Android Framework и компонент, используемый приложениями для доступа к функциональным возможностям Keystore. Это реализация стандартных API Java Cryptography Architecture, но также добавляет специфичные для Android расширения и состоит из кода Java, который выполняется в собственном пространстве процесса приложения. AndroidKeyStore выполняет запросы приложения на поведение Keystore, перенаправляя их демону keystore.
демон хранилища ключей
Системный демон Android, который обеспечивает доступ ко всем функциям Keystore через API Binder . Этот демон отвечает за хранение keyblobs , созданных базовой реализацией KeyMint (или Keymaster), которые содержат секретный ключевой материал, зашифрованный, чтобы Keystore мог хранить их, но не использовать или раскрывать.
Служба 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.

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

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

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

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

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

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

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

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

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

  • Домен BLOB указывает, что в дескрипторе ключа нет идентификатора для ключа; вместо этого дескриптор ключа содержит сам keyblob, а клиент управляет хранилищем keyblob. Это используется клиентами (например, vold ), которым необходимо получить доступ к Keystore до монтирования раздела данных.
  • Домен 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 ... 9999 /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 УИД Описание
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 для поддержки возобновления работы после перезагрузки.

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

Keystore позволяет контролировать, какие операции могут быть выполнены с ключом, в дополнение к контролю общего доступа к ключу. Разрешения 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 криптографических служб с аппаратной поддержкой, предоставляемый версиями 0.2 и 0.3 уровня аппаратной абстракции Keymaster (HAL). 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 перешел от старого стиля C-структуры HAL к интерфейсу C++ HAL, сгенерированному из определения на новом языке определения аппаратного интерфейса (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 как для подписи, так и для согласования ключей.