Merge "KeyMint: new version number in attestation" am: 17393cbb40
am: 0a3c90f904
am: bb5882c6b3
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1918628 Change-Id: Ib930f22030769d965e1e0323cebfc4bf0344dcac
This commit is contained in:
commit
1cce1762fe
7 changed files with 74 additions and 37 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, //
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue