Merge changes I5e19880b,Ibaed7364 am: 66b8018f0f

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1739774

Change-Id: I5b33ec6cc4412a79f6a8022513d0ff5fad453a89
This commit is contained in:
David Drysdale
2021-06-18 06:03:42 +00:00
committed by Automerger Merge Worker
6 changed files with 350 additions and 49 deletions

View File

@@ -71,6 +71,7 @@ typedef struct km_auth_list {
ASN1_INTEGER_SET* padding;
ASN1_INTEGER* ec_curve;
ASN1_INTEGER* rsa_public_exponent;
ASN1_NULL* rollback_resistance;
ASN1_INTEGER* active_date_time;
ASN1_INTEGER* origination_expire_date_time;
ASN1_INTEGER* usage_expire_date_time;
@@ -78,56 +79,84 @@ typedef struct km_auth_list {
ASN1_INTEGER* user_auth_type;
ASN1_INTEGER* auth_timeout;
ASN1_NULL* allow_while_on_body;
ASN1_NULL* trusted_user_presence_required;
ASN1_NULL* trusted_confirmation_required;
ASN1_NULL* unlocked_device_required;
ASN1_NULL* all_applications;
ASN1_OCTET_STRING* application_id;
ASN1_INTEGER* creation_date_time;
ASN1_INTEGER* origin;
ASN1_NULL* rollback_resistance;
KM_ROOT_OF_TRUST* root_of_trust;
ASN1_INTEGER* os_version;
ASN1_INTEGER* os_patchlevel;
ASN1_OCTET_STRING* attestation_application_id;
ASN1_NULL* trusted_user_presence_required;
ASN1_NULL* trusted_confirmation_required;
ASN1_NULL* unlocked_device_required;
ASN1_OCTET_STRING* attestation_id_brand;
ASN1_OCTET_STRING* attestation_id_device;
ASN1_OCTET_STRING* attestation_id_product;
ASN1_OCTET_STRING* attestation_id_serial;
ASN1_OCTET_STRING* attestation_id_imei;
ASN1_OCTET_STRING* attestation_id_meid;
ASN1_OCTET_STRING* attestation_id_manufacturer;
ASN1_OCTET_STRING* attestation_id_model;
ASN1_INTEGER* vendor_patchlevel;
ASN1_INTEGER* boot_patchlevel;
} KM_AUTH_LIST;
ASN1_SEQUENCE(KM_AUTH_LIST) = {
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()),
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()),
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, TAG_ROLLBACK_RESISTANCE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
TAG_USAGE_EXPIRE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL, TAG_ALLOW_WHILE_ON_BODY.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL,
TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL,
TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL,
TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER, TAG_CREATION_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, TAG_VENDOR_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()),
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()),
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
TAG_ROLLBACK_RESISTANCE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
TAG_USAGE_EXPIRE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL,
TAG_ALLOW_WHILE_ON_BODY.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL,
TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL,
TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL,
TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER,
TAG_CREATION_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_BRAND.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_DEVICE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_PRODUCT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_SERIAL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_IMEI.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MEID.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MODEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER,
TAG_VENDOR_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
} ASN1_SEQUENCE_END(KM_AUTH_LIST);
IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
@@ -259,6 +288,14 @@ static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet*
copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list);
copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list);
copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list);
copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list);
copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list);
copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list);
copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list);
copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list);
copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list);
copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list);
copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED,

View File

