Подтверждение ключа и идентификатора

Хранилище ключей обеспечивает более безопасное место для создания, хранения и использо��ания криптографических ключей контролируемым образом. Когда аппаратное хранилище ключей доступно и используется, материал ключа более защищен от извлечения из устройства, а Keymaster применяет ограничения, которые трудно обойти.

Однако это верно только в том случае, если известно, что ключи хранилища находятся в аппаратном хранилище. В Keymaster 1 у приложений или удаленных серверов не было возможности надежно проверить, так ли это. Демон хранилища ключей загрузил доступный мастер ключей HAL и верил всему, что говорил HAL в отношении аппаратной поддержки ключей.

Чтобы исправить это, Keymaster ввелаттестацию ключа в Android 7.0 (Keymaster 2) и аттестацию идентификатора в Android 8.0 (Keymaster 3).

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

Аттестация идентификатора позволяет устройству предоставить подтверждение своих аппаратных идентификаторов, таких как серийный номер или IMEI.

Ключевая аттестация

Для поддержки аттестации ключей в Android 7.1 в HAL появился набор тегов, типов и методов.

Теги

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Тип

Ключник 2 и ниже

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Метод AttestKey

Ключник 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Ключник 2 и ниже

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev — это структура устройства keymaster.
  • keyToAttest — это большой двоичный объект ключа, возвращаемый функцией generateKey для которого будет создана аттестация.
  • attestParams — это список любых параметров, необходимых для аттестации. Сюда входят Tag::ATTESTATION_CHALLENGE и, возможно, Tag::RESET_SINCE_ID_ROTATION , а также Tag::APPLICATION_ID и Tag::APPLICATION_DATA . Последние два необходимы для расшифровки большого двоичного объекта ключа, если они были указаны при генерации ключа.
  • certChain — это выходной параметр, который возвращает массив сертификатов. Запись 0 — это сертификат аттестации, то есть он удостоверяет ключ из keyToAttest и содержит расширение аттестации.

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

Свидетельство об аттестации

Сертификат аттестации — это стандартный сертификат X.509 с необязательным расширением аттестации, которое содержит описание аттестованного ключа. Сертификат подписывается заводским ключом подтверждения , в котором используется тот же алгоритм, что и в проверяемом ключе (RSA для RSA, EC для EC).

Сертификат аттестации содержит поля, указанные в таблице ниже, и не может содержать никаких дополнительных полей. В некоторых полях указывается фиксиров��нное значение поля. Тесты CTS подтверждают, что содержимое сертификата точно соответствует заданному.

ПОСЛЕДОВАТЕЛЬНОСТЬ сертификата

Имя поля (см. RFC 5280 ) Стоимость
tbsСертификат TBSCertificate ПОСЛЕДОВАТЕЛЬНОСТЬ
подписьАлгоритм AlgorithmIdentifier алгоритма, используемого для подписи ключа:
ECDSA для ключей EC, RSA для ключей RSA.
подписьЗначение БИТОВАЯ СТРОКА, подпись, вычисленная для tbsCertificate в кодировке ASN.1 DER.

TBSCertificate ПОСЛЕДОВАТЕЛЬНОСТЬ

Имя поля (см. RFC 5280 ) Стоимость
version INTEGER 2 (означает сертификат v3)
serialNumber INTEGER 1 (фиксированное значение: одинаково для всех сертификатов)
signature AlgorithmIdentifier алгоритма, используемого для подписи ключа: ECDSA для ключей EC, RSA для ключей RSA.
issuer То же, что и поле темы ключа пакетной аттестации.
validity ПОСЛЕДОВАТЕЛЬНОСТЬ двух дат, содержащая значения Tag::ACTIVE_DATETIME и Tag::USAGE_EXPIRE_DATETIME . Эти значения указаны в миллисекундах с 1 января 1970 года. См. RFC 5280 для правильного представления даты в сертификатах.
Если Tag::ACTIVE_DATETIME отсутствует, используйте значение Tag::CREATION_DATETIME . Если Tag::USAGE_EXPIRE_DATETIME отсутствует, используйте дату истечения срока действия сертификата ключа пакетной аттестации.
subject CN = «Ключ хранилища ключей Android» (фиксированное значение: одинаково для всех сертификатов)
subjectPublicKeyInfo SubjectPublicKeyInfo, содержащий аттестованный открытый ключ.
extensions/Key Usage digitalSignature: устанавливается, если ключ имеет назначение KeyPurpose::SIGN или KeyPurpose::VERIFY . Все остальные биты не установлены.
extensions/CRL Distribution Points Значение подлежит уточнению
extensions/"attestation" OID: 1.3.6.1.4.1.11129.2.1.17; содержание определено в разделе «Расширение аттестации» ниже. Как и во всех расширениях сертификата X.509, содержимое предста��лен�� как OCTET_STRING, содержащее кодировку DER ПОСЛЕДОВАТЕЛЬНОСТИ аттестации.

