From 50fcf7d066066dd2434760f44cd6743934867165 Mon Sep 17 00:00:00 2001 From: Subrahmanyaman Date: Thu, 20 Apr 2023 22:48:39 +0000 Subject: [PATCH] Support for non-factory attestation in Strongbox. Updated the BootLoaderStateTest for strongbox implementations which do not support factory attestation. Test: vts -m VtsAidlKeyMintTarget Change-Id: I8fe176a18fc0b9e2b2d0b012b7b63124d15c9e2f --- .../aidl/vts/functional/AttestKeyTest.cpp | 89 +------------------ .../vts/functional/BootloaderStateTest.cpp | 35 ++++---- .../vts/functional/KeyMintAidlTestBase.cpp | 87 +++++++++++++++++- .../aidl/vts/functional/KeyMintAidlTestBase.h | 14 +++ 4 files changed, 118 insertions(+), 107 deletions(-) diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index e759123334..c035f1906e 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -88,96 +88,9 @@ string get_imei(int slot) { class AttestKeyTest : public KeyMintAidlTestBase { public: void SetUp() override { - check_skip_test(); + skipAttestKeyTest(); KeyMintAidlTestBase::SetUp(); } - - protected: - const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; - - const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; - - ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc, - const optional& attest_key, - vector* key_blob, - vector* key_characteristics, - vector* cert_chain) { - // The original specification for KeyMint v1 required ATTEST_KEY not be combined - // with any other key purpose, but the original VTS tests incorrectly did exactly that. - // This means that a device that launched prior to Android T (API level 33) may - // accept or even require KeyPurpose::SIGN too. - if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) { - AuthorizationSet key_desc_plus_sign = key_desc; - key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN); - - auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics, - cert_chain); - if (result == ErrorCode::OK) { - return result; - } - // If the key generation failed, it may be because the device is (correctly) - // rejecting the combination of ATTEST_KEY+SIGN. Fall through to try again with - // just ATTEST_KEY. - } - return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain); - } - - // Check if ATTEST_KEY feature is disabled - bool is_attest_key_feature_disabled(void) const { - if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) { - GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled"; - return true; - } - - return false; - } - - // Check if StrongBox KeyStore is enabled - bool is_strongbox_enabled(void) const { - if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) { - GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled"; - return true; - } - - return false; - } - - // Check if chipset has received a waiver allowing it to be launched with Android S or T with - // Keymaster 4.0 in StrongBox. - bool is_chipset_allowed_km4_strongbox(void) const { - std::array buffer; - - const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0); - if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false; - - auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr); - if (res <= 0) return false; - - const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"}; - - for (const string model : allowed_soc_models) { - if (model.compare(buffer.data()) == 0) { - GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0"; - return true; - } - } - - return false; - } - - // Skip the test if all the following conditions hold: - // 1. ATTEST_KEY feature is disabled - // 2. STRONGBOX is enabled - // 3. The device is running one of the chipsets that have received a waiver - // allowing it to be launched with Android S (or later) with Keymaster 4.0 - // in StrongBox - void check_skip_test(void) const { - // Check the chipset first as that doesn't require a round-trip to Package Manager. - if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() && - is_attest_key_feature_disabled()) { - GTEST_SKIP() << "Test is not applicable"; - } - } }; /* diff --git a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp index 723edeef3d..dff0498ce5 100644 --- a/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp +++ b/security/keymint/aidl/vts/functional/BootloaderStateTest.cpp @@ -34,20 +34,13 @@ using ::std::vector; // Since this test needs to talk to KeyMint HAL, it can only run as root. Thus, // bootloader can not be locked. -class BootloaderStateTest : public testing::TestWithParam { - public: - virtual void SetUp() override { - ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); - keyMint_ = IKeyMintDevice::fromBinder(binder); - ASSERT_TRUE(keyMint_) << "Failed to get KM device"; - } - - std::shared_ptr keyMint_; -}; +class BootloaderStateTest : public KeyMintAidlTestBase {}; // Check that attested bootloader state is set to unlocked. TEST_P(BootloaderStateTest, IsUnlocked) { // Generate a key with attestation. + vector key_blob; + vector key_characteristics; AuthorizationSet keyDesc = AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .EcdsaSigningKey(EcCurve::P_256) @@ -55,15 +48,23 @@ TEST_P(BootloaderStateTest, IsUnlocked) { .AttestationApplicationId("bar") .Digest(Digest::NONE) .SetDefaultValidity(); - KeyCreationResult creationResult; - auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult); - ASSERT_TRUE(kmStatus.isOk()); - - vector key_cert_chain = std::move(creationResult.certificateChain); + auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics); + // If factory provisioned attestation key is not supported by Strongbox, + // then create a key with self-signed attestation and use it as the + // attestation key instead. + if (SecLevel() == SecurityLevel::STRONGBOX && + result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) { + result = GenerateKeyWithSelfSignedAttestKey( + AuthorizationSetBuilder() + .EcdsaKey(EcCurve::P_256) + .AttestKey() + .SetDefaultValidity(), /* attest key params */ + keyDesc, &key_blob, &key_characteristics); + } + ASSERT_EQ(ErrorCode::OK, result); // Parse attested AVB values. - const auto& attestation_cert = key_cert_chain[0].encodedCertificate; - X509_Ptr cert(parse_cert_blob(attestation_cert)); + X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); ASSERT_TRUE(cert.get()); ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get()); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 5e27bd0e5b..a8ea407e44 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -322,12 +322,13 @@ ErrorCode KeyMintAidlTestBase::GenerateKeyWithSelfSignedAttestKey( const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc, vector* key_blob, vector* key_characteristics, vector* cert_chain) { + skipAttestKeyTest(); AttestationKey attest_key; vector attest_cert_chain; vector attest_key_characteristics; // Generate a key with self signed attestation. - auto error = GenerateKey(attest_key_desc, std::nullopt, &attest_key.keyBlob, - &attest_key_characteristics, &attest_cert_chain); + auto error = GenerateAttestKey(attest_key_desc, std::nullopt, &attest_key.keyBlob, + &attest_key_characteristics, &attest_cert_chain); if (error != ErrorCode::OK) { return error; } @@ -1548,6 +1549,88 @@ ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector& ecdsaKeyBlob) return result; } +ErrorCode KeyMintAidlTestBase::GenerateAttestKey(const AuthorizationSet& key_desc, + const optional& attest_key, + vector* key_blob, + vector* key_characteristics, + vector* cert_chain) { + // The original specification for KeyMint v1 required ATTEST_KEY not be combined + // with any other key purpose, but the original VTS tests incorrectly did exactly that. + // This means that a device that launched prior to Android T (API level 33) may + // accept or even require KeyPurpose::SIGN too. + if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) { + AuthorizationSet key_desc_plus_sign = key_desc; + key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN); + + auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics, + cert_chain); + if (result == ErrorCode::OK) { + return result; + } + // If the key generation failed, it may be because the device is (correctly) + // rejecting the combination of ATTEST_KEY+SIGN. Fall through to try again with + // just ATTEST_KEY. + } + return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain); +} + +// Check if ATTEST_KEY feature is disabled +bool KeyMintAidlTestBase::is_attest_key_feature_disabled(void) const { + if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) { + GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled"; + return true; + } + + return false; +} + +// Check if StrongBox KeyStore is enabled +bool KeyMintAidlTestBase::is_strongbox_enabled(void) const { + if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) { + GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled"; + return true; + } + + return false; +} + +// Check if chipset has received a waiver allowing it to be launched with Android S or T with +// Keymaster 4.0 in StrongBox. +bool KeyMintAidlTestBase::is_chipset_allowed_km4_strongbox(void) const { + std::array buffer; + + const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0); + if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false; + + auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr); + if (res <= 0) return false; + + const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"}; + + for (const string model : allowed_soc_models) { + if (model.compare(buffer.data()) == 0) { + GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0"; + return true; + } + } + + return false; +} + +// Skip the test if all the following conditions hold: +// 1. ATTEST_KEY feature is disabled +// 2. STRONGBOX is enabled +// 3. The device is running one of the chipsets that have received a waiver +// allowing it to be launched with Android S (or later) with Keymaster 4.0 +// in StrongBox +void KeyMintAidlTestBase::skipAttestKeyTest(void) const { + // Check the chipset first as that doesn't require a round-trip to Package Manager. + if (is_chipset_allowed_km4_strongbox() && is_strongbox_enabled() && + is_attest_key_feature_disabled()) { + GTEST_SKIP() << "Test is not applicable"; + } +} + void verify_serial(X509* cert, const uint64_t expected_serial) { BIGNUM_Ptr ser(BN_new()); EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get())); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 3245ca98f2..30ac452bab 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -54,6 +54,9 @@ using ::std::vector; constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF; +const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key"; +const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore"; + class KeyMintAidlTestBase : public ::testing::TestWithParam { public: struct KeyData { @@ -347,6 +350,17 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { ErrorCode UseRsaKey(const vector& rsaKeyBlob); ErrorCode UseEcdsaKey(const vector& ecdsaKeyBlob); + ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc, + const optional& attest_key, + vector* key_blob, + vector* key_characteristics, + vector* cert_chain); + + bool is_attest_key_feature_disabled(void) const; + bool is_strongbox_enabled(void) const; + bool is_chipset_allowed_km4_strongbox(void) const; + void skipAttestKeyTest(void) const; + protected: std::shared_ptr keymint_; uint32_t os_version_;