Skip to content
This repository has been archived by the owner on Jul 15, 2024. It is now read-only.

Commit

Permalink
Merge "Support for non-factory attestation in Strongbox."
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxBires authored and Gerrit Code Review committed May 3, 2023
2 parents 8182edb + 50fcf7d commit c4f05e8
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 107 deletions.
89 changes: 1 addition & 88 deletions security/keymint/aidl/vts/functional/AttestKeyTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
};

/*
Expand Down
35 changes: 18 additions & 17 deletions security/keymint/aidl/vts/functional/BootloaderStateTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,37 @@ 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)
.AttestationChallenge("foo")
.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());
Expand Down
87 changes: 85 additions & 2 deletions security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,13 @@ 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,
&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;
}
Expand Down Expand Up @@ -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()));
Expand Down
14 changes: 14 additions & 0 deletions security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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_;
Expand Down

0 comments on commit c4f05e8

Please sign in to comment.