Keymaster 授权标记

本页提供了一些对 Keymaster HAL 实现人员很有帮助的详细信息。其中介绍了 HAL 中的每个标记、提供相应标记的 Keymaster 版本以及相应标记是否可重复使用。除非标记说明中另有注明,否则以下所有标记都会在密钥生成期间用于指定密钥特性。

对于 Keymaster 4,标记如 platform/hardware/interfaces/keymaster/keymaster-version/types.hal 中所定义,例如,3.0/types.hal(对于 Keymaster 3)和 4.0/types.hal(对于 Keymaster 4)。对于 Keymaster 2 及更低版本,标记如 platform/hardware/libhardware/include/hardware/keymaster_defs.h 中所定义。

如需了解具体函数,请参阅 Keymaster 函数页面。

Tag::ACTIVE_DATETIME

版本:1、2、3、4

是否可重复使用?否

用于指定相应密钥变为有效状态的日期和时间。在此之前,任何试图使用相应密钥的行为都会失败并显示 ErrorCode::KEY_NOT_YET_VALID

此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。

Tag::ALGORITHM

版本:1、2、3、4

是否可重复使用?否

用于指定与相应密钥配合使用的加密算法。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class Algorithm : uint32_t {
    RSA = 1,
    EC = 3,
    AES = 32,
    HMAC = 128,
};
Keymaster 2 及更低版本
typedef enum {
    KM_ALGORITHM_RSA = 1,
    KM_ALGORITHM_EC = 3,
    KM_ALGORITHM_AES = 32,
    KM_ALGORITHM_HMAC = 128,
} keymaster_algorithm_t;

Tag::ALL_APPLICATIONS

版本:1、2、3、4

是否可重复使用?否

预留以供日后使用。

Tag::ALLOW_WHILE_ON_BODY

版本:2、3、4

是否可重复使用?否

此标记仅适用于配有贴身传感器的 Android Wear 设备。目前预计任何 TEE 都无法提供对贴身传感器的安全访问,我们也无法保证贴身传感器非常安全,因此这是一项完全由软件强制执行的功能。

Tag::ALL_USERS

版本:3、4

是否可重复使用?否

预留以供日后使用。

Tag::APPLICATION_DATA

版本:1、2、3、4

是否可重复使用?否

如果将此标记提供给 generateKeyimportKey,则可指定使用相应密钥时所必需的数据。具体来说就是,调用 exportKeygetKeyCharacteristics 时需要为 clientId 参数提供相同的值,而调用 begin 时则需要提供此标记以及 inParams 集合中所包含的相同关联数据。如果未收到正确的数据,则该函数会返回 ErrorCode::INVALID_KEY_BLOB

此标记的内容“以加密形式”绑定到相应密钥。这意味着,如果攻击者有权访问安全域的所有机密内容,但无权访问此标记的内容,则他们只能对此标记的内容进行暴力破解攻击才能解密相应密钥,而应用可通过指定具有足够高熵的内容来防范这一行为。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::APPLICATION_ID

版本:1、2、3、4

是否可重复使用?否

如果将此标记提供给 generateKeyimportKey,则可指定使用相应密钥时所必需的数据。具体来说就是,调用 exportKeygetKeyCharacteristics 时需要为 clientId 参数提供相同的值,而调用 begin 时则需要提供此标记以及 inParams 集合中包含的相同关联数据。如果未收到正确的数据,则该函数会返回 ErrorCode::INVALID_KEY_BLOB

此标记的内容“以加密形式”绑定到相应密钥,这意味着,如果攻击者有权访问安全域的所有机密内容,但无权访问此标记的内容,则他们只能对此标记的内容进行暴力破解攻击才能解密相应密钥。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ASSOCIATED_DATA

版本:1、2、3、4

是否可重复使用?否

用于提供进行 AES-GCM 加密或解密时使用的“相关数据”。可以将此标记提供给 update,以便指定在计算 GCM 标记时使用的未加密/解密的数据。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_APPLICATION_ID

版本:3、4

是否可重复使用?否

用于识别已发起密钥认证的可能的应用集。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_CHALLENGE

版本:3、4

是否可重复使用?否

用于在认证时提供质询。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_BRAND

版本:3、4

是否可重复使用?否

提供设备的品牌名称,由 Android 中的 Build.BRAND 返回。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_DEVICE

版本:3、4

