Подсистема Gatekeeper выполняет аутентификацию устройства по графическому ключу и паролю в доверенной среде выполнения (TEE). Gatekeeper регистрирует и проверяет пароли, используя аппаратный секретный ключ. Кроме того, Gatekeeper ограничивает количество последовательных неудачных попыток проверки и должен отклонять запросы на обслуживание в зависимости от заданного тайм-аута и заданного количества последовательных неудачных попыток.
Когда пользователи подтверждают свои пароли, Gatekeeper генерирует токен аутентификации, подписанный ключом HMAC, доступным только для защищенных компонентов при загрузке системы, и этот токен отправляется в хранилище ключей, поддерживаемое оборудованием . То есть, токен аутентификации Gatekeeper уведомляет хранилище ключей о том, что ключи, привязанные к аутентификации (например, ключи, созданные приложениями), могут использоваться приложениями.
Архитектура
В состав Gatekeeper входят три основных компонента:
-
gatekeeperd(демон Gatekeeper) — служба C++ Binder в Android, содержащая платформенно-независимую логику, реализующую интерфейс AIDLIGateKeeperService, основанный на базовой реализацииIGatekeeper, специфичной для конкретного поставщика. - Сервис аппаратного уровня абстракции (HAL) Gatekeeper — это реализация интерфейса AIDL
IGatekeeper, специфичная для конкретного производителя. Этот сервис HAL работает в Android, но основная функциональность Gatekeeper должна работать в защищенной среде, поэтому он обычно взаимодействует с Gatekeeper TA. - Gatekeeper Trusted Application (TA) — это реализация, специфичная для конкретного поставщика, которая работает в TEE и выполняет фактическую проверку пароля или графического ключа.
Сервис LockSettingsService отправляет запрос (через Binder), который достигает демона gatekeeperd в операционной системе Android. Затем демон gatekeeperd отправляет запрос к службе IGatekeeper HAL, которая, в свою очередь, достигает своего аналога Gatekeeper TA в TEE:

