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." am: c4f05e81e0 am: 41f750ff37
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2553970 Change-Id: I5745b6d0ef21a398022d1f0eaa7a74d9288a49b8 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -88,96 +88,9 @@ string get_imei(int slot) {
|
|||||||
class AttestKeyTest : public KeyMintAidlTestBase {
|
class AttestKeyTest : public KeyMintAidlTestBase {
|
||||||
public:
|
public:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
check_skip_test();
|
skipAttestKeyTest();
|
||||||
KeyMintAidlTestBase::SetUp();
|
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,
|
// Since this test needs to talk to KeyMint HAL, it can only run as root. Thus,
|
||||||
// bootloader can not be locked.
|
// bootloader can not be locked.
|
||||||
class BootloaderStateTest : public testing::TestWithParam<std::string> {
|
class BootloaderStateTest : public KeyMintAidlTestBase {};
|
||||||
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_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check that attested bootloader state is set to unlocked.
|
// Check that attested bootloader state is set to unlocked.
|
||||||
TEST_P(BootloaderStateTest, IsUnlocked) {
|
TEST_P(BootloaderStateTest, IsUnlocked) {
|
||||||
// Generate a key with attestation.
|
// Generate a key with attestation.
|
||||||
|
vector<uint8_t> key_blob;
|
||||||
|
vector<KeyCharacteristics> key_characteristics;
|
||||||
AuthorizationSet keyDesc = AuthorizationSetBuilder()
|
AuthorizationSet keyDesc = AuthorizationSetBuilder()
|
||||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||||
.EcdsaSigningKey(EcCurve::P_256)
|
.EcdsaSigningKey(EcCurve::P_256)
|
||||||
@@ -55,15 +48,23 @@ TEST_P(BootloaderStateTest, IsUnlocked) {
|
|||||||
.AttestationApplicationId("bar")
|
.AttestationApplicationId("bar")
|
||||||
.Digest(Digest::NONE)
|
.Digest(Digest::NONE)
|
||||||
.SetDefaultValidity();
|
.SetDefaultValidity();
|
||||||
KeyCreationResult creationResult;
|
auto result = GenerateKey(keyDesc, &key_blob, &key_characteristics);
|
||||||
auto kmStatus = keyMint_->generateKey(keyDesc.vector_data(), std::nullopt, &creationResult);
|
// If factory provisioned attestation key is not supported by Strongbox,
|
||||||
ASSERT_TRUE(kmStatus.isOk());
|
// then create a key with self-signed attestation and use it as the
|
||||||
|
// attestation key instead.
|
||||||
vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
|
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.
|
// Parse attested AVB values.
|
||||||
const auto& attestation_cert = key_cert_chain[0].encodedCertificate;
|
X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
|
||||||
X509_Ptr cert(parse_cert_blob(attestation_cert));
|
|
||||||
ASSERT_TRUE(cert.get());
|
ASSERT_TRUE(cert.get());
|
||||||
|
|
||||||
ASN1_OCTET_STRING* attest_rec = get_attestation_record(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,
|
const AuthorizationSet& attest_key_desc, const AuthorizationSet& key_desc,
|
||||||
vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
|
vector<uint8_t>* key_blob, vector<KeyCharacteristics>* key_characteristics,
|
||||||
vector<Certificate>* cert_chain) {
|
vector<Certificate>* cert_chain) {
|
||||||
|
skipAttestKeyTest();
|
||||||
AttestationKey attest_key;
|
AttestationKey attest_key;
|
||||||
vector<Certificate> attest_cert_chain;
|
vector<Certificate> attest_cert_chain;
|
||||||
vector<KeyCharacteristics> attest_key_characteristics;
|
vector<KeyCharacteristics> attest_key_characteristics;
|
||||||
// Generate a key with self signed attestation.
|
// 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);
|
&attest_key_characteristics, &attest_cert_chain);
|
||||||
if (error != ErrorCode::OK) {
|
if (error != ErrorCode::OK) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -1548,6 +1549,88 @@ ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob)
|
|||||||
return result;
|
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) {
|
void verify_serial(X509* cert, const uint64_t expected_serial) {
|
||||||
BIGNUM_Ptr ser(BN_new());
|
BIGNUM_Ptr ser(BN_new());
|
||||||
EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
|
EXPECT_TRUE(ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), ser.get()));
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ using ::std::vector;
|
|||||||
|
|
||||||
constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
|
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> {
|
class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
|
||||||
public:
|
public:
|
||||||
struct KeyData {
|
struct KeyData {
|
||||||
@@ -347,6 +350,17 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
|
|||||||
ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
|
ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
|
||||||
ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
|
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:
|
protected:
|
||||||
std::shared_ptr<IKeyMintDevice> keymint_;
|
std::shared_ptr<IKeyMintDevice> keymint_;
|
||||||
uint32_t os_version_;
|
uint32_t os_version_;
|
||||||
|
|||||||
Reference in New Issue
Block a user