Keymaster 授权标记

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

对于 Keymaster 3,标记在 platform/hardware/interfaces/keymaster/3.0/types.hal 中定义。对于 Keymaster 2 及更低版本,标记在 hardware/libhardware/include/hardware/keymaster_defs.h 中定义。

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

为了支持 Keymaster 3 从旧式 C 结构 HAL 转换到从新的硬件接口定义语言 (HIDL) 中的定义生成的 C++ HAL 接口,Android 8.0 中的标记名称已更改。如同所有其他 keymaster 枚举一样,标记现在被定义为范围限定为 C++ 的枚举。例如,之前标记带有 KM_TAG_ 前缀,而现在带有 Tag:: 前缀。

Tag::ACTIVE_DATETIME

版本:1、2、3

是否可重复使用?否

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

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

Tag::ALGORITHM

版本:1、2、3

是否可重复使用?否

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

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

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

是否可重复使用?否

预留以供日后使用。

Tag::ALLOW_WHILE_ON_BODY

版本:2、3

是否可重复使用?否

此标记仅适用于配备贴身传感器的 Android Wear 设备。目前,并非所有 TEE 都能提供对贴身传感器的安全访问权限,或贴身传感器非常安全,因此这应该是一项完全由软件强制执行的功能。

Tag::ALL_USERS

版本:3

是否可重复使用?否

预留以供日后使用。

Tag::APPLICATION_DATA

版本:1、2、3

是否可重复使用?否

当提供给 generateKeyimportKey 时,此标记用于指定使用相应密钥时必需的数据。具体来说就是,调用 exportKeygetKeyCharacteristics 时需要在 clientId 参数中提供相同的值,而调用 begin 时则需要提供此标记以及相同的相关数据(作为 inParams 集的一部分)。如果未收到正确的数据,则该函数会返回 ErrorCode::INVALID_KEY_BLOB

此标记的内容以加密形式绑定到相应密钥,这意味着,如果有不轨人士有权访问安全域的所有机密内容,但无权访问此标记的内容,必须要确保他们在不对此标记的内容进行暴力破解攻击的情况下无法解密相应密钥,应用可通过指定足够的高熵内容来防范这一行为。

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

Tag::APPLICATION_ID

版本:1、2、3

是否可重复使用?否

当提供给 generateKeyimportKey 时,此标记用于指定使用相应密钥时必需的数据。具体来说就是,调用 exportKeygetKeyCharacteristics 时需要在 clientId 参数中提供相同的值,而调用 begin 时则需要提供此标记以及相同的相关数据(作为 inParams 集的一部分)。如果未收到正确的数据,则该函数会返回 ErrorCode::INVALID_KEY_BLOB

此标记的内容以加密形式绑定到相应密钥,这意味着,如果有不轨人士有权访问安全域的所有机密内容,但无权访问此标记的内容,必须要确保他们无法解密相应密钥(在不对此标记的内容进行暴力破解攻击的情况下)。

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

Tag::ASSOCIATED_DATA

版本:1、2、3

是否可重复使用?否

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

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

Tag::ATTESTATION_APPLICATION_ID

版本:3

是否可重复使用?否

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

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

Tag::ATTESTATION_CHALLENGE

版本:3

是否可重复使用?否

用于在认证时提供质询。

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

Tag::ATTESTATION_ID_BRAND

版本:3

是否可重复使用?否

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

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

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

Tag::ATTESTATION_ID_DEVICE

版本:3

是否可重复使用?否

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

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

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

Tag::ATTESTATION_ID_IMEI

版本:3

是否可重复使用?是

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

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

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

Tag::ATTESTATION_ID_MANUFACTURER

版本:3

是否可重复使用?否

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

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

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

Tag::ATTESTATION_ID_MEID

版本:3

是否可重复使用?是

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

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

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

Tag::ATTESTATION_ID_MODEL

版本:3

是否可重复使用?否

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

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

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

Tag::ATTESTATION_ID_PRODUCT

版本:3

是否可重复使用?否

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

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

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

Tag::ATTESTATION_ID_SERIAL

版本:3

是否可重复使用?否

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

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

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

Tag::AUTH_TIMEOUT

版本:1、2、3

是否可重复使用?否

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

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

Tag::AUTH_TOKEN

