From 565ccc70ed0dd31965ca4ca86ddce1be741da1c5 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Mon, 11 Oct 2021 12:49:50 +0100 Subject: [PATCH] KeyMint VTS: check INCLUDE_UNIQUE_ID works Bug: 202487002 Test: atest VtsAidlKeyMintTargetTest (on CF, O6) Change-Id: I8bc674b47549aa1133f816c510289774db752e04 --- .../vts/functional/KeyMintAidlTestBase.cpp | 7 +- .../aidl/vts/functional/KeyMintAidlTestBase.h | 3 +- .../aidl/vts/functional/KeyMintTest.cpp | 88 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 37acfa9032..12ce859f29 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -1307,7 +1307,8 @@ bool verify_attestation_record(const string& challenge, // AuthorizationSet expected_sw_enforced, // AuthorizationSet expected_hw_enforced, // SecurityLevel security_level, - const vector& attestation_cert) { + const vector& attestation_cert, + vector* unique_id) { X509_Ptr cert(parse_cert_blob(attestation_cert)); EXPECT_TRUE(!!cert.get()); if (!cert.get()) return false; @@ -1472,6 +1473,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; } diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index ec3fcf6a3e..7b3b9d4b4b 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -338,7 +338,8 @@ bool verify_attestation_record(const string& challenge, // AuthorizationSet expected_sw_enforced, // AuthorizationSet expected_hw_enforced, // SecurityLevel security_level, - const vector& attestation_cert); + const vector& attestation_cert, + vector* unique_id = nullptr); string bin2hex(const vector& data); X509_Ptr parse_cert_blob(const vector& blob); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index e41a851a6f..670043d0dd 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -1620,6 +1620,94 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) { } } +/* + * 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* unique_id) { + auto challenge = "hello"; + auto subject = "cert subj 2"; + vector subject_der(make_name_from_str(subject)); + uint64_t serial_int = 0x1010; + vector 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 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 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 unique_id3; + get_unique_id(app_id, min_date, &unique_id3); + EXPECT_EQ(unique_id, unique_id3); + + vector 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 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 unique_id6; + get_unique_id(app_id, 1611621648000, &unique_id6); + EXPECT_NE(unique_id, unique_id6); + + vector unique_id7; + get_unique_id(app_id, max_date + 1, &unique_id7); + EXPECT_NE(unique_id, unique_id7); + + vector unique_id8; + get_unique_id(app_id, min_date - 1, &unique_id8); + EXPECT_NE(unique_id, unique_id8); +} + /* * NewKeyGenerationTest.EcdsaAttestationTagNoApplicationId *