mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Support for non-factory attestation in Strongbox."
This commit is contained in:
@@ -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";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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()));
|
||||
|
||||
@@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user