是否可重复使用?否

提供设备的设备名称,由 Android 中的 Build.DEVICE 返回。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_IMEI

版本:3、4

是否可重复使用?是

为设备上的所有无线装置提供 IMEI。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_MANUFACTURER

版本:3、4

是否可重复使用?否

提供设备的制造商名称,由 Android 中的 Build.MANUFACTURER 返回。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_MEID

版本:3、4

是否可重复使用?是

为设备上的所有无线装置提供 MEID。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_MODEL

版本:3、4

是否可重复使用?否

提供设备的型号名称,由 Android 中的 Build.MODEL 返回。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_PRODUCT

版本:3、4

是否可重复使用?否

提供设备的产品名称,由 Android 中的 Build.PRODUCT 返回。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::ATTESTATION_ID_SERIAL

版本:3、4

是否可重复使用?否

提供设备的序列号。仅在请求认证该设备的标识符时才会设置此字段。

如果该设备不支持 ID 认证(或者之前已调用 destroyAttestationIds() 且该设备无法再证明其 ID),则任何包含此标记的密钥认证请求都会失败并显示 ErrorCode::CANNOT_ATTEST_IDS

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::AUTH_TIMEOUT

版本:1、2、3、4

是否可重复使用?否

用于指定授权在多长时间内使用相应密钥(以秒数计,从通过身份验证开始算起)。如果 Tag::USER_SECURE_ID 存在而此标记不存在,那么每次使用相应密钥时都需要进行身份验证(如需详细了解按操作进行身份验证的流程,请参阅 begin)。

此标记的值是一个 32 位的整数,用于指定可在多长时间内使用相应密钥(以秒计,从使用由 Tag::USER_SECURE_ID 指定的身份验证方法对由 Tag::USER_AUTH_TYPE 指定的用户成功进行身份验证后开始算起)。

Tag::AUTH_TOKEN

版本:1、2、3、4

是否可重复使用?否

用于向 beginupdatefinish 提供finish,以便向要求用户通过身份验证的密钥操作(密钥带有 Tag::USER_SECURE_ID)证明相应用户已通过身份验证。

此标记的值是一个包含 hw_auth_token_t 结构的 Blob。

Tag::BLOB_USAGE_REQUIREMENTS

版本:1、2、3、4

是否可重复使用?否

指定要使用所生成的密钥必需的系统环境条件。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class KeyBlobUsageRequirements : uint32_t {
    STANDALONE = 0,
    REQUIRES_FILE_SYSTEM = 1,
};
Keymaster 2 及更低版本
typedef enum {
    KM_BLOB_STANDALONE = 0,
    KM_BLOB_REQUIRES_FILE_SYSTEM = 1,
} keymaster_key_blob_usage_requirements_t;

可以在密钥生成期间指定此标记,以便要求在指定条件下才可以使用生成的密钥。此标记需要随密钥特性一起从 generateKeygetKeyCharacteristics 返回。如果调用方指定了值为 KeyBlobUsageRequirements::STANDALONETag::BLOB_USAGE_REQUIREMENTS,则 Trustlet 会返回一个可在没有文件系统支持的情况下使用的密钥 Blob。这对于具有已加密磁盘的设备至关重要:在使用 Keymaster 密钥解密磁盘之前,此类设备的文件系统可能一直无法使用。

Tag::BLOCK_MODE

版本:1、2、3、4

是否可重复使用?是

指定可与相应密钥配合使用的分组加密模式。此标记仅与 AES 密钥有关。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class BlockMode : uint32_t {
    ECB = 1,
    CBC = 2,
    CTR = 3,
    GCM = 32,
};
Keymaster 2 及更低版本
typedef enum {
    KM_MODE_ECB = 1,
    KM_MODE_CBC = 2,
    KM_MODE_CTR = 3,
    KM_MODE_GCM = 32,
} keymaster_block_mode_t;

此标记可重复使用;对于 AES 密钥操作,请在 beginadditionalParams 参数中指定模式。 如果指定的模式不在相应密钥的关联模式之列,操作会失败并显示 ErrorCode::INCOMPATIBLE_BLOCK_MODE

Tag::BOOT_PATCHLEVEL

版本:4