@@ -96,6 +96,18 @@ bool contains(hidl_vec<KeyParameter>& set, TypedTag<tag_type, tag>) {
return count > 0;
}
// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const char* prop) {
char value[PROPERTY_VALUE_MAX];
int len = property_get(prop, value, /* default = */ "");
if (len > 0) {
tags->Authorization(ttag, reinterpret_cast<const uint8_t*>(value),
static_cast<size_t>(len));
}
}
constexpr char hex_value[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
@@ -4408,6 +4420,95 @@ TEST_P(AttestationTest, EcAttestation) {
SecLevel(), cert_chain[0]));
}
/*
* AttestationTest.EcAttestationID
*
* Verifies that attesting to EC keys with correct attestation ID fields works and generates the
* expected output.
*/
TEST_P(AttestationTest, EcAttestationID) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
// Collection of valid attestation ID tags.
auto attestation_id_tags = AuthorizationSetBuilder();
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
"ro.product.manufacturer");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
for (const KeyParameter& tag : attestation_id_tags) {
AuthorizationSetBuilder builder =
AuthorizationSetBuilder()
.Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
.Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo"));
// Include one of the (valid) attestation ID tags.
builder.push_back(tag);
hidl_vec<hidl_vec<uint8_t>> cert_chain;
auto result = AttestKey(builder, &cert_chain);
if (result == ErrorCode::CANNOT_ATTEST_IDS) {
continue;
}
ASSERT_EQ(ErrorCode::OK, result);
EXPECT_GE(cert_chain.size(), 2U);
std::vector<KeyParameter> expected_hw_enforced = key_characteristics_.hardwareEnforced;
expected_hw_enforced.push_back(tag);
EXPECT_TRUE(verify_attestation_record(
"challenge", "foo", key_characteristics_.softwareEnforced,
hidl_vec<KeyParameter>(expected_hw_enforced), SecLevel(), cert_chain[0]));
}
}
/*
* AttestationTest.EcAttestationMismatchID
*
* Verifies that attesting to EC keys with incorrect attestation ID fields fails.
*/
TEST_P(AttestationTest, EcAttestationMismatchID) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(EcCurve::P_256)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)));
// Collection of invalid attestation ID tags.
std::string invalid = "completely-invalid";
auto invalid_tags =
AuthorizationSetBuilder()
.Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(),
invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size());
for (const KeyParameter& invalid_tag : invalid_tags) {
AuthorizationSetBuilder builder =
AuthorizationSetBuilder()
.Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
.Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo"));
// Include one of the invalid attestation ID tags.
builder.push_back(invalid_tag);
hidl_vec<hidl_vec<uint8_t>> cert_chain;
auto result = AttestKey(builder, &cert_chain);
EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
<< "result: " << static_cast<int32_t>(result);
}
}
/*
* AttestationTest.EcAttestationRequiresAttestationAppId
*

View File

@@ -79,6 +79,8 @@ typedef struct km_auth_list {
ASN1_INTEGER_SET* padding;
ASN1_INTEGER* ec_curve;
ASN1_INTEGER* rsa_public_exponent;
ASN1_NULL* rollback_resistance;
ASN1_NULL* early_boot_only;
ASN1_INTEGER* active_date_time;
ASN1_INTEGER* origination_expire_date_time;
ASN1_INTEGER* usage_expire_date_time;
@@ -86,21 +88,27 @@ typedef struct km_auth_list {
ASN1_INTEGER* user_auth_type;
ASN1_INTEGER* auth_timeout;
ASN1_NULL* allow_while_on_body;
ASN1_NULL* trusted_user_presence_required;
ASN1_NULL* trusted_confirmation_required;
ASN1_NULL* unlocked_device_required;
ASN1_NULL* all_applications;
ASN1_OCTET_STRING* application_id;
ASN1_INTEGER* creation_date_time;
ASN1_INTEGER* origin;
ASN1_NULL* rollback_resistance;
KM_ROOT_OF_TRUST* root_of_trust;
ASN1_INTEGER* os_version;
ASN1_INTEGER* os_patchlevel;
ASN1_OCTET_STRING* attestation_application_id;
ASN1_NULL* trusted_user_presence_required;
ASN1_NULL* trusted_confirmation_required;
ASN1_NULL* unlocked_device_required;
ASN1_OCTET_STRING* attestation_id_brand;
ASN1_OCTET_STRING* attestation_id_device;
ASN1_OCTET_STRING* attestation_id_product;
ASN1_OCTET_STRING* attestation_id_serial;
ASN1_OCTET_STRING* attestation_id_imei;
ASN1_OCTET_STRING* attestation_id_meid;
ASN1_OCTET_STRING* attestation_id_manufacturer;
ASN1_OCTET_STRING* attestation_id_model;
ASN1_INTEGER* vendor_patchlevel;
ASN1_INTEGER* boot_patchlevel;
ASN1_NULL* early_boot_only;
ASN1_NULL* device_unique_attestation;
ASN1_NULL* identity_credential_key;
} KM_AUTH_LIST;
@@ -116,6 +124,7 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = {
TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
TAG_ROLLBACK_RESISTANCE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
@@ -138,12 +147,27 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = {
ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_BRAND.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_DEVICE.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_PRODUCT.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_SERIAL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_IMEI.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MEID.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING,
TAG_ATTESTATION_ID_MODEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER,
TAG_VENDOR_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL,
TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential_key, ASN1_NULL,
@@ -279,6 +303,14 @@ static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet*
copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list);
copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list);
copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list);
copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list);
copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list);
copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list);
copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list);
copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list);
copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list);
copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list);
copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED,

View File

@@ -53,6 +53,14 @@ using V4_0::TAG_APPLICATION_ID;
using V4_0::TAG_ASSOCIATED_DATA;
using V4_0::TAG_ATTESTATION_APPLICATION_ID;
using V4_0::TAG_ATTESTATION_CHALLENGE;
using V4_0::TAG_ATTESTATION_ID_BRAND;
using V4_0::TAG_ATTESTATION_ID_DEVICE;
using V4_0::TAG_ATTESTATION_ID_IMEI;
using V4_0::TAG_ATTESTATION_ID_MANUFACTURER;
using V4_0::TAG_ATTESTATION_ID_MEID;
using V4_0::TAG_ATTESTATION_ID_MODEL;
using V4_0::TAG_ATTESTATION_ID_PRODUCT;
using V4_0::TAG_ATTESTATION_ID_SERIAL;
using V4_0::TAG_AUTH_TIMEOUT;
using V4_0::TAG_BLOB_USAGE_REQUIREMENTS;
using V4_0::TAG_BLOCK_MODE;

View File

@@ -27,6 +27,8 @@
#include <keymasterV4_1/attestation_record.h>
#include <keymasterV4_1/authorization_set.h>
using android::hardware::keymaster::V4_0::test::add_tag_from_prop;
// Not to dump the attestation by default. Can enable by specify the parameter
// "--dump_attestations" on lunching VTS
static bool dumpAttestations = false;
@@ -173,10 +175,15 @@ void check_attestation_record(AttestationRecord attestation, const HidlBuf& chal
attestation.software_enforced.Sort();
attestation.hardware_enforced.Sort();
EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(attestation.software_enforced))
<< DIFFERENCE(expected_sw_enforced, attestation.software_enforced);
EXPECT_EQ(filter_tags(expected_hw_enforced), filter_tags(attestation.hardware_enforced))
<< DIFFERENCE(expected_hw_enforced, attestation.hardware_enforced);
expected_sw_enforced = filter_tags(expected_sw_enforced);
expected_hw_enforced = filter_tags(expected_hw_enforced);
AuthorizationSet attestation_sw_enforced = filter_tags(attestation.software_enforced);
AuthorizationSet attestation_hw_enforced = filter_tags(attestation.hardware_enforced);
EXPECT_EQ(expected_sw_enforced, attestation_sw_enforced)
<< DIFFERENCE(expected_sw_enforced, attestation_sw_enforced);
EXPECT_EQ(expected_hw_enforced, attestation_hw_enforced)
<< DIFFERENCE(expected_hw_enforced, attestation_hw_enforced);
}
X509_Ptr parse_cert_blob(const std::vector<uint8_t>& blob) {
@@ -342,6 +349,106 @@ TEST_P(DeviceUniqueAttestationTest, Ecdsa) {
SecLevel());
}
TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
if (SecLevel() != SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID))));
// Collection of valid attestation ID tags.
auto attestation_id_tags = AuthorizationSetBuilder();
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_SERIAL, "ro.serial");
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MANUFACTURER,
"ro.product.manufacturer");
add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MODEL, "ro.product.model");
for (const KeyParameter& tag : attestation_id_tags) {
hidl_vec<hidl_vec<uint8_t>> cert_chain;
HidlBuf challenge("challenge");
HidlBuf app_id("foo");
AuthorizationSetBuilder builder =
AuthorizationSetBuilder()
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
.Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
.Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id);
builder.push_back(tag);
ErrorCode result = convert(AttestKey(builder, &cert_chain));
// It is optional for Strong box to support DeviceUniqueAttestation.
if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
ASSERT_EQ(ErrorCode::OK, result);
EXPECT_EQ(2U, cert_chain.size());
if (dumpAttestations) {
for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_));
}
auto [err, attestation] = parse_attestation_record(cert_chain[0]);
ASSERT_EQ(ErrorCode::OK, err);
AuthorizationSetBuilder hw_enforced =
AuthorizationSetBuilder()
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
.Authorization(TAG_OS_VERSION, os_version())
.Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
hw_enforced.push_back(tag);
check_attestation_record(
attestation, challenge,
/* sw_enforced */
AuthorizationSetBuilder().Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id),
hw_enforced, SecLevel());
}
}
TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) {
if (SecLevel() != SecurityLevel::STRONGBOX) return;
ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.EcdsaSigningKey(256)
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID))));
// Collection of invalid attestation ID tags.
std::string invalid = "completely-invalid";
auto attestation_id_tags =
AuthorizationSetBuilder()
.Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(),
invalid.size())
.Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size());
for (const KeyParameter& invalid_tag : attestation_id_tags) {
hidl_vec<hidl_vec<uint8_t>> cert_chain;
HidlBuf challenge("challenge");
HidlBuf app_id("foo");
AuthorizationSetBuilder builder =
AuthorizationSetBuilder()
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
.Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
.Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id);
builder.push_back(invalid_tag);
ErrorCode result = convert(AttestKey(builder, &cert_chain));
EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG)
<< "result: " << static_cast<int32_t>(result);
}
}
INSTANTIATE_KEYMASTER_4_1_HIDL_TEST(DeviceUniqueAttestationTest);
} // namespace test

View File

@@ -18,6 +18,8 @@
#include <android/hardware/keymaster/4.1/IKeymasterDevice.h>
#include <android-base/properties.h>
#include <KeymasterHidlTest.h>
#include <keymasterV4_1/authorization_set.h>
@@ -159,3 +161,17 @@ bool contains(hidl_vec<KeyParameter>& set, TypedTag typedTag) {
android::hardware::PrintInstanceNameToString)
} // namespace android::hardware::keymaster::V4_1::test
namespace android::hardware::keymaster::V4_0::test {
// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const char* prop) {
std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
if (!prop_value.empty()) {
tags->Authorization(ttag, prop_value.data(), prop_value.size());
}
}
} // namespace android::hardware::keymaster::V4_0::test