Привратник

Подсистема Gatekeeper выполняет аутентификацию по шаблону устройства/паролю в среде Trusted Execution Environment (TEE). Gatekeeper регистрирует и проверяет пароли с помощью аппаратного секретного ключа. Кроме того, Gatekeeper ограничивает последовательные неудачные попытки проверки и должен отказывать в обслуживании запросов на основе заданного тайм-аута и заданного количества последовательных неудачных попыток.

Когда пользователи проверяют свои пароли, Gatekeeper выдает токен аутентификации, подписанный ключом HMAC для каждой загрузки, который доступен только для защищенных компонентов, и этот токен отправляется в аппаратное хранилище ключей . То есть токен аутентификации Gatekeeper уведомляет Keystore о том, что ключи, привязанные к аутентификации (например, ключи, созданные приложениями), могут использоваться приложениями.

Архитектура

Gatekeeper включает в себя три основных компонента:

  • gatekeeperd (Gatekeeper daemon) — служба C++ Binder в Android, которая содержит независимую от платформы логику, реализующую интерфейс IGateKeeperService AIDL на основе базовой реализации IGatekeeper , специфичной для поставщика.
  • Служба уровня аппаратной абстракции Gatekeeper (HAL) — специфичная для поставщика реализация интерфейса IGatekeeper AIDL. Эта служба HAL работает в Android, но основная функциональность Gatekeeper должна работать в защищенной среде, поэтому она обычно взаимодействует с Gatekeeper TA.
  • Доверенное приложение Gatekeeper (TA) — реализация, специфичная для поставщика, которая работает в TEE и выполняет фактическую проверку пароля или шаблона.

LockSettingsService делает запрос (через Binder), который достигает демона gatekeeperd в ОС Android. Затем демон gatekeeperd делает запрос к службе HAL IGatekeeper , а та, в свою очередь, достигает своего аналога Gatekeeper TA в TEE:

Поток привратника

Рисунок 1. Высокоуровневый поток данных для аутентификации с помощью GateKeeper.

Демон gatekeeperd предоставляет API-интерфейсам Android Framework доступ к 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 и другие реализации

Операционная система Trusty — это доверенная ОС с открытым исходным кодом от Google для сред TEE, которая содержит одобренную реализацию Gatekeeper. Однако любая ОС TEE может реализовать Gatekeeper, если у TEE есть доступ к постоянному аппаратному ключу и безопасным, монотонным часам , которые тикают в режиме ожидания .

Trusty использует внутреннюю систему IPC для прямой передачи общего секрета между KeyMint и реализацией Trusty Gatekeeper ( Trusty Gatekeeper ). Этот общий секрет используется для подписи токенов аутентификации, отправляемых в Keystore для предоставления аттестаций проверки пароля. Trusty Gatekeeper запрашивает ключ у KeyMint для каждого использования и не сохраняет или не кэширует значение. Реализации могут свободно делиться этим секретом любым способом, который не ставит под угрозу безопасность.

Ключ HMAC, используемый для регистрации и проверки паролей, создается и хранится исключительно в Gatekeeper.

Android предоставляет общую реализацию Gatekeeper на C++, которая требует только добавления специфичных для устройства процедур для завершения; реализация Trusty основана на этом. Чтобы реализовать TEE Gatekeeper с специфичным для устройства кодом для вашего TEE, обратитесь к функциям и комментариям в system/gatekeeper/include/gatekeeper/gatekeeper.h . Основные обязанности совместимой реализации включают:

  • Соблюдение HAL IGatekeeper .
  • Возвращаемые токены аутентификации должны быть отформатированы в соответствии со спецификацией HardwareAuthToken (описанной в HardwareAuthToken.aidl ).
  • TEE Gatekeeper должен иметь возможность поделиться ключом HMAC с KeyMint, используя один из следующих способов:
    • Соглашение о совместном секрете: Gatekeeper может принимать участие в согласовании ключа HMAC при загрузке, реализуя ISharedSecret HAL. Для этого требуется, чтобы Gatekeeper и KeyMint имели доступ к общему предварительному секрету.
    • Прямой доступ: Gatekeeper может извлечь ключ HMAC из KeyMint, используя механизм внутреннего межпроцессного взаимодействия TEE, либо по запросу, либо при первом использовании (впоследствии кэшируется).

Безопасные идентификаторы пользователя (SID)

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

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

SID пользователя включается в аутентификацию HMAC вместе с паролем в дескрипторе пароля при регистрации пароля.

Идентификаторы безопасности пользователей включаются в HardwareAuthToken , возвращаемый функцией verify() , и связываются со всеми ключами хранилища ключей, связанными с аутентификацией (подробную информацию о формате HardwareAuthToken и хранилище ключей см. в разделе Аутентификация ).

Обратите внимание, что поскольку ненадежный вызов функции enroll() изменяет SID пользователя, вызов делает ключи, привязанные к этому паролю, бесполезными. Злоумышленники могут изменить пароль для устройства, если они контролируют ОС Android, но они уничтожают защищенные root, конфиденциальные ключи в процессе.

Запросить регулирование

Gatekeeper должен иметь возможность надежно блокировать попытки подбора учетных данных пользователя. Как показано в GatekeeperVerifyResponse.aidl , HAL обеспечивает возврат тайм-аута в миллисекундах. Тайм-аут информирует клиента о том, что не следует вызывать Gatekeeper снова, пока не истечет тайм-аут. Gatekeeper не должен обслуживать запросы, если есть ожидающий тайм-аут.

Gatekeeper должен записать счетчик отказов перед проверкой пароля пользователя. Если проверка пароля прошла успешно, счетчик отказов должен быть очищен. Это предотвращает атаки, которые предотвращают регулирование путем отключения встроенной MMC (eMMC) после выдачи вызова verify . Функция enroll также проверяет пароль пользователя (если он был предоставлен) и должна регулироваться таким же образом.

Если поддерживается устройством, настоятельно рекомендуется записывать счетчик отказов в защищенное хранилище. Если устройство не поддерживает шифрование на основе файлов или защищенное хранилище слишком медленное, реализации могут напрямую использовать Replay Protected Memory Block (RPMB).