Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cce1762 authored by David Drysdale's avatar David Drysdale Committed by Automerger Merge Worker
Browse files

Merge "KeyMint: new version number in attestation" am: 17393cbb am: 0a3c90f9 am: bb5882c6

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

Change-Id: Ib930f22030769d965e1e0323cebfc4bf0344dcac
parents f2e03535 bb5882c6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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
+23 −14
Original line number Diff line number Diff line
@@ -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);
+3 −2
Original line number Diff line number Diff line
@@ -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));
    }
};

+23 −3
Original line number Diff line number Diff line
@@ -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);

+3 −1
Original line number Diff line number Diff line
@@ -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,  //
Loading