Update KM4 VTS tests to allow s/w implementation to pass.
Although no real devices should have a software implementation, emulator and cloud devices do, and it's useful to be able to use them as a development platform, which is facilitated by having useful VTS tests. This is in preparation for Keymaster 4.1 implementation and VTS work. Bug: 140193672 Bug: 140192237 Bug: 140824829 Test: VtsHalKeymaster4.0TargetTest Change-Id: Idc5de13c342ef1ac62d3131a1a2185d5e78a0d45
This commit is contained in:
parent
13f4bf8491
commit
0a6755018f
4 changed files with 58 additions and 39 deletions
|
@ -321,19 +321,20 @@ ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc
|
||||||
LOG(ERROR) << AT << "Failed record parsing";
|
LOG(ERROR) << AT << "Failed record parsing";
|
||||||
return ErrorCode::UNKNOWN_ERROR;
|
return ErrorCode::UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
if (!record->tee_enforced) {
|
|
||||||
LOG(ERROR) << AT << "Failed hardware characteristic parsing";
|
KM_ROOT_OF_TRUST* root_of_trust = nullptr;
|
||||||
|
if (record->tee_enforced && record->tee_enforced->root_of_trust) {
|
||||||
|
root_of_trust = record->tee_enforced->root_of_trust;
|
||||||
|
} else if (record->software_enforced && record->software_enforced->root_of_trust) {
|
||||||
|
root_of_trust = record->software_enforced->root_of_trust;
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << AT << " Failed root of trust parsing";
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
return ErrorCode::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
if (!record->tee_enforced->root_of_trust) {
|
if (!root_of_trust->verified_boot_key) {
|
||||||
LOG(ERROR) << AT << "Failed root of trust parsing";
|
LOG(ERROR) << AT << " Failed verified boot key parsing";
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
return ErrorCode::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
if (!record->tee_enforced->root_of_trust->verified_boot_key) {
|
|
||||||
LOG(ERROR) << AT << "Failed verified boot key parsing";
|
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
KM_ROOT_OF_TRUST* root_of_trust = record->tee_enforced->root_of_trust;
|
|
||||||
|
|
||||||
auto& vb_key = root_of_trust->verified_boot_key;
|
auto& vb_key = root_of_trust->verified_boot_key;
|
||||||
verified_boot_key->resize(vb_key->length);
|
verified_boot_key->resize(vb_key->length);
|
||||||
|
@ -342,19 +343,19 @@ ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc
|
||||||
*verified_boot_state = static_cast<keymaster_verified_boot_t>(
|
*verified_boot_state = static_cast<keymaster_verified_boot_t>(
|
||||||
ASN1_ENUMERATED_get(root_of_trust->verified_boot_state));
|
ASN1_ENUMERATED_get(root_of_trust->verified_boot_state));
|
||||||
if (!verified_boot_state) {
|
if (!verified_boot_state) {
|
||||||
LOG(ERROR) << AT << "Failed verified boot state parsing";
|
LOG(ERROR) << AT << " Failed verified boot state parsing";
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
return ErrorCode::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
*device_locked = root_of_trust->device_locked;
|
*device_locked = root_of_trust->device_locked;
|
||||||
if (!device_locked) {
|
if (!device_locked) {
|
||||||
LOG(ERROR) << AT << "Failed device locked parsing";
|
LOG(ERROR) << AT << " Failed device locked parsing";
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
return ErrorCode::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& vb_hash = root_of_trust->verified_boot_hash;
|
auto& vb_hash = root_of_trust->verified_boot_hash;
|
||||||
if (!vb_hash) {
|
if (!vb_hash) {
|
||||||
LOG(ERROR) << AT << "Failed verified boot hash parsing";
|
LOG(ERROR) << AT << " Failed verified boot hash parsing";
|
||||||
return ErrorCode::INVALID_ARGUMENT;
|
return ErrorCode::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
verified_boot_hash->resize(vb_hash->length);
|
verified_boot_hash->resize(vb_hash->length);
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace test {
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
void KeymasterHidlTest::InitializeKeymaster() {
|
void KeymasterHidlTest::InitializeKeymaster() {
|
||||||
|
std::string instance_name = GetParam();
|
||||||
keymaster_ = IKeymasterDevice::getService(GetParam());
|
keymaster_ = IKeymasterDevice::getService(GetParam());
|
||||||
ASSERT_NE(keymaster_, nullptr);
|
ASSERT_NE(keymaster_, nullptr);
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ ErrorCode KeymasterHidlTest::ImportWrappedKey(string wrapped_key, string wrappin
|
||||||
string masking_key,
|
string masking_key,
|
||||||
const AuthorizationSet& unwrapping_params) {
|
const AuthorizationSet& unwrapping_params) {
|
||||||
ErrorCode error;
|
ErrorCode error;
|
||||||
ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key);
|
EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key));
|
||||||
EXPECT_TRUE(keymaster_
|
EXPECT_TRUE(keymaster_
|
||||||
->importWrappedKey(HidlBuf(wrapped_key), key_blob_, HidlBuf(masking_key),
|
->importWrappedKey(HidlBuf(wrapped_key), key_blob_, HidlBuf(masking_key),
|
||||||
unwrapping_params.hidl_data(), 0 /* passwordSid */,
|
unwrapping_params.hidl_data(), 0 /* passwordSid */,
|
||||||
|
@ -196,7 +197,9 @@ void KeymasterHidlTest::CheckGetCharacteristics(const HidlBuf& key_blob, const H
|
||||||
HidlBuf empty_buf = {};
|
HidlBuf empty_buf = {};
|
||||||
EXPECT_EQ(ErrorCode::OK,
|
EXPECT_EQ(ErrorCode::OK,
|
||||||
GetCharacteristics(key_blob, client_id, app_data, key_characteristics));
|
GetCharacteristics(key_blob, client_id, app_data, key_characteristics));
|
||||||
EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
|
if (SecLevel() != SecurityLevel::SOFTWARE) {
|
||||||
|
EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
|
||||||
|
}
|
||||||
EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
|
EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
|
||||||
|
|
||||||
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
|
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
|
||||||
|
@ -636,23 +639,25 @@ std::vector<uint32_t> KeymasterHidlTest::ValidKeySizes(Algorithm algorithm) {
|
||||||
switch (algorithm) {
|
switch (algorithm) {
|
||||||
case Algorithm::RSA:
|
case Algorithm::RSA:
|
||||||
switch (SecLevel()) {
|
switch (SecLevel()) {
|
||||||
|
case SecurityLevel::SOFTWARE:
|
||||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||||
return {2048, 3072, 4096};
|
return {2048, 3072, 4096};
|
||||||
case SecurityLevel::STRONGBOX:
|
case SecurityLevel::STRONGBOX:
|
||||||
return {2048};
|
return {2048};
|
||||||
default:
|
default:
|
||||||
CHECK(false) << "Invalid security level " << uint32_t(SecLevel());
|
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Algorithm::EC:
|
case Algorithm::EC:
|
||||||
switch (SecLevel()) {
|
switch (SecLevel()) {
|
||||||
|
case SecurityLevel::SOFTWARE:
|
||||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||||
return {224, 256, 384, 521};
|
return {224, 256, 384, 521};
|
||||||
case SecurityLevel::STRONGBOX:
|
case SecurityLevel::STRONGBOX:
|
||||||
return {256};
|
return {256};
|
||||||
default:
|
default:
|
||||||
CHECK(false) << "Invalid security level " << uint32_t(SecLevel());
|
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -667,25 +672,27 @@ std::vector<uint32_t> KeymasterHidlTest::ValidKeySizes(Algorithm algorithm) {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
CHECK(false) << "Invalid Algorithm: " << algorithm;
|
ADD_FAILURE() << "Invalid Algorithm: " << algorithm;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
CHECK(false) << "Should be impossible to get here";
|
ADD_FAILURE() << "Should be impossible to get here";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> KeymasterHidlTest::InvalidKeySizes(Algorithm algorithm) {
|
std::vector<uint32_t> KeymasterHidlTest::InvalidKeySizes(Algorithm algorithm) {
|
||||||
if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {};
|
if (SecLevel() == SecurityLevel::STRONGBOX) {
|
||||||
CHECK(SecLevel() == SecurityLevel::STRONGBOX);
|
switch (algorithm) {
|
||||||
switch (algorithm) {
|
case Algorithm::RSA:
|
||||||
case Algorithm::RSA:
|
return {3072, 4096};
|
||||||
return {3072, 4096};
|
case Algorithm::EC:
|
||||||
case Algorithm::EC:
|
return {224, 384, 521};
|
||||||
return {224, 384, 521};
|
case Algorithm::AES:
|
||||||
case Algorithm::AES:
|
return {192};
|
||||||
return {192};
|
default:
|
||||||
default:
|
return {};
|
||||||
return {};
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EcCurve> KeymasterHidlTest::ValidCurves() {
|
std::vector<EcCurve> KeymasterHidlTest::ValidCurves() {
|
||||||
|
@ -704,6 +711,7 @@ std::vector<EcCurve> KeymasterHidlTest::InvalidCurves() {
|
||||||
|
|
||||||
std::vector<Digest> KeymasterHidlTest::ValidDigests(bool withNone, bool withMD5) {
|
std::vector<Digest> KeymasterHidlTest::ValidDigests(bool withNone, bool withMD5) {
|
||||||
switch (SecLevel()) {
|
switch (SecLevel()) {
|
||||||
|
case SecurityLevel::SOFTWARE:
|
||||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||||
if (withNone) {
|
if (withNone) {
|
||||||
if (withMD5)
|
if (withMD5)
|
||||||
|
@ -729,10 +737,10 @@ std::vector<Digest> KeymasterHidlTest::ValidDigests(bool withNone, bool withMD5)
|
||||||
return {Digest::SHA_2_256};
|
return {Digest::SHA_2_256};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CHECK(false) << "Invalid security level " << uint32_t(SecLevel());
|
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CHECK(false) << "Should be impossible to get here";
|
ADD_FAILURE() << "Should be impossible to get here";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,11 @@ class KeymasterHidlTest : public ::testing::TestWithParam<std::string> {
|
||||||
KeyCharacteristics key_characteristics_;
|
KeyCharacteristics key_characteristics_;
|
||||||
OperationHandle op_handle_ = kOpHandleSentinel;
|
OperationHandle op_handle_ = kOpHandleSentinel;
|
||||||
|
|
||||||
|
static std::vector<std::string> build_params() {
|
||||||
|
auto params = android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor);
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sp<IKeymasterDevice> keymaster_;
|
sp<IKeymasterDevice> keymaster_;
|
||||||
uint32_t os_version_;
|
uint32_t os_version_;
|
||||||
|
@ -214,10 +219,9 @@ class KeymasterHidlTest : public ::testing::TestWithParam<std::string> {
|
||||||
hidl_string author_;
|
hidl_string author_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INSTANTIATE_KEYMASTER_HIDL_TEST(name) \
|
#define INSTANTIATE_KEYMASTER_HIDL_TEST(name) \
|
||||||
INSTANTIATE_TEST_SUITE_P(PerInstance, name, \
|
INSTANTIATE_TEST_SUITE_P(PerInstance, name, \
|
||||||
testing::ValuesIn(android::hardware::getAllHalInstanceNames( \
|
testing::ValuesIn(KeymasterHidlTest::build_params()), \
|
||||||
IKeymasterDevice::descriptor)), \
|
|
||||||
android::hardware::PrintInstanceNameToString)
|
android::hardware::PrintInstanceNameToString)
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|
|
@ -397,10 +397,16 @@ bool verify_attestation_record(const string& challenge, const string& app_id,
|
||||||
// true. A provided boolean tag that can be pulled back out of the certificate indicates correct
|
// true. A provided boolean tag that can be pulled back out of the certificate indicates correct
|
||||||
// encoding. No need to check if it's in both lists, since the AuthorizationSet compare below
|
// encoding. No need to check if it's in both lists, since the AuthorizationSet compare below
|
||||||
// will handle mismatches of tags.
|
// will handle mismatches of tags.
|
||||||
EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED));
|
if (security_level == SecurityLevel::SOFTWARE) {
|
||||||
|
EXPECT_TRUE(expected_sw_enforced.Contains(TAG_NO_AUTH_REQUIRED));
|
||||||
|
} else {
|
||||||
|
EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED));
|
||||||
|
}
|
||||||
|
|
||||||
// Alternatively this checks the opposite - a false boolean tag (one that isn't provided in
|
// Alternatively this checks the opposite - a false boolean tag (one that isn't provided in
|
||||||
// the authorization list during key generation) isn't being attested to in the certificate.
|
// the authorization list during key generation) isn't being attested to in the certificate.
|
||||||
|
EXPECT_FALSE(expected_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
||||||
|
EXPECT_FALSE(att_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
||||||
EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
||||||
EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
|
||||||
|
|
||||||
|
@ -461,10 +467,10 @@ bool verify_attestation_record(const string& challenge, const string& app_id,
|
||||||
verified_boot_key.size()));
|
verified_boot_key.size()));
|
||||||
} else if (!strcmp(property_value, "red")) {
|
} else if (!strcmp(property_value, "red")) {
|
||||||
EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_FAILED);
|
EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_FAILED);
|
||||||
EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
|
|
||||||
verified_boot_key.size()));
|
|
||||||
} else {
|
} else {
|
||||||
EXPECT_TRUE(false);
|
EXPECT_EQ(verified_boot_state, KM_VERIFIED_BOOT_UNVERIFIED);
|
||||||
|
EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
|
||||||
|
verified_boot_key.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
att_sw_enforced.Sort();
|
att_sw_enforced.Sort();
|
||||||
|
|
Loading…
Reference in a new issue