Рисунок 1. Высокоуровневая схема передачи данных для аутентификации с помощью GateKeeper.
Демон gatekeeperd предоставляет API фреймворка Android доступ к HAL и участвует в передаче данных об аутентификации устройств в Keystore. Демон gatekeeperd работает в собственном процессе и отделен от системного сервера.
реализация HAL
Демон gatekeeperd использует HAL IGatekeeper для взаимодействия с базовым Gatekeeper TA для аутентификации по паролю. Реализация Gatekeeper TA должна уметь подписывать (регистрировать) и проверять BLOB-объекты. Ожидается, что все реализации будут придерживаться стандартного формата токена аутентификации ( HardwareAuthToken ), генерируемого при каждой успешной проверке пароля. Подробную информацию о содержимом и семантике HardwareAuthToken см. в определении HardwareAuthToken.aidl .
Внедренные поставщиками реализации HAL-интерфейса IGatekeeper должны содержать функции enroll и verify :
- Метод
enrollпринимает блок паролей, подписывает его и возвращает подпись в виде дескриптора. Возвращаемый блок паролей (из вызова методаenroll) должен иметь структуру, показанную вsystem/gatekeeper/include/gatekeeper/password_handle.h. - Функция
verifyдолжна сравнить подпись, созданную на основе предоставленного пароля, и убедиться, что она совпадает с зарегистрированным идентификатором пароля.
Ключ, используемый для регистрации и проверки, никогда не должен меняться и должен быть воспроизводимым при каждой загрузке устройства.
Надежные и другие реализации
Операционная система Trusty — это открытая доверенная ОС от Google для сред TEE, содержащая утвержденную реализацию Gatekeeper. Однако любая ОС для TEE может реализовывать Gatekeeper, если TEE имеет доступ к постоянному аппаратному ключу и защищенным монотонным часам, работающим в режиме ожидания .
Trusty использует внутреннюю систему межпроцессного взаимодействия (IPC) для прямой передачи общего секрета между KeyMint (ранее Keymaster) и реализацией Gatekeeper в Trusty ( Trusty Gatekeeper ). Этот общий секрет используется для подписи токенов аутентификации, отправляемых в Keystore для подтверждения проверки пароля. Trusty Gatekeeper запрашивает ключ у KeyMint при каждом использовании и не сохраняет и не кэширует значение. Реализации могут свободно передавать этот секрет любым способом, не ставящим под угрозу безопасность.
Ключ HMAC, используемый для регистрации и проверки паролей, формируется и хранится исключительно в Gatekeeper.
Android предоставляет универсальную реализацию Gatekeeper на C++, для полной реализации которой требуется лишь добавление процедур, специфичных для устройства; реализация Trusty основана на этом. Для реализации TEE Gatekeeper с кодом, специфичным для вашего TEE, обратитесь к функциям и комментариям в system/gatekeeper/include/gatekeeper/gatekeeper.h . Основные обязанности совместимой реализации включают:
- Соблюдение требований
IGatekeeperHAL. - Возвращаемые токены аутентификации должны быть отформатированы в соответствии со спецификацией
HardwareAuthToken(описанной в разделе «Аутентификация »). - TEE Gatekeeper должен иметь возможность обмениваться ключом HMAC с KeyMint, либо запрашивая ключ через TEE IPC по запросу, либо постоянно поддерживая действительный кэш значения.
Защищенные идентификаторы пользователей (SID)
Идентификатор пользователя (SID) — это представление пользователя в формате TEE (без тесной связи с идентификатором пользователя Android). SID генерируется с помощью криптографического генератора псевдослучайных чисел (PRNG) всякий раз, когда пользователь регистрирует новый пароль, не указывая предыдущий. Это называется ненадежной повторной регистрацией и обычно происходит только при первой установке пользователем пароля или графического ключа.
Доверенная повторная регистрация происходит, когда пользователь предоставляет действительный предыдущий пароль, например, при смене пароля. В этом случае идентификатор безопасности пользователя (SID) переносится на новый дескриптор пароля, сохраняя при этом ключи, которые были к нему привязаны.
Идентификатор пользователя (SID) включается в аутентификацию HMAC вместе с паролем в дескрипторе пароля при регистрации пароля.
Идентификаторы безопасности пользователей (SID) включены в объект HardwareAuthToken , возвращаемый функцией verify() , и связаны со всеми ключами хранилища ключей, привязанными к аутентификации (подробнее о формате HardwareAuthToken и хранилище ключей см. в разделе «Аутентификация »).
Обратите внимание, что поскольку ненадежный вызов функции enroll() изменяет SID пользователя, этот вызов делает ключи, привязанные к этому паролю, бесполезными. Злоумышленники могут изменить пароль устройства, если контролируют операционную систему Android, но при этом уничтожают защищенные root-правами конфиденциальные ключи.
Запрос на ограничение скорости
Gatekeeper должен иметь возможность безопасно ограничивать попытки подбора учетных данных методом перебора. Как показано в GatekeeperVerifyResponse.aidl , HAL предусматривает возврат таймаута в миллисекундах. Таймаут сообщает клиенту, что не следует снова вызывать Gatekeeper до истечения этого времени. Gatekeeper не должен обрабатывать запросы, если ожидается истечение таймаута.
Перед проверкой пароля пользователя привратник должен записать счетчик ошибок. Если проверка пароля прошла успешно, счетчик ошибок должен быть обнулен. Это предотвращает атаки, которые препятствуют ограничению скорости путем отключения встроенной MMC (eMMC) после выполнения вызова verify . Функция enroll также проверяет пароль пользователя (если он предоставлен) и должна быть ограничена аналогичным образом.
Если устройство поддерживает эту функцию, настоятельно рекомендуется записывать счетчик ошибок в защищенное хранилище. Если устройство не поддерживает шифрование на основе файлов или если защищенное хранилище работает слишком медленно, можно использовать непосредственно защищенный от воспроизведения блок памяти (RPMB).