版本:1、2、3

是否可重复使用?否

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

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

Tag::BLOB_USAGE_REQUIREMENTS

版本:1、2、3

是否可重复使用?否

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

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

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

是否可重复使用?是

用于指定可与相应密钥配合使用的分块加密模式。 此标记仅与 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::BOOTLOADER_ONLY

版本:1、2、3

是否可重复使用?否

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

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

尝试从 Android 系统使用带有 Tag::BOOTLOADER_ONLY 标记的密钥时,操作会失败并显示 ErrorCode::INVALID_KEY_BLOB

Tag::CALLER_NONCE

版本:1、2、3

是否可重复使用?否

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

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

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

Tag::CREATION_DATETIME

版本:1、2、3

是否可重复使用?否

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

Tag::DIGEST

版本:1、2、3

是否可重复使用?是

用于指定可与相应密钥配合使用以执行签名和验证操作的摘要算法。此标记与 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

是否可重复使用?否

在 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

是否可重复使用?否

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

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

Tag::KEY_SIZE

版本:1、2、3

是否可重复使用?否

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

在 Keymaster 2 及更高版本中,Tag::KEY_SIZE 不再是选择 ECC(椭圆曲线加密)曲线的首选机制。 虽然其他密钥类型不变,但使用标记 Tag::EC_CURVE 选择 ECC 曲线。

Tag::MAC_LENGTH

版本:1、2、3

是否可重复使用?否

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

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

Tag::MAX_USES_PER_BOOT

版本:1、2、3

是否可重复使用?否

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

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

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

Tag::MIN_MAC_LENGTH

版本:1、2、3

是否可重复使用?否

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

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

Tag::MIN_SECONDS_BETWEEN_OPS

版本:1、2、3

是否可重复使用?否

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

此标记的值是一个 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

是否可重复使用?否

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

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

Tag::NONCE

版本:1、2、3

是否可重复使用?否

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

此标记的值是一个 Blob(任意长度的字节数数组)。所允许的长度取决于模式:GCM 随机数的长度为 12 个字节;CBC IV 和 CTR IV 的长度为 16 个字节。

Tag::ORIGIN

版本:1、2、3

是否可重复使用?否

用于指定相应密钥是在哪里创建的(如果知道)。在生成或导入密钥期间可以不指定此标记,但此标记必须要由 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

是否可重复使用?否

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

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

Tag::OS_PATCHLEVEL

版本:2、3

是否可重复使用?否

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

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

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

Tag::OS_VERSION

版本:2、3

是否可重复使用?否

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

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

Tag::PADDING

版本:1、2、3

是否可重复使用?是

用于指定可与相应密钥配合使用的填充模式。此标记与 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 确定性填充。

注意:RSA PSS 填充模式与 Digest::NONE 不兼容。

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

是否可重复使用?是

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

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

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

是否可重复使用?否

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

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

Tag::ROLLBACK_RESISTANT

版本:1、2、3

是否可重复使用?否

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

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

Tag::ROOT_OF_TRUST

版本:1、2、3

是否可重复使用?否

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

Tag::RSA_PUBLIC_EXPONENT

版本:1、2、3

是否可重复使用?否

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

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

Tag::UNIQUE_ID

版本:3

是否可重复使用?否

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

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

Tag::USAGE_EXPIRE_DATETIME

版本:1、2、3

是否可重复使用?否

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

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

Tag::USER_AUTH_TYPE

版本:1、2、3

是否可重复使用?否

用于指定可以使用哪些类型的用户身份验证程序来授权使用相应密钥。请求 Keymaster 执行所用密钥带有此标记的操作时,要为 Keymaster 提供一个身份验证令牌,并且该令牌的 authenticator_type 字段需与此标记中的值一致。例如,(ntoh(token.authenticator_type) & auth_type_tag_value) != 0,其中 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

是否可重复使用?否

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

此标记的值是一个 64 位的整数,用于指定在通过 Tag::AUTH_TOKENbegin 提供的身份验证令牌中必须存在哪个身份验证政策状态值,身份验证程序才会授权使用相应密钥。如果在调用 begin 时未提供身份验证令牌,或提供的身份验证令牌没有匹配的政策状态值,但所用密钥带有此标记,则该调用失败。

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