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

Commit 2f361c15 authored by David Drysdale's avatar David Drysdale
Browse files

KeyMint VTS: check INCLUDE_UNIQUE_ID works

Bug: 202487002
Test: atest VtsAidlKeyMintTargetTest (on CF, O6)
Merged-In: I8bc674b47549aa1133f816c510289774db752e04
Change-Id: I8bc674b47549aa1133f816c510289774db752e04
Ignore-AOSP-First: already in aosp/master
parent 5ee43a6d
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1298,7 +1298,8 @@ bool verify_attestation_record(const string& challenge, //
                               AuthorizationSet expected_sw_enforced,  //
                               AuthorizationSet expected_hw_enforced,  //
                               SecurityLevel security_level,
                               const vector<uint8_t>& attestation_cert) {
                               const vector<uint8_t>& attestation_cert,
                               vector<uint8_t>* unique_id) {
    X509_Ptr cert(parse_cert_blob(attestation_cert));
    EXPECT_TRUE(!!cert.get());
    if (!cert.get()) return false;
@@ -1458,6 +1459,10 @@ bool verify_attestation_record(const string& challenge, //
    expected_hw_enforced.Sort();
    EXPECT_EQ(filtered_tags(expected_hw_enforced), filtered_tags(att_hw_enforced));

    if (unique_id != nullptr) {
        *unique_id = att_unique_id;
    }

    return true;
}

+2 −1
Original line number Diff line number Diff line
@@ -338,7 +338,8 @@ bool verify_attestation_record(const string& challenge, //
                               AuthorizationSet expected_sw_enforced,  //
                               AuthorizationSet expected_hw_enforced,  //
                               SecurityLevel security_level,
                               const vector<uint8_t>& attestation_cert);
                               const vector<uint8_t>& attestation_cert,
                               vector<uint8_t>* unique_id = nullptr);

string bin2hex(const vector<uint8_t>& data);
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
+88 −0
Original line number Diff line number Diff line
@@ -1549,6 +1549,94 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) {
    }
}

/*
 * NewKeyGenerationTest.EcdsaAttestationUniqueId
 *
 * Verifies that creation of an attested ECDSA key with a UNIQUE_ID included.
 */
TEST_P(NewKeyGenerationTest, EcdsaAttestationUniqueId) {
    auto get_unique_id = [this](const std::string& app_id, uint64_t datetime,
                                vector<uint8_t>* unique_id) {
        auto challenge = "hello";
        auto subject = "cert subj 2";
        vector<uint8_t> subject_der(make_name_from_str(subject));
        uint64_t serial_int = 0x1010;
        vector<uint8_t> serial_blob(build_serial_blob(serial_int));
        const AuthorizationSetBuilder builder =
                AuthorizationSetBuilder()
                        .Authorization(TAG_NO_AUTH_REQUIRED)
                        .Authorization(TAG_INCLUDE_UNIQUE_ID)
                        .EcdsaSigningKey(EcCurve::P_256)
                        .Digest(Digest::NONE)
                        .AttestationChallenge(challenge)
                        .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
                        .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
                        .AttestationApplicationId(app_id)
                        .Authorization(TAG_CREATION_DATETIME, datetime)
                        .SetDefaultValidity();

        ASSERT_EQ(ErrorCode::OK, GenerateKey(builder));
        ASSERT_GT(key_blob_.size(), 0U);

        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
        ASSERT_GT(cert_chain_.size(), 0);
        verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false);

        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics_);
        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_GT(unique_id->size(), 0);
        CheckedDeleteKey();
    };

    // Generate unique ID
    auto app_id = "foo";
    uint64_t cert_date = 1619621648000;  // Wed Apr 28 14:54:08 2021 in ms since epoch
    vector<uint8_t> unique_id;
    get_unique_id(app_id, cert_date, &unique_id);

    // Generating a new key with the same parameters should give the same unique ID.
    vector<uint8_t> unique_id2;
    get_unique_id(app_id, cert_date, &unique_id2);
    EXPECT_EQ(unique_id, unique_id2);

    // Generating a new key with a slightly different date should give the same unique ID.
    uint64_t rounded_date = cert_date / 2592000000LLU;
    uint64_t min_date = rounded_date * 2592000000LLU;
    uint64_t max_date = ((rounded_date + 1) * 2592000000LLU) - 1;

    vector<uint8_t> unique_id3;
    get_unique_id(app_id, min_date, &unique_id3);
    EXPECT_EQ(unique_id, unique_id3);

    vector<uint8_t> unique_id4;
    get_unique_id(app_id, max_date, &unique_id4);
    EXPECT_EQ(unique_id, unique_id4);

    // A different attestation application ID should yield a different unique ID.
    auto app_id2 = "different_foo";
    vector<uint8_t> unique_id5;
    get_unique_id(app_id2, cert_date, &unique_id5);
    EXPECT_NE(unique_id, unique_id5);

    // A radically different date should yield a different unique ID.
    vector<uint8_t> unique_id6;
    get_unique_id(app_id, 1611621648000, &unique_id6);
    EXPECT_NE(unique_id, unique_id6);

    vector<uint8_t> unique_id7;
    get_unique_id(app_id, max_date + 1, &unique_id7);
    EXPECT_NE(unique_id, unique_id7);

    vector<uint8_t> unique_id8;
    get_unique_id(app_id, min_date - 1, &unique_id8);
    EXPECT_NE(unique_id, unique_id8);
}

/*
 * NewKeyGenerationTest.EcdsaAttestationTagNoApplicationId
 *