From 8c0edf6c84253afb4500a386b83c858e94331d32 Mon Sep 17 00:00:00 2001 From: Max Bires Date: Fri, 8 Feb 2019 12:29:58 -0800 Subject: [PATCH] Expanding VTS test coverage Keymaster VTS test coverage on 4.0 was incomplete. This significantly expands the coverage of the spec. The bugs listed are errors found that these tests will cover, but are not indicative of the complete set of things tested. Test: atest VtsHalKeymasterV4_0TargetTest Bug: 79953279 Bug: 119553313 Bug: 119541233 Bug: 119396995 Bug: 119542230 Bug: 119549128 Bug: 119549677 Bug: 122184852 Bug: 122261372 Change-Id: I42d78091b48398597bbebe1d9c91b806494ddf4c --- keymaster/4.0/support/attestation_record.cpp | 58 ++++ .../keymasterV4_0/attestation_record.h | 13 + .../4.0/vts/functional/KeymasterHidlTest.cpp | 42 +++ .../4.0/vts/functional/KeymasterHidlTest.h | 5 + .../functional/keymaster_hidl_hal_test.cpp | 291 +++++++++++++++++- 5 files changed, 399 insertions(+), 10 deletions(-) diff --git a/keymaster/4.0/support/attestation_record.cpp b/keymaster/4.0/support/attestation_record.cpp index 6de0c1c629..000d46e7db 100644 --- a/keymaster/4.0/support/attestation_record.cpp +++ b/keymaster/4.0/support/attestation_record.cpp @@ -16,6 +16,7 @@ #include +#include #include #include @@ -26,6 +27,8 @@ #include #include +#define AT __FILE__ ":" << __LINE__ + namespace android { namespace hardware { namespace keymaster { @@ -304,6 +307,61 @@ ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key return extract_auth_list(record->tee_enforced, tee_enforced); } +ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len, + hidl_vec* verified_boot_key, + keymaster_verified_boot_t* verified_boot_state, bool* device_locked, + hidl_vec* verified_boot_hash) { + if (!verified_boot_key || !verified_boot_state || !device_locked || !verified_boot_hash) { + LOG(ERROR) << AT << "null pointer input(s)"; + return ErrorCode::INVALID_ARGUMENT; + } + const uint8_t* p = asn1_key_desc; + KM_KEY_DESCRIPTION_Ptr record(d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len)); + if (!record.get()) { + LOG(ERROR) << AT << "Failed record parsing"; + return ErrorCode::UNKNOWN_ERROR; + } + if (!record->tee_enforced) { + LOG(ERROR) << AT << "Failed hardware characteristic parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + if (!record->tee_enforced->root_of_trust) { + LOG(ERROR) << AT << "Failed root of trust parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + if (!record->tee_enforced->root_of_trust->verified_boot_key) { + LOG(ERROR) << AT << "Failed verified boot key parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + KM_ROOT_OF_TRUST* root_of_trust = record->tee_enforced->root_of_trust; + + auto& vb_key = root_of_trust->verified_boot_key; + verified_boot_key->resize(vb_key->length); + memcpy(verified_boot_key->data(), vb_key->data, vb_key->length); + + *verified_boot_state = static_cast( + ASN1_ENUMERATED_get(root_of_trust->verified_boot_state)); + if (!verified_boot_state) { + LOG(ERROR) << AT << "Failed verified boot state parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + + *device_locked = root_of_trust->device_locked; + if (!device_locked) { + LOG(ERROR) << AT << "Failed device locked parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + + auto& vb_hash = root_of_trust->verified_boot_hash; + if (!vb_hash) { + LOG(ERROR) << AT << "Failed verified boot hash parsing"; + return ErrorCode::INVALID_ARGUMENT; + } + verified_boot_hash->resize(vb_hash->length); + memcpy(verified_boot_hash->data(), vb_hash->data, vb_hash->length); + return ErrorCode::OK; // KM_ERROR_OK; +} + } // namespace V4_0 } // namespace keymaster } // namespace hardware diff --git a/keymaster/4.0/support/include/keymasterV4_0/attestation_record.h b/keymaster/4.0/support/include/keymasterV4_0/attestation_record.h index fae403a7c5..eb95ceae13 100644 --- a/keymaster/4.0/support/include/keymasterV4_0/attestation_record.h +++ b/keymaster/4.0/support/include/keymasterV4_0/attestation_record.h @@ -42,6 +42,13 @@ class AuthorizationSet; */ static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17"; +enum keymaster_verified_boot_t { + KM_VERIFIED_BOOT_VERIFIED = 0, + KM_VERIFIED_BOOT_SELF_SIGNED = 1, + KM_VERIFIED_BOOT_UNVERIFIED = 2, + KM_VERIFIED_BOOT_FAILED = 3, +}; + ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len, uint32_t* attestation_version, // SecurityLevel* attestation_security_level, @@ -51,6 +58,12 @@ ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key AuthorizationSet* software_enforced, AuthorizationSet* tee_enforced, // hidl_vec* unique_id); + +ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len, + hidl_vec* verified_boot_key, + keymaster_verified_boot_t* verified_boot_state, bool* device_locked, + hidl_vec* verified_boot_hash); + } // namespace V4_0 } // namespace keymaster } // namespace hardware diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp index 995ae4f45c..a7b6c981f4 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.cpp @@ -16,6 +16,7 @@ #include "KeymasterHidlTest.h" +#include #include #include @@ -206,6 +207,47 @@ void KeymasterHidlTest::CheckedDeleteKey() { CheckedDeleteKey(&key_blob_); } +void KeymasterHidlTest::CheckCreationDateTime( + const AuthorizationSet& sw_enforced, + std::chrono::time_point creation) { + for (int i = 0; i < sw_enforced.size(); i++) { + if (sw_enforced[i].tag == TAG_CREATION_DATETIME) { + std::chrono::time_point now = + std::chrono::system_clock::now(); + std::chrono::time_point reported_time{ + std::chrono::milliseconds(sw_enforced[i].f.dateTime)}; + // The test is flaky for EC keys, so a buffer time of 1 second will be added. + EXPECT_LE(creation - 1s, reported_time); + EXPECT_LE(reported_time, now + 1s); + } + } +} + +void KeymasterHidlTest::CheckGetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id, + const HidlBuf& app_data, + KeyCharacteristics* key_characteristics) { + HidlBuf empty_buf = {}; + EXPECT_EQ(ErrorCode::OK, + GetCharacteristics(key_blob, client_id, app_data, key_characteristics)); + EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0); + EXPECT_GT(key_characteristics->softwareEnforced.size(), 0); + + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, empty_buf, app_data, key_characteristics)); + EXPECT_EQ(key_characteristics->hardwareEnforced.size(), 0); + EXPECT_EQ(key_characteristics->softwareEnforced.size(), 0); + + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, client_id, empty_buf, key_characteristics)); + EXPECT_EQ(key_characteristics->hardwareEnforced.size(), 0); + EXPECT_EQ(key_characteristics->softwareEnforced.size(), 0); + + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, empty_buf, empty_buf, key_characteristics)); + EXPECT_EQ(key_characteristics->hardwareEnforced.size(), 0); + EXPECT_EQ(key_characteristics->softwareEnforced.size(), 0); +} + ErrorCode KeymasterHidlTest::GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id, const HidlBuf& app_data, KeyCharacteristics* key_characteristics) { diff --git a/keymaster/4.0/vts/functional/KeymasterHidlTest.h b/keymaster/4.0/vts/functional/KeymasterHidlTest.h index 4cd6a5b577..015fc43752 100644 --- a/keymaster/4.0/vts/functional/KeymasterHidlTest.h +++ b/keymaster/4.0/vts/functional/KeymasterHidlTest.h @@ -131,6 +131,11 @@ class KeymasterHidlTest : public ::testing::VtsHalHidlTargetTestBase { void CheckedDeleteKey(HidlBuf* key_blob, bool keep_key_blob = false); void CheckedDeleteKey(); + static void CheckCreationDateTime(const AuthorizationSet& sw_enforced, + std::chrono::time_point creation); + + void CheckGetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id, + const HidlBuf& app_data, KeyCharacteristics* key_characteristics); ErrorCode GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id, const HidlBuf& app_data, KeyCharacteristics* key_characteristics); ErrorCode GetCharacteristics(const HidlBuf& key_blob, KeyCharacteristics* key_characteristics); diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index a9c6f6ca93..2e76604027 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -299,8 +299,9 @@ std::string make_string(const uint8_t (&a)[N]) { bool verify_attestation_record(const string& challenge, const string& app_id, AuthorizationSet expected_sw_enforced, - AuthorizationSet expected_tee_enforced, SecurityLevel security_level, - const hidl_vec& attestation_cert) { + AuthorizationSet expected_hw_enforced, SecurityLevel security_level, + const hidl_vec& attestation_cert, + std::chrono::time_point creation_time) { X509_Ptr cert(parse_cert_blob(attestation_cert)); EXPECT_TRUE(!!cert.get()); if (!cert.get()) return false; @@ -310,7 +311,7 @@ bool verify_attestation_record(const string& challenge, const string& app_id, if (!attest_rec) return false; AuthorizationSet att_sw_enforced; - AuthorizationSet att_tee_enforced; + AuthorizationSet att_hw_enforced; uint32_t att_attestation_version; uint32_t att_keymaster_version; SecurityLevel att_attestation_security_level; @@ -327,7 +328,7 @@ bool verify_attestation_record(const string& challenge, const string& app_id, &att_keymaster_security_level, // &att_challenge, // &att_sw_enforced, // - &att_tee_enforced, // + &att_hw_enforced, // &att_unique_id); EXPECT_EQ(ErrorCode::OK, error); if (error != ErrorCode::OK) return false; @@ -343,13 +344,105 @@ bool verify_attestation_record(const string& challenge, const string& app_id, EXPECT_EQ(challenge.length(), att_challenge.size()); EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length())); + char property_value[PROPERTY_VALUE_MAX] = {}; + for (int i = 0; i < att_hw_enforced.size(); i++) { + if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL || + att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) { + std::string date = std::to_string(att_hw_enforced[i].f.integer); + // strptime seems to require delimiters, but the tag value will be YYYYMMDD + date.insert(6, "-"); + date.insert(4, "-"); + EXPECT_EQ(date.size(), 10); + struct tm time; + strptime(date.c_str(), "%Y-%m-%d", &time); + + // Day of the month (0-31) + EXPECT_GT(time.tm_mday, 0); + EXPECT_LT(time.tm_mday, 32); + // Months since Jan (0-11) + EXPECT_GE(time.tm_mon, 0); + EXPECT_LT(time.tm_mon, 12); + // Years since 1900 + EXPECT_GT(time.tm_year, 110); + EXPECT_LT(time.tm_year, 200); + } + } + + // Check to make sure boolean values are properly encoded. Presence of a boolean tag indicates + // true. A provided boolean tag that can be pulled back out of the certificate indicates correct + // encoding. No need to check if it's in both lists, since the AuthorizationSet compare below + // will handle mismatches of tags. + EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED)); + + // Alternatively this checks the opposite - a false boolean tag (one that isn't provided in + // the authorization list during key generation) isn't being attested to in the certificate. + EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); + EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); + + KeymasterHidlTest::CheckCreationDateTime(att_sw_enforced, creation_time); + + if (att_hw_enforced.Contains(TAG_ALGORITHM, Algorithm::EC)) { + // For ECDSA keys, either an EC_CURVE or a KEY_SIZE can be specified, but one must be. + EXPECT_TRUE(att_hw_enforced.Contains(TAG_EC_CURVE) || + att_hw_enforced.Contains(TAG_KEY_SIZE)); + } + + // Test root of trust elements + HidlBuf verified_boot_key; + keymaster_verified_boot_t verified_boot_state; + bool device_locked; + HidlBuf verified_boot_hash; + error = parse_root_of_trust(attest_rec->data, attest_rec->length, &verified_boot_key, + &verified_boot_state, &device_locked, &verified_boot_hash); + EXPECT_EQ(ErrorCode::OK, error); + + property_get("ro.boot.vbmeta.digest", property_value, "nogood"); + EXPECT_NE(strcmp(property_value, "nogood"), 0); + string prop_string(property_value); + EXPECT_EQ(prop_string.size(), 64); + EXPECT_EQ(0, memcmp(verified_boot_hash.data(), prop_string.data(), verified_boot_hash.size())); + + property_get("ro.boot.vbmeta.device_state", property_value, "nogood"); + EXPECT_NE(property_value, "nogood"); + if (!strcmp(property_value, "unlocked")) { + EXPECT_FALSE(device_locked); + } else { + EXPECT_TRUE(device_locked); + } + + // Verified boot key should be all 0's if the boot state is not verified or self signed + std::string empty_boot_key(32, '\0'); + std::string verified_boot_key_str((const char*)verified_boot_key.data(), + verified_boot_key.size()); + property_get("ro.boot.verifiedbootstate", property_value, "nogood"); + EXPECT_NE(property_value, "nogood"); + if (!strcmp(property_value, "green")) { + EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_VERIFIED); + EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(), + verified_boot_key.size())); + } else if (!strcmp(property_value, "yellow")) { + EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_SELF_SIGNED); + EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(), + verified_boot_key.size())); + } else if (!strcmp(property_value, "orange")) { + EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_UNVERIFIED); + EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(), + verified_boot_key.size())); + } else if (!strcmp(property_value, "red")) { + EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_FAILED); + EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(), + verified_boot_key.size())); + } else { + EXPECT_TRUE(false); + } + att_sw_enforced.Sort(); expected_sw_enforced.Sort(); EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(att_sw_enforced)); - att_tee_enforced.Sort(); - expected_tee_enforced.Sort(); - EXPECT_EQ(filter_tags(expected_tee_enforced), filter_tags(att_tee_enforced)); + att_hw_enforced.Sort(); + expected_hw_enforced.Sort(); + EXPECT_EQ(filter_tags(expected_hw_enforced), filter_tags(att_hw_enforced)); return true; } @@ -431,6 +524,24 @@ TEST_F(NewKeyGenerationTest, Rsa) { } } +/* + * NewKeyGenerationTest.RsaCheckCreationDateTime + * + * Verifies that creation date time is correct. + */ +TEST_F(NewKeyGenerationTest, RsaCheckCreationDateTime) { + KeyCharacteristics key_characteristics; + auto creation_time = std::chrono::system_clock::now(); + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 3) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE))); + GetCharacteristics(key_blob_, &key_characteristics); + AuthorizationSet sw_enforced = key_characteristics.softwareEnforced; + CheckCreationDateTime(sw_enforced, creation_time); +} + /* * NewKeyGenerationTest.NoInvalidRsaSizes * @@ -494,6 +605,23 @@ TEST_F(NewKeyGenerationTest, Ecdsa) { } } +/* + * NewKeyGenerationTest.EcCheckCreationDateTime + * + * Verifies that creation date time is correct. + */ +TEST_F(NewKeyGenerationTest, EcCheckCreationDateTime) { + KeyCharacteristics key_characteristics; + auto creation_time = std::chrono::system_clock::now(); + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::NONE))); + GetCharacteristics(key_blob_, &key_characteristics); + AuthorizationSet sw_enforced = key_characteristics.softwareEnforced; + CheckCreationDateTime(sw_enforced, creation_time); +} + /* * NewKeyGenerationTest.EcdsaDefaultSize * @@ -733,6 +861,69 @@ TEST_F(SigningOperationsTest, RsaSuccess) { message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); } +/* + * SigningOperationsTest.RsaGetKeyCharacteristicsRequiresCorrectAppIdAppData + * + * Verifies that getting RSA key characteristics requires the correct app ID/data. + */ +TEST_F(SigningOperationsTest, RsaGetKeyCharacteristicsRequiresCorrectAppIdAppData) { + HidlBuf key_blob; + KeyCharacteristics key_characteristics; + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 65537) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")), + &key_blob, &key_characteristics)); + CheckGetCharacteristics(key_blob, HidlBuf("clientid"), HidlBuf("appdata"), + &key_characteristics); +} + +/* + * SigningOperationsTest.RsaUseRequiresCorrectAppIdAppData + * + * Verifies that using an RSA key requires the correct app ID/data. + */ +TEST_F(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) { + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 65537) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")))); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::OK, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")))); + AbortIfNeeded(); +} + /* * SigningOperationsTest.RsaPssSha256Success * @@ -1109,6 +1300,63 @@ TEST_F(SigningOperationsTest, EcdsaNoDigestHugeData) { SignMessage(message, AuthorizationSetBuilder().Digest(Digest::NONE)); } +/* + * SigningOperationsTest.EcGetKeyCharacteristicsRequiresCorrectAppIdAppData + * + * Verifies that getting EC key characteristics requires the correct app ID/data. + */ +TEST_F(SigningOperationsTest, EcGetKeyCharacteristicsRequiresCorrectAppIdAppData) { + HidlBuf key_blob; + KeyCharacteristics key_characteristics; + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")), + &key_blob, &key_characteristics)); + CheckGetCharacteristics(key_blob, HidlBuf("clientid"), HidlBuf("appdata"), + &key_characteristics); +} + +/* + * SigningOperationsTest.EcUseRequiresCorrectAppIdAppData + * + * Verifies that using an EC key requires the correct app ID/data. + */ +TEST_F(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")))); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")))); + AbortIfNeeded(); + EXPECT_EQ(ErrorCode::OK, + Begin(KeyPurpose::SIGN, + AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Authorization(TAG_APPLICATION_DATA, HidlBuf("appdata")) + .Authorization(TAG_APPLICATION_ID, HidlBuf("clientid")))); + AbortIfNeeded(); +} + /* * SigningOperationsTest.AesEcbSign * @@ -3858,6 +4106,7 @@ typedef KeymasterHidlTest AttestationTest; * Verifies that attesting to RSA keys works and generates the expected output. */ TEST_F(AttestationTest, RsaAttestation) { + auto creation_time = std::chrono::system_clock::now(); ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .RsaSigningKey(2048, 65537) @@ -3882,7 +4131,7 @@ TEST_F(AttestationTest, RsaAttestation) { EXPECT_TRUE(verify_attestation_record("challenge", "foo", // key_characteristics_.softwareEnforced, // key_characteristics_.hardwareEnforced, // - SecLevel(), cert_chain[0])); + SecLevel(), cert_chain[0], creation_time)); } /* @@ -3905,12 +4154,35 @@ TEST_F(AttestationTest, RsaAttestationRequiresAppId) { &cert_chain)); } +/* + * AttestationTest.RsaAttestationRequiresCorrectAppId + * + * Verifies that attesting to RSA requires the correct app ID. + */ +TEST_F(AttestationTest, RsaAttestationRequiresCorrectAppId) { + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 65537) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_APPLICATION_ID, HidlBuf("lol")))); + + hidl_vec> cert_chain; + EXPECT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, + AttestKey(AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) + .Authorization(TAG_APPLICATION_ID, HidlBuf("heh")), + &cert_chain)); +} + /* * AttestationTest.EcAttestation * * Verifies that attesting to EC keys works and generates the expected output. */ TEST_F(AttestationTest, EcAttestation) { + auto creation_time = std::chrono::system_clock::now(); ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .EcdsaSigningKey(EcCurve::P_256) @@ -3929,11 +4201,10 @@ TEST_F(AttestationTest, EcAttestation) { string signature = SignMessage(message, AuthorizationSetBuilder().Digest(Digest::SHA_2_256)); EXPECT_TRUE(verify_chain(cert_chain, message, signature)); - EXPECT_TRUE(verify_attestation_record("challenge", "foo", // key_characteristics_.softwareEnforced, // key_characteristics_.hardwareEnforced, // - SecLevel(), cert_chain[0])); + SecLevel(), cert_chain[0], creation_time)); } /*