Source release 19.4.0

This commit is contained in:
Vicky Min
2024-11-27 00:07:23 +00:00
parent 11c108a8da
commit 22759672a8
72 changed files with 5321 additions and 2622 deletions

View File

@@ -8,6 +8,7 @@
#include <gtest/gtest.h>
#include "device_info_validator.h"
#include "log.h"
using ::testing::AllOf;
using ::testing::Ge;
@@ -30,7 +31,7 @@ cppbor::Map BuildDeviceInfoMap(int version) {
.add("model", "model")
.add("vb_state", "green")
.add("bootloader_state", "unlocked")
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>()))
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>(32, 0xCC)))
.add("os_version", "os_version")
.add("system_patch_level", 202312)
.add("boot_patch_level", 20231201)
@@ -61,6 +62,14 @@ std::vector<uint8_t> BuildDeviceInfo(int version) {
}
} // namespace
static void DumpValidatorOutput(const DeviceInfoValidator& validator) {
const std::string out = validator.GetFormattedMessage();
LOGI("%s", out.c_str());
for (auto& msg : validator.GetValidateMessages()) {
LOGE("Error code %d: %s", msg.first, msg.second.c_str());
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoParseError) {
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion3);
const std::vector<uint8_t> device_info_bad(device_info.begin(),
@@ -87,6 +96,9 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoNotMap) {
EXPECT_EQ(1u, msgs.size());
EXPECT_EQ(kCborValidateFatal, msgs[0].first);
EXPECT_THAT(msgs[0].second, HasSubstr("Device info is not a CBOR map"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest,
@@ -95,8 +107,7 @@ TEST(OEMCryptoDeviceInfoValidatorTest,
cppbor::Map()
.add("brand", "brand")
.add("manufacturer", "manufacturer")
.add(123, 456) // Non-Tstr key type
.add("system_patch_level", "not a uint") // Non-uint value type
.add(123, 456) // Non-Tstr key type
.canonicalize()
.encode();
DeviceInfoValidator validator(kDeviceVersion3);
@@ -112,25 +123,22 @@ TEST(OEMCryptoDeviceInfoValidatorTest,
return p.second.find("Unexpected entry key type") != std::string::npos;
});
EXPECT_EQ(true, unexpected_key_type_found);
const bool unexpected_value_type_found = std::any_of(
msgs.begin(), msgs.end(),
[](const std::pair<CborMessageStatus, std::string>& p) {
return p.second.find("system_patch_level has the wrong type") !=
std::string::npos;
});
EXPECT_EQ(true, unexpected_value_type_found);
const bool missing_model_found = std::any_of(
msgs.begin(), msgs.end(),
[](const std::pair<CborMessageStatus, std::string>& p) {
return p.second.find("model is missing") != std::string::npos;
});
const bool missing_model_found =
std::any_of(msgs.begin(), msgs.end(),
[](const std::pair<CborMessageStatus, std::string>& p) {
return p.second.find("missing important field model") !=
std::string::npos;
});
EXPECT_EQ(true, missing_model_found);
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3NonCanonical) {
const cppbor::Map map = BuildDeviceInfoMap(kDeviceVersion3);
const std::vector<uint8_t> device_info = map.encode();
DeviceInfoValidator validator(kDeviceVersion3);
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
@@ -141,43 +149,97 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3NonCanonical) {
EXPECT_EQ(kCborValidateError, msgs[0].first);
EXPECT_THAT(msgs[0].second,
HasSubstr("Device info ordering is non-canonical"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3) {
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion3);
DeviceInfoValidator validator(kDeviceVersion3);
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
const std::string out = validator.GetFormattedMessage();
EXPECT_THAT(out, HasSubstr("manufacturer: manufacturer"));
EXPECT_THAT(out, HasSubstr("model: model"));
EXPECT_THAT(out, HasSubstr("fused: 0"));
EXPECT_THAT(out, HasSubstr("manufacturer:manufacturer"));
EXPECT_THAT(out, HasSubstr("model:model"));
EXPECT_THAT(out, HasSubstr("fused:0"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV3InvalidFields) {
cppbor::Map device_info_map =
cppbor::Map()
.add("brand", "brand")
.add("manufacturer", "manufacturer")
.add("product", "product")
.add("model", "model")
.add("vb_state", "invalid_green") // invalid value
.add("bootloader_state", "invalid_unlocked") // invalid value
.add("vbmeta_digest", cppbor::Bstr(std::vector<uint8_t>(32, 0xCC)))
.add("os_version", "os_version")
.add("system_patch_level", 100) // invalid value, expects "YYYYMM"
.add("boot_patch_level",
12345678) // invalid value, expectes "YYYYMMDD"
.add("vendor_patch_level",
"20231201") // invalid value, expects YYYYMMDD in int
.add("security_level", "tee")
.add("device", "device")
.add("fused", 9); // invalid value, expects 0 or 1
auto device_info = device_info_map.canonicalize().encode();
DeviceInfoValidator validator(kDeviceVersion3, true /* is_gms */);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
EXPECT_THAT(result, Ge(kCborValidateError));
const std::vector<std::pair<CborMessageStatus, std::string>> msgs =
validator.GetValidateMessages();
std::string out = "";
for (auto& msg : msgs) {
out += (msg.second + "\n");
}
EXPECT_THAT(out, HasSubstr("invalid value for system_patch_level"));
EXPECT_THAT(out, HasSubstr("invalid value for boot_patch_level"));
EXPECT_THAT(out, HasSubstr("missing required field vendor_patch_level"));
EXPECT_THAT(out, HasSubstr("unexpected value for vb_state"));
EXPECT_THAT(out, HasSubstr("unexpected value for bootloader_state"));
EXPECT_THAT(out, HasSubstr("unexpected value for fused"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV2) {
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion2);
DeviceInfoValidator validator(kDeviceVersion2);
DeviceInfoValidator validator(kDeviceVersion2, true /* is_gms */);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
const std::string out = validator.GetFormattedMessage();
EXPECT_THAT(out, HasSubstr("manufacturer: manufacturer"));
EXPECT_THAT(out, HasSubstr("model: model"));
EXPECT_THAT(out, HasSubstr("fused: 0"));
EXPECT_THAT(out, HasSubstr("version: 2"));
EXPECT_THAT(out, HasSubstr("manufacturer:manufacturer"));
EXPECT_THAT(out, HasSubstr("model:model"));
EXPECT_THAT(out, HasSubstr("fused:0"));
EXPECT_THAT(out, HasSubstr("version:2"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1MissingField) {
const std::vector<uint8_t> device_info = cppbor::Map()
.add("brand", "brand")
.add("security_level", "tee")
.add("version", 1)
.canonicalize()
.encode();
DeviceInfoValidator validator(kDeviceVersion1);
const std::vector<uint8_t> device_info =
cppbor::Map()
.add("manufacturer", "manufacturer")
.add("model", "model")
.add("brand", "brand")
.add("security_level", "tee")
.add("version", 1)
.canonicalize()
.encode();
DeviceInfoValidator validator(kDeviceVersion1, true /* is_gms */);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
@@ -186,19 +248,50 @@ TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1MissingField) {
validator.GetValidateMessages();
EXPECT_EQ(1u, msgs.size());
EXPECT_EQ(kCborValidateError, msgs[0].first);
EXPECT_THAT(msgs[0].second, HasSubstr("att_id_state is missing"));
EXPECT_THAT(msgs[0].second, HasSubstr("missing required field att_id_state"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoV1) {
DeviceInfoValidator validator(kDeviceVersion1);
DeviceInfoValidator validator(kDeviceVersion1, true /* is_gms */);
const std::vector<uint8_t> device_info = BuildDeviceInfo(kDeviceVersion1);
CborMessageStatus result = validator.Parse(device_info);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
EXPECT_THAT(result, AllOf(Ge(kCborValidateOk), Le(kCborValidateWarning)));
const std::string out = validator.GetFormattedMessage();
EXPECT_THAT(out, HasSubstr("board: board"));
EXPECT_THAT(out, HasSubstr("version: 1"));
EXPECT_THAT(out, HasSubstr("board:board"));
EXPECT_THAT(out, HasSubstr("version:1"));
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
TEST(OEMCryptoDeviceInfoValidatorTest, DeviceInfoMissingFused) {
const std::vector<uint8_t> device_info_bad =
cppbor::Map()
.add("model", "model")
.add("manufacturer", "manufacturer")
.canonicalize()
.encode();
DeviceInfoValidator validator(kDeviceVersion1, false /* is_gms */);
CborMessageStatus result = validator.Parse(device_info_bad);
EXPECT_EQ(kCborParseOk, result);
result = validator.Validate();
EXPECT_EQ(kCborValidateWarning, result);
const std::vector<std::pair<CborMessageStatus, std::string>> msgs =
validator.GetValidateMessages();
const bool missing_fused_found = std::any_of(
msgs.begin(), msgs.end(),
[](const std::pair<CborMessageStatus, std::string>& p) {
return p.second.find("missing field fused") != std::string::npos;
});
EXPECT_EQ(true, missing_fused_found);
if (result >= kCborValidateWarning) {
DumpValidatorOutput(validator);
}
}
} // namespace util
} // namespace wvoec