Tag::BOOT_PATCHLEVEL 用于指定可与密钥配合使用的启动映像(内核)安全补丁程序级别。此标记一定不会发送至 keymaster TA,而是由 TA 添加到由硬件强制执行的授权列表中。任何试图将密钥与不同于当前运行的系统补丁程序级别的 Tag::BOOT_PATCHLEVEL 值配合使用的行为都会导致 begin()getKeyCharacteristics()exportKey() 返回 ErrorCode::KEY_REQUIRES_UPGRADE。如需了解详情,请参阅 upgradeKey()

该标记的值是形式为 YYYYMMDD 的整数,其中 YYYY 表示上次更新时间的四位数年份,MM 表示上次更新时间的两位数月份,DD 表示上次更新时间的两位数日期。例如,对于 Android 设备上生成的密钥,如果上次更新时间为 2018 年 6 月 5 日,则值将表示为 20180605。如果日期未知,则可以替换为 00。

在每次启动期间,引导加载程序都必须将启动映像的补丁程序级别提供给安全环境(相应机制是由实现定义的)。

必须由硬件强制执行。

Tag::BOOTLOADER_ONLY

版本:1、2、3、4

是否可重复使用?否

用于指定仅引导加载程序可以使用该密钥。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

任何试图从 Android 系统使用带有 Tag::BOOTLOADER_ONLY 标记的密钥的行为都会失败并显示 ErrorCode::INVALID_KEY_BLOB

Tag::CALLER_NONCE

版本:1、2、3、4

是否可重复使用?否

用于指定调用方可以为需要随机数的操作提供随机数。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

此标记仅用于 AES 密钥,并且仅与 CBC、CTR 和 GCM 分块模式有关。如果此标记不存在,则实现应拒绝执行任何向 begin 提供 Tag::NONCE 的操作并显示 ErrorCode::CALLER_NONCE_PROHIBITED

Tag::CREATION_DATETIME

版本:1、2、3、4

是否可重复使用?否

用于指定相应密钥的创建日期和时间(以距 1970 年 1 月 1 日的毫秒数计)。此标记为可选标记,仅供参考。

Tag::DIGEST

版本:1、2、3、4

是否可重复使用?是

用于指定可与相应密钥配合使用以执行签名和验证操作的摘要算法。此标记与 RSA 密钥、ECDSA 密钥和 HMAC 密钥有关。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class Digest : uint32_t {
    NONE = 0,
    MD5 = 1,
    SHA1 = 2,
    SHA_2_224 = 3,
    SHA_2_256 = 4,
    SHA_2_384 = 5,
    SHA_2_512 = 6,
};
Keymaster 2 及更低版本
typedef enum {
    KM_DIGEST_NONE = 0,
    KM_DIGEST_MD5 = 1,
    KM_DIGEST_SHA1 = 2,
    KM_DIGEST_SHA_2_224 = 3,
    KM_DIGEST_SHA_2_256 = 4,
    KM_DIGEST_SHA_2_384 = 5,
    KM_DIGEST_SHA_2_512 = 6,
}
keymaster_digest_t;

此标记可重复使用。如需执行签名和验证操作,请在 beginadditionalParams 参数中指定摘要。如果指定的摘要不在相应密钥的关联摘要之内,则操作会失败并显示 ErrorCode::INCOMPATIBLE_DIGEST

Tag::EC_CURVE

版本:2、3、4

是否可重复使用?否

在 Keymaster 1 中,用于 EC 密钥的曲线从指定密钥的大小推测而来。为了在今后提高灵活性,Keymaster 2 引入了一种明确的方法来指定曲线。EC 密钥生成请求可包含 Tag::EC_CURVE 和/或 Tag::KEY_SIZE

可能的值是通过以下枚举定义的:

Keymaster 3
enum class EcCurve : uint32_t {
    P_224 = 0,
    P_256 = 1,
    P_384 = 2,
    P_521 = 3,
};
Keymaster 2 及更低版本
enum class EcCurve : uint32_t {
    P_224 = 0,
    P_256 = 1,
    P_384 = 2,
P_521 = 3,
};

如果某个生成请求仅包含 Tag::KEY_SIZE,则回退到 Keymaster 1 逻辑,以选择相应的 NIST 曲线。

如果请求仅包含 Tag::EC_CURVE,则使用指定的曲线。对于 Keymaster 3 及更高版本,曲线如 EcCurve 中所定义。对于 Keymaster 2 及更低版本,曲线如 keymaster_ec_curve_t 中所定义。

