Функции KeyMint

На этой странице представлены дополнительные сведения и рекомендации для разработчиков уровня аппаратной абстракции KeyMint (HAL). Основной документацией по HAL является спецификация интерфейса AIDL .

Неправильное использование API

Вызывающие объекты могут создавать ключи KeyMint с авторизациями, допустимыми в качестве параметров API, но при этом полученные ключи становятся небезопасными или непригодными к использованию. Реализации KeyMint не обязаны выдавать ошибку в таких случаях или диагностировать ошибку. Использование слишком маленьких ключей, указание нерелевантных входных параметров, повторное использование векторов инициализации (IV) или одноразовых значений (nonce), генерация ключей без назначения (и, следовательно, бесполезных) и тому подобное не должны диагностироваться реализациями.

Приложения, фреймворк и Android Keystore отвечают за то, чтобы вызовы модулей KeyMint были разумными и полезными.

точка входа addRngEntropy

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

Реализации KeyMint должны безопасно подмешивать предоставленную энтропию в свой пул, который также должен содержать внутреннюю энтропию, сгенерированную аппаратным генератором случайных чисел. Смешивание должно быть организовано таким образом, чтобы злоумышленник, имеющий полный контроль либо над битами, предоставленными addRngEntropy , либо над аппаратно сгенерированными битами (но не над обоими), не имел значительного преимущества в прогнозировании битов, сгенерированных из пула энтропии.

Ключевые характеристики

Каждый из механизмов ( generateKey , importKey и importWrappedKey ), создающих ключи KeyMint, возвращает характеристики вновь созданного ключа, разделенные соответствующим образом на уровни безопасности, которые обеспечивают реализацию каждой характеристики. Возвращаемые характеристики включают все параметры, указанные для создания ключа, за исключением Tag::APPLICATION_ID и Tag::APPLICATION_DATA . Если эти теги включены в параметры ключа, они удаляются из возвращаемых характеристик, так что невозможно найти их значения, проверив возвращенный ключевой блок. Однако они криптографически привязаны к ключевому блоку, так что если при использовании ключа не будут предоставлены правильные значения, использование ключа завершится ошибкой. Аналогично, Tag::ROOT_OF_TRUST криптографически привязан к ключу, но его нельзя указать во время создания или импорта ключа, и он никогда не возвращается.

В дополнение к предоставленным тегам реализация KeyMint также добавляет Tag::ORIGIN , указывающий способ создания ключа ( KeyOrigin::GENERATED , KeyOrigin::IMPORTED или KeyOrigin::SECURELY_IMPORTED ).

Сопротивление откату

Устойчивость к откату обозначается Tag::ROLLBACK_RESISTANCE и означает, что после удаления ключа с помощью deleteKey или deleteAllKeys защищенное оборудование гарантирует, что его больше никогда нельзя будет использовать.

Реализации KeyMint возвращают вызывающей стороне сгенерированный или импортированный ключевой материал в виде зашифрованного и аутентифицированного ключевого блока. Когда Keystore удаляет ключевой блок, ключ исчезает, но злоумышленник, которому ранее удалось получить ключевой материал, потенциально может восстановить его на устройстве.

Ключ устойчив к откату, если защищённое оборудование гарантирует невозможность последующего восстановления удалённых ключей. Обычно это достигается путём хранения дополнительных метаданных ключа в надёжном месте, которое недоступно злоумышленнику. На мобильных устройствах для этого обычно используются блоки памяти с защитой от повторного воспроизведения (RPMB). Поскольку количество создаваемых ключей практически неограниченно, а доверенное хранилище, используемое для защиты от отката, может быть ограничено по размеру, реализация может привести к сбою запросов на создание ключей, устойчивых к откату, при его заполнении.

начинать

Точка входа begin() начинает криптографическую операцию с использованием указанного ключа, для указанной цели и с указанными параметрами (при необходимости). Она возвращает новый объект Binder IKeyMintOperation , используемый для завершения операции. Кроме того, возвращается значение запроса, которое используется в составе токена аутентификации в аутентифицированных операциях.

Реализация KeyMint поддерживает не менее 16 одновременных операций. Keystore использует до 15, оставляя одну для vold для шифрования паролей. Когда Keystore выполняет 15 операций ( begin() был вызван, но finish или abort не был вызван) и получает запрос на запуск 16-й, он вызывает abort() для самой последней использованной операции, чтобы сократить количество активных операций до 14, прежде чем вызвать begin() для запуска новой запрошенной операции.

Если во время генерации или импорта ключа были указаны Tag::APPLICATION_ID или Tag::APPLICATION_DATA , вызовы begin() должны включать эти теги с первоначально указанными значениями в аргументе params этого метода.

Обработка ошибок

Если метод объекта IKeyMintOperation возвращает код ошибки, отличный от ErrorCode::OK , операция прерывается, а объект Binder операции становится недействительным. Любое последующее использование объекта возвращает ErrorCode::INVALID_OPERATION_HANDLE .

Обеспечение соблюдения авторизации

Проверка подлинности ключа выполняется в основном в begin() . Единственным исключением является случай, когда ключ имеет одно или несколько значений Tag::USER_SECURE_ID и не имеет значения Tag::AUTH_TIMEOUT .

В этом случае ключ требует авторизации для каждой операции, а методы update() или finish() получают токен авторизации в аргументе authToken . Чтобы гарантировать валидность токена, реализация KeyMint:

  • Проверяет подпись HMAC на токене авторизации.
  • Проверяет, содержит ли токен безопасный идентификатор пользователя, соответствующий идентификатору, связанному с ключом.
  • Проверяет, соответствует ли тип аутентификации токена Tag::USER_AUTH_TYPE ключа.
  • Проверяет, содержит ли токен значение вызова для текущей операции в поле вызова.

Если эти условия не выполняются, KeyMint возвращает ErrorCode::KEY_USER_NOT_AUTHENTICATED .

Вызывающий объект предоставляет токен аутентификации при каждом вызове update() и finish() . Реализация может проверить токен только один раз.