Merge "KeyMint: new version number in attestation" am: 17393cbb40

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

Change-Id: I4ba9a58363ff940f3db7d7dae2e8b5444268535e
This commit is contained in:
David Drysdale 2021-12-16 10:44:11 +00:00 committed by Automerger Merge Worker
commit 0a3c90f904
7 changed files with 74 additions and 37 deletions

View file

@ -122,9 +122,9 @@ parcelable KeyCreationResult {
* straightforward translation of the KeyMint tag/value parameter lists to ASN.1.
*
* KeyDescription ::= SEQUENCE {
* attestationVersion INTEGER, # Value 100
* attestationVersion INTEGER, # Value 200
* attestationSecurityLevel SecurityLevel, # See below
* keyMintVersion INTEGER, # Value 100
* keyMintVersion INTEGER, # Value 200
* keymintSecurityLevel SecurityLevel, # See below
* attestationChallenge OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
* uniqueId OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID

View file

@ -81,7 +81,8 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -113,7 +114,8 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo2", "bar2", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo2", "bar2", sw_enforced,
hw_enforced, SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -154,12 +156,13 @@ TEST_P(AttestKeyTest, AllRsaSizes) {
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
// The client-specified CREATION_DATETIME should be in sw_enforced.
// Its presence will also trigger verify_attestation_record() to check that it
// is in the attestation extension with a matching value.
// Its presence will also trigger verify_attestation_record() to check that
// it is in the attestation extension with a matching value.
EXPECT_TRUE(sw_enforced.Contains(TAG_CREATION_DATETIME, timestamp))
<< "expected CREATION_TIMESTAMP in sw_enforced:" << sw_enforced
<< " not in hw_enforced:" << hw_enforced;
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -235,7 +238,7 @@ TEST_P(AttestKeyTest, RsaAttestedAttestKeys) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attest_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attest_key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
attest_key_cert_chain[0].encodedCertificate));
@ -270,7 +273,8 @@ TEST_P(AttestKeyTest, RsaAttestedAttestKeys) {
AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced2, hw_enforced2, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced2, hw_enforced2,
SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -331,7 +335,8 @@ TEST_P(AttestKeyTest, RsaAttestKeyChaining) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
cert_chain_list[i][0].encodedCertificate));
if (i > 0) {
@ -403,7 +408,8 @@ TEST_P(AttestKeyTest, EcAttestKeyChaining) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
cert_chain_list[i][0].encodedCertificate));
if (i > 0) {
@ -510,7 +516,8 @@ TEST_P(AttestKeyTest, AlternateAttestKeyChaining) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
ASSERT_GT(cert_chain_list[i].size(), 0);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
cert_chain_list[i][0].encodedCertificate));
if (i > 0) {
@ -624,7 +631,8 @@ TEST_P(AttestKeyTest, AllEcCurves) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -655,7 +663,8 @@ TEST_P(AttestKeyTest, AllEcCurves) {
hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
// Attestation by itself is not valid (last entry is not self-signed).
@ -760,8 +769,8 @@ TEST_P(AttestKeyTest, EcdsaAttestationID) {
// attestation extension should contain them, so make sure the extra tag is added.
hw_enforced.push_back(tag);
EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
SecLevel(),
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
hw_enforced, SecLevel(),
attested_key_cert_chain[0].encodedCertificate));
}
CheckedDeleteKey(&attest_key.keyBlob);

View file

@ -52,8 +52,9 @@ class DeviceUniqueAttestationTest : public KeyMintAidlTestBase {
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false));
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
SecLevel(), cert_chain_[0].encodedCertificate));
EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
}
};

View file