Расширение аттестации

Расширение attestation содержит полное описание авторизаций мастеров ключей, связанных с ключом, в структуре, которая напрямую соответствует спискам авторизации, используемым в Android, и мастеру ключей HAL. Каждый тег в списке авторизации представлен записью SEQUENCE ASN.1, явно помеченной номером тега мастера ключей, но с замаскированным дескриптором типа (четыре старших бита).

Например, в Keymaster 3 Tag::PURPOSE PURPOSE определяется в types.hal как ENUM_REP | 1 . Для расширения аттестации значение ENUM_REP удаляется, оставляя тег 1 . (Для Keymaster 2 и ниже KM_TAG_PURPOSE определяется в keymaster_defs.h.)

Значения напрямую переводятся в типы ASN.1 в соответствии с этой таблицей:

Тип мастера ключей Тип АСН.1
ENUM ЦЕЛОЕ ЧИСЛО
ENUM_REP НАБОР ЦЕЛЫХ
UINT ЦЕЛОЕ ЧИСЛО
UINT_REP НАБОР ЦЕЛЫХ
ULONG ЦЕЛОЕ ЧИСЛО
ULONG_REP НАБОР ЦЕЛЫХ
DATE INTEGER (миллисекунды с 1 января 1970 г. 00:00:00 по Гринвичу)
BOOL NULL (в мастере ключей присутствие тега означает истину, отсутствие означает ложь.
Та же семантика применяется к кодировке ASN.1)
BIGNUM В настоящее время не используется, поэтому сопоставление не определено
BYTES OCTET_STRING

Схема

Содержимое расширения аттестации описывается следующей схемой ASN.1.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Поля KeyDescription

Поля keymasterVersion и attestationChallenge идентифицируются позиционно, а не по тегу, поэтому теги в закодированной форме определяют только тип поля. Остальные поля неявно помечены, как указано в схеме.

Имя поля Тип Стоимость
attestationVersion ЦЕЛОЕ ЧИСЛО Версия схемы аттестации: 1, 2 или 3.
attestationSecurity Уровень безопасности Уровень безопасности этой аттестации. Можно получить программную аттестацию аппаратных ключей. Таким аттестациям нельзя доверять, если система Android скомпрометирована.
keymasterVersion ЦЕЛОЕ ЧИСЛО Версия ключевого устройства: 0, 1, 2, 3 или 4.
keymasterSecurity Уровень безопасности Уровень безопасности реализации мастера ключей.
attestationChallenge OCTET_STRING Значение Tag::ATTESTATION_CHALLENGE , указанное в запросе на аттестацию.
uniqueId OCTET_STRING Необязательный уникальный идентификатор, присутствует, если у ключа есть Tag::INCLUDE_UNIQUE_ID
softwareEnforced Список ��вторизации Необязательные авторизации ключей, которые не применяются TEE, если таковые имеются.
teeEnforced Список авторизации Необязательные, авторизации Keymaster, которые применяются TEE, если таковые имеются.

Поля AuthorizationList

Все поля AuthorizationList являются необязательными и идентифицируются по значению тега keymaster, а биты типа замаскированы. Используется явная маркировка, поэтому поля также содержат метку, указывающую их тип ASN.1, для облегчения синтаксического анализа.

Подробнее о значениях каждого поля см. в types.hal для Keymaster 3 и keymaster_defs.h для Keymaster 2 и ниже. Имена тегов мастеров ключей были преобразованы в имена полей путем опускания префикса KM_TAG и изменения остатка на верблюжий регистр, поэтому Tag::KEY_SIZE стал keySize .

Поля RootOfTrust

Поля RootOfTrust идентифицируются позиционно.

Имя поля Тип Стоимость
verifiedBootKey OCTET_STRING Защищенный хэш ключа, используемого для проверки образа системы. Рекомендуется SHA-256.
deviceLocked логическое значение Истинно, если загрузчик заблокирован, что означает, что можно прошивать только подписанные образы и выполняется проверенная проверка загрузки.
verifiedBootState ВерифицированоBootState Состояние проверенной загрузки.
verifiedBootHash OCTET_STRING Дайджест всех данных, защищенных Verified Boot. Для устройств, использующих реализацию Verified Boot для Android Verified Boot, это значение содержит дайджест структуры VBMeta или структуру метаданных Verified Boot. Чтобы узнать больше о том, как вычислить это значение, см . Дайджест VBMeta.

Значения VerifiedBootState

Значения verifiedBootState имеют следующие значения:

Стоимость Имея в виду
Verified Указывает полную цепочку доверия, простирающуюся от загрузчика до проверенных разделов, включая загрузчик, загрузочный раздел и все проверенные разделы.
В этом состоянии значение verifiedBootKey представляет собой хэш встроенного се��тифика��а, ��о есть н��изменяемый сертификат, записанный в ПЗУ.
SelfSigned Указывает, что загрузочный раздел был проверен с использованием встроенного сертификата, и подпись действительна. Загрузчик отображает предупреждение и отпечаток открытого ключа, прежде чем продолжить процесс загрузки.
В этом состоянии значение verifiedBootKey является хэшем самозаверяющего сертификата.
Unverified Указывает, что устройство можно свободно модифицировать. Целостность устройства предоставляется пользователю для внеполосной проверки. Загрузчик отображает предупреждение пользователю, прежде чем продолжить процесс загрузки.
В этом состоянии значение verifiedBootKey пусто.
Failed Указывает, что устройство не прошло проверку. На самом деле ни один сертификат аттестации не содержит этого значения, потому что в этом состоянии загрузчик останавливается. Он включен здесь для полноты картины.

Значения SecurityLevel

Значения securityLevel имеют следующие значения:

Стоимость Имея в виду
Software Код, который создает соответствующий элемент (аттестацию или ключ) или управляет им, реализован в системе Android и может быть изменен в случае взлома этой системы.
TrustedEnvironment Код, который создает соответствующий элемент (аттестацию или ключ) или управляет им, реализован в доверенной среде выполнения (TEE). Он может быть изменен, если TEE скомпрометирован, но TEE обладает высокой устойчивостью к удаленной компрометации и умеренной устойчивостью к компрометации путем прямой аппаратной атаки.
StrongBox Код, создающий соответствующий элемент (аттестацию или ключ) или управляющий им, реализован в специальном аппаратном модуле безопасности. Он может быть изменен, если аппаратный модуль безопасности скомпрометирован, но он очень устойчив к удаленному взлому и очень устойчив к компрометации при прямой атаке на оборудование.

Уникальный идентификатор

Уникальный идентификатор — это 128-битное значение, которое идентифицирует устройство, но только в течение ограниченного периода времени. Значение вычисляется с помощью:

HMAC_SHA256(T || C || R, HBK)

Где:

  • T — это «значение временного счетчика», вычисленное путем деления значения Tag::CREATION_DATETIME на 2592000000 с отбрасыванием остатка. T меняется каждые 30 дней (2592000000 = 30*24*60*60*1000).
  • C — это значение Tag::APPLICATION_ID .
  • R равно 1, если Tag::RESET_SINCE_ID_ROTATION присутствует в параметре attest_params для вызова attest_key, или 0, если тег отсутствует.
  • HBK — это уникальный аппаратный секрет, известный Trusted Execution Environment и никогда им не раскрываемый. Секрет содержит не менее 128 бит энтропии и уникален для отдельного устройства (вероятностная уникальность приемлема, учитывая 128 бит энтропии). HBK должен быть получен из материала объединенного ключа через HMAC или AES_CMAC.

Сократите выходные данные HMAC_SHA256 до 128 бит.

Ключи аттестации и сертификаты

Два ключа, один RSA и один ECDSA, а также соответствующие цепочки сертификатов защищены на устройстве.

удостоверение личности

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

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

Основная поверхность API для аттестации идентификаторов строится на основе существующего механизма аттестации ключей, предст��вленного в Keymaster 2. При запросе сертификата аттестации для ключа, которым владеет мастер ключей, вызывающая сторона может запросить включение аппаратных идентификаторов устройства в метаданные сертификата аттестации. Если ключ хранится в TEE, сертификат будет привязан к известному корню доверия. Получатель такого сертификата может проверить, что сертификат и его содержимое, включая идентификаторы оборудования, были написаны TEE. При запросе на включение идентификаторов оборудования в сертификат аттестации TEE подтверждает только те идентификаторы, которые хранятся в его хранилище и заполняются на заводе.

Свойства хранилища

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

  • Значения, полученные из исходных идентификаторов устройства, копируются в хранилище до того, как устройство покинет завод.
  • Метод destroyAttestationIds() может безвозвратно уничтожить эту копию данных, полученных из идентификатора. Безвозвратное уничтожение означает, что данные полностью удаляются, поэтому ни сброс к заводским настройкам, ни какие-либо другие процедуры, выполняемые на устройстве, не могут их восстановить. Это особенно важно для устройств, на которых пользователь разблокировал загрузчик и изменил системное программное обеспечение, а также изменил идентификаторы, возвращаемые платформами Android.
  • Средства RMA должны иметь возможность генерировать новые копии данных, полученных на основе идентификатора оборудования. Таким образом, устройство, прошедшее RMA, может снова выполнить аттестацию идентификатора. Механизм, используемый средствами RMA, должен быть защищен таким образом, чтобы пользователи не могли использовать его сами, поскольку это позволит им получить подтверждения поддельных идентификаторов.
  • Ни один код, кроме доверенного приложения Keymaster в TEE, не может считывать данные, полученные от идентификатора, хранящиеся в хранилище.
  • Хранилище защищено от несанкционированного доступа: если содержимое хранилища было изменено, TEE обрабатывает его так же, как если бы копии содержимого были уничтожены, и отклоняет все попытки аттестации идентификатора. Это реализуется путем подписания или MAC-адресации хранилища , как описано ниже .
  • Хранилище не содержит исходных идентификаторов. Поскольку аттестация идентификатора включает в себя вызов, вызывающая сторона всег��а предоставляет идентификаторы для аттестации. TEE нужно только убедиться, что они соответствуют значениям, которые у них были изначально. Хранение безопасных хэшей исходных значений, а не значений, позволяет эту проверку.