如果请求同时包含两者,则使用 Tag::EC_CURVE 指定的曲线,并验证指定密钥的大小是否适合该曲线。否则返回 ErrorCode::INVALID_ARGUMENT

Tag::INCLUDE_UNIQUE_ID

版本:2、3、4

是否可重复使用?否

此标记在密钥生成期间指定,以指示所生成密钥的认证证书应包含一个范围限定于应用且受时间限制的设备唯一 ID(由 Tag::UNIQUE_ID 指定)。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

Tag::KEY_SIZE

版本:1、2、3、4

是否可重复使用?否

用于指定相应密钥的大小(以位数计,按适用于相应密钥算法的一般方式衡量)。例如,对于 RSA 密钥,Tag::KEY_SIZE 用于指定公开模数的大小。对于 AES 密钥,此标记可指定密钥资料的长度。

Tag::MAC_LENGTH

版本:1、2、3、4

是否可重复使用?否

用于提供 MAC 或 GCM 身份验证标记的请求长度(以位数计)。

此标记的值是 MAC 长度(以位数计)。这个值是 8 的倍数,并且不小于与相应密钥关联的 Tag::MIN_MAC_LENGTH 的值。

Tag::MAX_USES_PER_BOOT

版本:1、2、3、4

是否可重复使用?否

用于指定在两次系统重启之间可以使用相应密钥的最大次数。这是另一种限制密钥使用次数的机制。

该值是一个 32 位的整数,表示在每次系统启动后可以使用相应密钥的次数。

当有操作使用带有此标记的某个密钥时,与该密钥关联的计数器应在 begin 调用期间递增。当密钥计数器超出此标记的值后,所有尝试使用该密钥的后续操作都会失败并显示 ErrorCode::MAX_OPS_EXCEEDED,直到设备重启为止。这意味着 Trustlet 会为带有此标记的密钥维护一份使用次数计数器表格。由于 Keymaster 内存的大小通常有限制,因此该表格可以具有固定的最大大小,并且当该表格被占满时,如果有操作尝试使用带有此标记的密钥,Keymaster 可能会使这些操作失败。此表格需要容纳至少 16 个密钥。如果某项操作因该表格已满而失败,则 Keymaster 会返回 ErrorCode::TOO_MANY_OPERATIONS

Tag::MIN_MAC_LENGTH

版本:1、2、3、4

是否可重复使用?否

此标记适用于支持 GCM 模式的 HMAC 密钥和 AES 密钥,用于指定可通过相应密钥请求或验证的 MAC 的最小长度。

此标记的值是 MAC 的最小长度(以位数计)。这个值是 8 的倍数。对于 HMAC 密钥,这个值至少为 64。对于 GCM 密钥,这个值介于 96 到 128 之间。

Tag::MIN_SECONDS_BETWEEN_OPS

版本:1、2、3、4

是否可重复使用?否

用于指定至少间隔多长时间才能再次将密钥用于允许的操作。在不限制密钥使用次数可能会给暴力破解攻击以可乘之机的环境中,可以使用此标记来限制密钥的使用次数。

该值是一个 32 位的整数,表示允许的操作之间间隔的秒数。

在某项操作中使用带有此标记的密钥时,在 finishabort 调用期间将启动计时器。在计时器表明由 Tag::MIN_SECONDS_BETWEEN_OPS 指定的间隔时间已过去之前收到的所有 begin 调用都会失败并显示 ErrorCode::KEY_RATE_LIMIT_EXCEEDED。这意味着 Trustlet 会为带有此标记的密钥维护一份使用次数计数器表格。由于 Keymaster 内存的大小通常有限制,因此该表格可以具有固定的最大大小,并且当该表格被占满时,如果有操作尝试使用带有此标记的密钥,Keymaster 可能会使这些操作失败。该表格需要容纳至少 32 个使用中的密钥,而且当密钥最小使用间隔到期时,需要主动重复使用该表格中的位置。如果某项操作因该表格已满而失败,则 Keymaster 会返回 ErrorCode::TOO_MANY_OPERATIONS

Tag::NO_AUTH_REQUIRED

版本:1、2、3、4

是否可重复使用?否

用于指定无需进行身份验证即可使用相应密钥。此标记与 Tag::USER_SECURE_ID 互斥。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

Tag::NONCE

版本:1、2、3、4

是否可重复使用?否