@ -127,6 +127,16 @@ ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
return attest_rec;
}
void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
// Version numbers in attestation extensions should be a multiple of 100.
EXPECT_EQ(attestation_version % 100, 0);
// The multiplier should never be higher than the AIDL version, but can be less
// (for example, if the implementation is from an earlier version but the HAL service
// uses the default libraries and so reports the current AIDL version).
EXPECT_TRUE((attestation_version / 100) <= aidl_version);
}
bool avb_verification_enabled() {
char value[PROPERTY_VALUE_MAX];
return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
@ -223,6 +233,15 @@ void KeyMintAidlTestBase::InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyM
vendor_patch_level_ = getVendorPatchlevel();
}
int32_t KeyMintAidlTestBase::AidlVersion() {
int32_t version = 0;
auto status = keymint_->getInterfaceVersion(&version);
if (!status.isOk()) {
ADD_FAILURE() << "Failed to determine interface version";
}
return version;
}
void KeyMintAidlTestBase::SetUp() {
if (AServiceManager_isDeclared(GetParam().c_str())) {
::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
@ -1304,7 +1323,8 @@ void verify_subject_and_serial(const Certificate& certificate, //
verify_subject(cert.get(), subject, self_signed);
}
bool verify_attestation_record(const string& challenge, //
bool verify_attestation_record(int32_t aidl_version, //
const string& challenge, //
const string& app_id, //
AuthorizationSet expected_sw_enforced, //
AuthorizationSet expected_hw_enforced, //
@ -1342,7 +1362,7 @@ bool verify_attestation_record(const string& challenge, //
EXPECT_EQ(ErrorCode::OK, error);
if (error != ErrorCode::OK) return false;
EXPECT_EQ(att_attestation_version, 100U);
check_attestation_version(att_attestation_version, aidl_version);
vector<uint8_t> appId(app_id.begin(), app_id.end());
// check challenge and app id only if we expects a non-fake certificate
@ -1353,7 +1373,7 @@ bool verify_attestation_record(const string& challenge, //
expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId);
}
EXPECT_EQ(att_keymint_version, 100U);
check_attestation_version(att_keymint_version, aidl_version);
EXPECT_EQ(security_level, att_keymint_security_level);
EXPECT_EQ(security_level, att_attestation_security_level);

View file

@ -73,6 +73,7 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
void InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint);
IKeyMintDevice& keyMint() { return *keymint_; }
int32_t AidlVersion();
uint32_t os_version() { return os_version_; }
uint32_t os_patch_level() { return os_patch_level_; }
uint32_t vendor_patch_level() { return vendor_patch_level_; }
@ -333,7 +334,8 @@ void verify_subject_and_serial(const Certificate& certificate, //
const uint64_t expected_serial, //
const string& subject, bool self_signed);
bool verify_attestation_record(const string& challenge, //
bool verify_attestation_record(int aidl_version, //
const string& challenge, //
const string& app_id, //
AuthorizationSet expected_sw_enforced, //
AuthorizationSet expected_hw_enforced, //

View file

@ -942,7 +942,7 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
@ -1093,7 +1093,7 @@ TEST_P(NewKeyGenerationTest, RsaEncryptionWithAttestation) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
@ -1315,7 +1315,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
@ -1444,7 +1444,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
@ -1523,8 +1523,9 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) {
// Verifying the attestation record will check for the specific tag because
// it's included in the authorizations.
EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
SecLevel(), cert_chain_[0].encodedCertificate));
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
CheckedDeleteKey(&key_blob);
}
@ -1621,8 +1622,9 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) {
// Verifying the attestation record will check for the specific tag because
// it's included in the authorizations.
EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
SecLevel(), cert_chain_[0].encodedCertificate));
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
CheckedDeleteKey(&key_blob);
}
@ -1668,9 +1670,9 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationUniqueId) {
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics_);
// Check that the unique ID field in the extension is non-empty.
EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
SecLevel(), cert_chain_[0].encodedCertificate,
unique_id));
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate, unique_id));
EXPECT_GT(unique_id->size(), 0);
CheckedDeleteKey();
};
@ -1765,8 +1767,9 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTagNoApplicationId) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, attest_app_id, sw_enforced, hw_enforced,
SecLevel(), cert_chain_[0].encodedCertificate));
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, attest_app_id, sw_enforced,
hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));
// Check that the app id is not in the cert.
string app_id = "clientid";
@ -1919,7 +1922,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) {
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, //
sw_enforced, hw_enforced, SecLevel(),
cert_chain_[0].encodedCertificate));

View file

@ -236,9 +236,11 @@ TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
EXPECT_EQ(attested_key_cert_chain.size(), 1);
int32_t aidl_version = 0;
ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced,
EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
info.securityLevel,
attested_key_cert_chain[0].encodedCertificate));