Merge "KeyMint: coalesce device ID failure code" into main

This commit is contained in:
David Drysdale
2024-10-11 07:46:16 +00:00
committed by Gerrit Code Review
3 changed files with 69 additions and 59 deletions

View File

@@ -253,39 +253,14 @@ TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) {
// Collection of valid attestation ID tags.
auto attestation_id_tags = AuthorizationSetBuilder();
// Use ro.product.brand_for_attestation property for attestation if it is present else fallback
// to ro.product.brand
std::string prop_value =
::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
if (!prop_value.empty()) {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
"ro.product.brand_for_attestation");
} else {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
}
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
// Use ro.product.name_for_attestation property for attestation if it is present else fallback
// to ro.product.name
prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
if (!prop_value.empty()) {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
"ro.product.name_for_attestation");
} else {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
}
add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "brand");
add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "device");
add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "name");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
"ro.product.manufacturer");
// Use ro.product.model_for_attestation property for attestation if it is present else fallback
// to ro.product.model
prop_value =
::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
if (!prop_value.empty()) {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
"ro.product.model_for_attestation");
} else {
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
}
add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "model");
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;

View File

@@ -2400,6 +2400,43 @@ std::string get_imei(int slot) {
return imei;
}
std::optional<std::string> get_attestation_id(const char* prop) {
// The frameworks code (in AndroidKeyStoreKeyPairGeneratorSpi.java) populates device ID
// values from one of 3 places, so the same logic needs to be reproduced here so the tests
// check what's expected correctly.
//
// In order of preference, the properties checked are:
//
// 1) `ro.product.<device-id>_for_attestation`: This should only be set in special cases; in
// particular, AOSP builds for reference devices use a different value than the normal
// builds for the same device (e.g. model of "aosp_raven" instead of "raven").
::android::String8 prop_name =
::android::String8::format("ro.product.%s_for_attestation", prop);
std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
if (!prop_value.empty()) {
return prop_value;
}
// 2) `ro.product.vendor.<device-id>`: This property refers to the vendor code, and so is
// retained even in a GSI environment.
prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
if (!prop_value.empty()) {
return prop_value;
}
// 3) `ro.product.<device-id>`: Note that this property is replaced by a default value when
// running a GSI environment, and so will *not* match the value expected/used by the
// vendor code on the device.
prop_name = ::android::String8::format("ro.product.%s", prop);
prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
if (!prop_value.empty()) {
return prop_value;
}
return std::nullopt;
}
} // namespace test
} // namespace aidl::android::hardware::security::keymint

View File

@@ -17,6 +17,7 @@
#pragma once
#include <functional>
#include <optional>
#include <string_view>
#include <aidl/Gtest.h>
@@ -384,14 +385,20 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
const string& plaintext, const string& exp_cipher_text);
};
// If the given string is non-empty, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const std::string& prop_value) {
if (!prop_value.empty()) {
tags->Authorization(ttag, prop_value.data(), prop_value.size());
}
}
// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const char* prop) {
std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
if (!prop_value.empty()) {
tags->Authorization(ttag, prop_value.data(), prop_value.size());
}
add_tag(tags, ttag, ::android::base::GetProperty(prop, /* default= */ ""));
}
// Return the VSR API level for this device.
@@ -431,6 +438,20 @@ bool check_feature(const std::string& name);
std::optional<int32_t> keymint_feature_value(bool strongbox);
std::string get_imei(int slot);
// Retrieve a device ID property value, to match what is expected in attestations.
std::optional<std::string> get_attestation_id(const char* prop);
// Add the appropriate attestation device ID tag value to the provided `AuthorizationSetBuilder`,
// if found.
template <Tag tag>
void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
auto prop_value = get_attestation_id(prop);
if (prop_value.has_value()) {
add_tag(attestation_id_tags, tag_type, prop_value.value());
}
}
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
@@ -444,29 +465,6 @@ ErrorCode GetReturnErrorCode(const Status& result);
::android::PrintInstanceNameToString); \
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);
// Use `ro.product.<property>_for_attestation` property for attestation if it is present else
// fallback to use `ro.product.vendor.<property>` if it is present else fallback to
// `ro.product.<property>`. Similar logic can be seen in Java method `getVendorDeviceIdProperty`
// in frameworks/base/core/java/android/os/Build.java.
template <Tag tag>
void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
::android::String8 prop_name =
::android::String8::format("ro.product.%s_for_attestation", prop);
std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
if (!prop_value.empty()) {
add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
} else {
prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
if (!prop_value.empty()) {
add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
} else {
prop_name = ::android::String8::format("ro.product.%s", prop);
add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
}
}
}
} // namespace test
} // namespace aidl::android::hardware::security::keymint