提供或返回进行 AES GCM、CBC 或 CTR 加密/解密时使用的随机数或初始化矢量 (IV)。在加密和解密操作期间,可以将此标记提供给 begin。仅当相应密钥带有 Tag::CALLER_NONCE 时,才可以将此标记提供给 begin。如果此标记未提供,则 Keymaster 将随机生成适当的随机数或 IV 并通过 begin 予以返回。

该值是一个 Blob(任意长度的字节数组)。所允许的长度取决于具体模式:GCM Nonce 的长度为 12 个字节;CBC IV 和 CTR IV 的长度为 16 个字节。

Tag::ORIGIN

版本:1、2、3、4

是否可重复使用?否

用于指定相应密钥是在哪里创建的(如果知道)。在生成或导入密钥期间可以不指定此标记,但此标记必须要由 Trustlet 添加到密钥特性中。

Keymaster 3

可能的值如 android::hardware::keymaster::v3_0::KeyOrigin 中所定义:

enum class KeyOrigin : uint32_t {
    GENERATED = 0,
    DERIVED = 1,
    IMPORTED = 2,
    UNKNOWN = 3,
};
Keymaster 2 及更低版本

可能的值如 keymaster_origin_t 中所定义:

typedef enum {
    KM_ORIGIN_GENERATED = 0,
    KM_ORIGIN_IMPORTED = 2,
    KM_ORIGIN_UNKNOWN = 3,
} keymaster_key_origin_t

该值的完整含义不仅取决于值本身,还取决于值是位于由硬件强制执行的特性列表中,还是位于由软件强制执行的特性列表中。

GENERATED 表示相应密钥是由 Keymaster 生成的。 如果它位于由硬件强制执行的列表中,那么相应密钥是在安全的硬件中生成的,并且已永久绑定到硬件。如果它位于由软件强制执行的列表中,那么相应密钥是在 SoftKeymaster 中生成的,并且没有绑定到硬件。

DERIVED 表示相应密钥是在 Keymaster 内部派生的。很可能存在于设备之外。

IMPORTED 表示密钥是在 Keymaster 之外生成的,并且已导入 Keymaster 中。如果它位于由硬件强制执行的列表中,那么相应密钥已永久绑定到硬件,不过可能存在位于安全硬件之外的副本。如果它位于由软件强制执行的列表中,那么相应密钥已导入 SoftKeymaster 中,并且没有绑定到硬件。

UNKNOWN 应当仅出现在由硬件强制执行的列表中。它表示相应密钥已绑定到硬件,但不知道该密钥原本就是在安全的硬件中生成的,还是导入的。只有在使用 keymaster0 硬件模拟 keymaster1 服务时,才会出现这种情况。

Tag::ORIGINATION_EXPIRE_DATETIME

版本:1、2、3、4

是否可重复使用?否

指定相应密钥无法再用于进行签名和加密的过期日期和时间。在此之后,如果尝试使用向 begin 提供 KeyPurpose::SIGNKeyPurpose::ENCRYPT 的密钥,操作都会失败并显示 ErrorCode::KEY_EXPIRED

此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。

Tag::OS_PATCHLEVEL

版本:2、3、4

是否可重复使用?否

该标记一定不会发送至 keymaster TA,而是由 TA 添加到由硬件强制执行的授权列表中。

该标记的值是形式为 YYYYMM 的整数,其中 YYYY 表示上次更新时间的四位数年份,MM 表示上次更新时间的两位数月份。例如,对于 Android 设备上生成的密钥,如果上次更新时间为 2015 年 12 月的,则值将表示为 201512。

如果密钥的补丁级别与当前补丁级别不同,则该密钥不可用。尝试使用此类密钥会导致 begingetKeyCharacteristicsexportKey 返回 ErrorCode::KEY_REQUIRES_UPGRADE。如需了解详情,请参阅版本绑定

Tag::OS_VERSION

版本:2、3、4

是否可重复使用?否

该标记一定不会发送至 keymaster TA,而是由 TA 添加到由硬件强制执行的授权列表中。

该标记的值是形式为 MMmmss 的整数,其中 MM 表示主要版本号,mm 表示次要版本号,ss 表示子次要版本号。例如,对于在 Android 版本 4.0.3 上生成的密钥,其值将表示为 040003。

Tag::PADDING

版本:1、2、3、4

是否可重复使用?是

