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

Commit 0e0f60cf authored by Subrahmanyaman's avatar Subrahmanyaman Committed by Tri Vo
Browse files

Support for non-factory attestation in Strongbox.

Updated the BootLoaderStateTest for strongbox implementations which
do not support factory attestation.

Bug: 255344624
Test: vts -m VtsAidlKeyMintTarget
Change-Id: I8fe176a18fc0b9e2b2d0b012b7b63124d15c9e2f
Merged-In: I8fe176a18fc0b9e2b2d0b012b7b63124d15c9e2f
parent 73ab3173
Loading
Loading
Loading
Loading
+1 −88
Original line number Diff line number Diff line
@@ -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<AttestationKey>& attest_key,
                                vector<uint8_t>* key_blob,
                                vector<KeyCharacteristics>* key_characteristics,
                                vector<Certificate>* 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<char, PROPERTY_VALUE_MAX> 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";
        }
    }
};

/*
+18 −17
Original line number Diff line number Diff line
@@ -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<std::string> {
  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<IKeyMintDevice> keyMint_;
};
class BootloaderStateTest : public KeyMintAidlTestBase {};

// Check that attested bootloader state is set to unlocked.
TEST_P(BootloaderStateTest, IsUnlocked) {
    // Generate a key with attestation.
    vector<uint8_t> key_blob;
    vector<KeyCharacteristics> 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<Certificate> 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());
+85 −2
Original line number Diff line number Diff line
@@ -322,11 +322,12 @@ ErrorCode KeyMintAidlTestBase::GenerateKeyWithSelfSignedAttestKey(
        const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc,
        vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
        vector<Certificate>* cert_chain) {
    skipAttestKeyTest();
    AttestationKey attest_key;
    vector<Certificate> attest_cert_chain;
    vector<KeyCharacteristics> attest_key_characteristics;
    // Generate a key with self signed attestation.
    auto error = GenerateKey(attest_key_desc, std::nullopt, &attest_key.keyBlob,
    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<uint8_t>& ecdsaKeyBlob)
    return result;
}

ErrorCode KeyMintAidlTestBase::GenerateAttestKey(const AuthorizationSet& key_desc,
                                                 const optional<AttestationKey>& attest_key,
                                                 vector<uint8_t>* key_blob,
                                                 vector<KeyCharacteristics>* key_characteristics,
                                                 vector<Certificate>* 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<char, PROPERTY_VALUE_MAX> 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()));
+14 −0
Original line number Diff line number Diff line
@@ -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<string> {
  public:
    struct KeyData {
@@ -347,6 +350,17 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
    ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
    ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);

    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
                                const optional<AttestationKey>& attest_key,
                                vector<uint8_t>* key_blob,
                                vector<KeyCharacteristics>* key_characteristics,
                                vector<Certificate>* 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<IKeyMintDevice> keymint_;
    uint32_t os_version_;