Строительство

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

S = D || HMAC(HBK, D)

куда:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC — это конструкция HMAC с соответствующим безопасным хэшем (рекомендуется SHA-256).
  • HBK — это аппаратный ключ, не используемый ни для каких других целей.
  • ID 1 ...ID n — исходные значения ID; связь определенного значения с конкретным индексом зависит от реализации, поскольку разные устройства будут иметь разное количество идентификаторов.
  • || представляет конкатенацию

Поскольку выходные данные HMAC имеют фиксированный размер, для поиска отдельных хэшей идентификаторов или HMAC для D не требуются заголовки или другая структура. , вычисляя HMAC(HBK, D) и сравнивая его со значением в S, чтобы убедиться, что отдельные идентификаторы не были изменены/повреждены. Кроме того, реализации должны использовать сравнения с постоянным временем для всех отдельных элементов идентификатора и проверку S. Время сравнения должно быть постоянным независимо от количества предоставленных идентификаторов и правильного сопоставления любой части теста.

Идентификаторы оборудования

Аттестация ID поддерживает следующие аппаратные идентификаторы:

  1. Название бренда, возвращенное Build.BRAND в Android.
  2. Имя устройства, возвращаемое Build.DEVICE в Android
  3. Название продукта, возвращаемое Build.PRODUCT в Android
  4. Название производителя, возвращенное Build.MANUFACTURER в Android.
  5. Название модели, возвращаемое Build.MODEL в Android
  6. Серийный номер
  7. IMEI всех радиостанций
  8. MEID всех радиостанций

Чтобы поддерживать аттестацию идентификатора устройства, устройство аттестует эти идентификаторы. Все устройства под управлением Android имеют первые шесть, и они необходимы для работы этой функции. Если устройство имеет какие-либо встроенные сотовые радиостанции, устройство также должно поддерживать аттестацию IMEI и/или MEID радиостанций.

Аттестация идентификатора запрашивается путем выполнения аттестации ключа и включения идентификаторов устройств для аттестации в запрос. Идентификаторы помечены как:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

Идентификатор для подтверждения представляет собой строку байтов в кодировке UTF-8. Этот формат также применяется к числовым идентификаторам. Каждый подтверждаемый идентификатор выражается в виде строки в кодировке UTF-8.

Если устройство не поддерживает аттестацию идентификатора (или destroyAttestationIds() , и устройство больше не может аттестовать свои идентификаторы), любой запрос на аттестацию ключа, включающий один или несколько из этих тегов, завершается ошибкой с ErrorCode::CANNOT_ATTEST_IDS .

Если устройство поддерживает аттестацию идентификатора и один или несколько из вышеперечисленных тегов были включены в запрос на аттестацию ключа, TEE проверяет идентификатор, предоставленный с каждым из тегов, на соответствие его копии аппаратных идентификаторов. Если один или несколько идентификаторов не совпадают, вся аттестация завершается с ошибкой ErrorCode::CANNOT_ATTEST_IDS . Один и тот же тег может использоваться несколько раз. Это может быть полезно, например, при аттестации IMEI: устройство может иметь несколько радиомодулей с несколькими IMEI. Запрос на аттестацию действителен, если значение, предоставленное с каждым ATTESTATION_ID_IMEI , соответствует одному из радиомодулей устройства. То же самое относится и ко всем другим тегам.

Если аттестация прошла успешно, аттестованные идентификаторы добавляются к расширению аттестации (OID 1.3.6.1.4.1.11129.2.1.17) выданного сертификата аттестации с использованием приведенной выше схемы . Изменения схемы аттестации Keymaster 2 выделены полужирным шрифтом с комментариями.

Java-API

Этот раздел носит только информационный характер. Разработчики Keymaster не реализуют и не используют Java API. Это предоставляется, чтобы помочь разработчикам понять, как эта функция используется приложениями. Системные компоненты могут использовать его по-разному, поэтому крайне важно, чтобы этот раздел не рассматривался как нормативный.