用于指定可与相应密钥配合使用的填充模式。此标记与 RSA 密钥和 AES 密钥有关。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class PaddingMode : uint32_t {
    NONE = 1,
    RSA_OAEP = 2,
    RSA_PSS = 3,
    RSA_PKCS1_1_5_ENCRYPT = 4,
    RSA_PKCS1_1_5_SIGN = 5,
    PKCS7 = 64,
};
Keymaster 2 及更低版本
typedef enum {
    KM_PAD_NONE = 1,
    KM_PAD_RSA_OAEP = 2,
    KM_PAD_RSA_PSS = 3,
    KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4,
    KM_PAD_RSA_PKCS1_1_5_SIGN = 5,
    KM_PAD_PKCS7 = 64,
} keymaster_padding_t;

PaddingMode::RSA_OAEPPaddingMode::RSA_PKCS1_1_5_ENCRYPT 仅用于 RSA 加密/解密密钥,分别用来指定 RSA PKCS#1v2 OAEP 填充和 RSA PKCS#1 v1.5 随机填充。PaddingMode::RSA_PSSPaddingMode::RSA_PKCS1_1_5_SIGN 仅用于 RSA 签名/验证密钥,分别用来指定 RSA PKCS#1v2 PSS 填充和 RSA PKCS#1 v1.5 确定性填充。

PaddingMode::NONE 可与 RSA 密钥或 AES 密钥配合使用。对于 AES 密钥,如果将 PaddingMode::NONE 与分块模式 ECB 或 CBC 配合使用,并且要加密或解密的数据的长度不是 AES 分块大小的倍数,则调用 finish 的操作肯定会失败并显示 ErrorCode::INVALID_INPUT_LENGTH

PaddingMode::PKCS7 只能与 AES 密钥以及 ECB 和 CBC 模式配合使用。

此标记可重复使用。在调用 begin 时必须指定填充模式。如果指定的模式未针对相应密钥获得授权,操作会失败并显示 ErrorCode::INCOMPATIBLE_BLOCK_MODE

Tag::PURPOSE

版本:1、2、3、4

是否可重复使用?是

指定相应密钥可用于哪些目的。

可能的值是通过以下枚举定义的:

Keymaster 3
enum class KeyPurpose : uint32_t {
    ENCRYPT = 0,
    DECRYPT = 1,
    SIGN = 2,
    VERIFY = 3,
    DERIVE_KEY = 4,  // since 3.0
    WRAP_KEY = 5,    // since 3.0
};
Keymaster 2 及更低版本
typedef enum {
    KM_PURPOSE_ENCRYPT = 0,
    KM_PURPOSE_DECRYPT = 1,
    KM_PURPOSE_SIGN = 2,
    KM_PURPOSE_VERIFY = 3,
} keymaster_purpose_t;

此标记可重复使用。可以生成具有多个值的密钥,但是一项操作只有一个目的。当调用 begin 函数来启动某项操作时,需要指定操作的目的。如果为操作指定的目的未通过相应密钥授权,则操作会失败并显示 ErrorCode::INCOMPATIBLE_PURPOSE

Tag::RESET_SINCE_ID_ROTATION

版本:3、4

是否可重复使用?否

指定设备自上次唯一 ID 交替以来是否已恢复出厂设置。用于密钥认证。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

Tag::ROLLBACK_RESISTANT

版本:1、2、3、4

是否可重复使用?否

表明密钥可抗回滚,也就是说,当通过 deleteKeydeleteAllKeys 删除密钥后,可保证该密钥已被永久删除且无法再使用。如果密钥不带此标记,那么在被删除后,可能能够从备份中恢复。

此标记为布尔值,因此可能的值为 true(如果此标记存在)和 false(如果此标记不存在)。

Tag::ROOT_OF_TRUST

版本:1、2、3、4

是否可重复使用?否

指定“信任根”,即经过验证的启动程序在验证操作系统是否已启动时使用的密钥(如果有)。在任何情况下,都不可以通过密钥特性将此标记提供给 Keymaster,也不可以通过密钥特性从 Keymaster 返回此标记。

Tag::RSA_PUBLIC_EXPONENT

版本:1、2、3、4

是否可重复使用?否

为 RSA 密钥对指定公开指数的值。此标记仅与 RSA 密钥有关,而且是所有 RSA 密钥都必需的标记。

此标记的值是一个 64 位的未签名整数,并且符合 RSA 公开指数方面的要求。此值必须是质数。Trustlet 支持 2^16+1 这个值,并且可以支持其他合理的值,尤其是 3。如果未指定指数或指定的指数不受支持,密钥生成操作会失败并显示 ErrorCode::INVALID_ARGUMENT

Tag::UNIQUE_ID

版本:3、4

是否可重复使用?否

用于在认证时提供唯一 ID。

此标记的值是一个 Blob(任意长度的字节数组)。

Tag::USAGE_EXPIRE_DATETIME

版本:1、2、3、4

是否可重复使用?否

指定相应密钥无法再用于进行验证和解密的过期日期和时间。在此之后,如果尝试使用向 begin 提供 KeyPurpose::VERIFYKeyPurpose::DECRYPT 的密钥,操作都会失败并显示 ErrorCode::KEY_EXPIRED

此标记的值是一个 64 位的整数,表示距 1970 年 1 月 1 日的毫秒数。

Tag::USER_AUTH_TYPE

版本:1、2、3、4

是否可重复使用?否

用于指定可以使用哪些类型的用户身份验证程序来授权使用相应密钥。请求 Keymaster 使用包含此标记的密钥执行某项操作时,需要为 Keymaster 提供一个身份验证令牌,并且该令牌的 authenticator_type 字段需与此标记中的值一致。例如,(ntoh(token.authenticator_type) & auth_type_tag_value) != 0 必须为 true,其中 ntoh 是一个函数,用于将按网络字节序保存的整数转换成按主机字节序保存的整数,而 auth_type_tag_value 是此标记的值。

该值是以下枚举值的位掩码(32 位整数):

Keymaster 3
enum class HardwareAuthenticatorType : uint32_t {
    NONE = 0u, // 0
    PASSWORD = 1 << 0,
    FINGERPRINT = 1 << 1,
    ANY = UINT32_MAX,
};
Keymaster 2 及更低版本
typedef enum {
    HW_AUTH_NONE = 0,
    HW_AUTH_PASSWORD = 1 << 0,
    HW_AUTH_FINGERPRINT = 1 << 1,
    // Additional entries should be powers of 2.
    HW_AUTH_ANY = UINT32_MAX,
} hw_authenticator_type_t;

Tag::USER_SECURE_ID

版本:1、2、3、4

是否可重复使用?否

用于指定只能在某个安全的用户身份验证状态下使用相应密钥。此标记与 Tag::NO_AUTH_REQUIRED 互斥。

该值是一个 64 位整数,用于指定在身份验证令牌(通过 Tag::AUTH_TOKEN 提供给 Tag::AUTH_TOKEN)中必须存在的身份验证政策状态值,以用于授权使用相应密钥。如果在使用包含此标记的密钥调用 begin 时未提供身份验证令牌,或提供的身份验证令牌没有匹配的政策状态值,则该调用失败。

此标记可重复使用。如果提供的值中有任何一个值与身份验证令牌中的任何政策状态值匹配,则会授权使用相应密钥。否则,操作会失败并显示 ErrorCode::KEY_USER_NOT_AUTHENTICATED

Tag::VENDOR_PATCHLEVEL

版本:4

此标记用于指定可与秘钥配合使用的供应商映像安全补丁程序级别。此标记一定不会发送至 keymaster TA,而是由 TA 添加到由硬件强制执行的授权列表中。任何试图将密钥与不同于当前运行的系统补丁程序级别的 Tag::VENDOR_PATCHLEVEL 值配合使用的行为肯定都会导致 begin()getKeyCharacteristics()exportKey() 返回 ErrorCode::KEY_REQUIRES_UPGRADE。如需了解详情,请参阅 upgradeKey()

该标记的值是形式为 YYYYMMDD 的整数,其中 YYYY 表示上次更新时间的四位数年份,MM 表示上次更新时间的两位数月份,DD 表示上次更新时间的两位数日期。例如,对于 Android 设备上生成的密钥,如果上次更新时间为 2018 年 6 月 5 日,则值将表示为 20180605。

IKeymasterDevice HAL 必须从系统属性 ro.vendor.build.security_patch 读取当前供应商补丁级别,并在 HAL 首次加载时将其传递给安全环境(机制由实现进行定义)。在下次启动完成前,安全环境不得接受其他补丁级别。

必须由硬件强制执行。