|
|
|
|
@@ -198,6 +198,106 @@ std::string MaybeHex(const uint8_t* data, size_t length) {
|
|
|
|
|
std::string MaybeHex(const std::vector<uint8_t>& data) {
|
|
|
|
|
return MaybeHex(data.data(), data.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* BoolName(bool value) { return value ? "true" : "false"; }
|
|
|
|
|
const char* SecurityLevelName(OEMCrypto_Security_Level value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case OEMCrypto_Level_Unknown:
|
|
|
|
|
return "OEMCrypto_Level_Unknown";
|
|
|
|
|
case OEMCrypto_Level1:
|
|
|
|
|
return "OEMCrypto_Level1";
|
|
|
|
|
case OEMCrypto_Level2:
|
|
|
|
|
return "OEMCrypto_Level2";
|
|
|
|
|
case OEMCrypto_Level3:
|
|
|
|
|
return "OEMCrypto_Level3";
|
|
|
|
|
}
|
|
|
|
|
// Not reachable unless the enum value is invalid
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case HDCP_NONE:
|
|
|
|
|
return "No HDCP supported, no secure data path";
|
|
|
|
|
case HDCP_V1:
|
|
|
|
|
return "HDCP version 1.x";
|
|
|
|
|
case HDCP_V1_0:
|
|
|
|
|
return "HDCP version 1.0";
|
|
|
|
|
case HDCP_V1_1:
|
|
|
|
|
return "HDCP version 1.1";
|
|
|
|
|
case HDCP_V1_2:
|
|
|
|
|
return "HDCP version 1.2";
|
|
|
|
|
case HDCP_V1_3:
|
|
|
|
|
return "HDCP version 1.3";
|
|
|
|
|
case HDCP_V1_4:
|
|
|
|
|
return "HDCP version 1.4";
|
|
|
|
|
case HDCP_V2:
|
|
|
|
|
return "HDCP version 2.0";
|
|
|
|
|
case HDCP_V2_1:
|
|
|
|
|
return "HDCP version 2.1";
|
|
|
|
|
case HDCP_V2_2:
|
|
|
|
|
return "HDCP version 2.2";
|
|
|
|
|
case HDCP_V2_3:
|
|
|
|
|
return "HDCP version 2.3";
|
|
|
|
|
case HDCP_NO_DIGITAL_OUTPUT:
|
|
|
|
|
return "No HDCP device attached/using local display with secure path";
|
|
|
|
|
}
|
|
|
|
|
// Not reachable unless the enum value is invalid
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
const char* HDCPCapabilityName(OEMCrypto_HDCP_Capability value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case HDCP_NONE:
|
|
|
|
|
return "HDCP_NONE";
|
|
|
|
|
case HDCP_V1:
|
|
|
|
|
return "HDCP_V1";
|
|
|
|
|
case HDCP_V1_0:
|
|
|
|
|
return "HDCP_V1_0";
|
|
|
|
|
case HDCP_V1_1:
|
|
|
|
|
return "HDCP_V1_1";
|
|
|
|
|
case HDCP_V1_2:
|
|
|
|
|
return "HDCP_V1_2";
|
|
|
|
|
case HDCP_V1_3:
|
|
|
|
|
return "HDCP_V1_3";
|
|
|
|
|
case HDCP_V1_4:
|
|
|
|
|
return "HDCP_V1_4";
|
|
|
|
|
case HDCP_V2:
|
|
|
|
|
return "HDCP_V2";
|
|
|
|
|
case HDCP_V2_1:
|
|
|
|
|
return "HDCP_V2_1";
|
|
|
|
|
case HDCP_V2_2:
|
|
|
|
|
return "HDCP_V2_2";
|
|
|
|
|
case HDCP_V2_3:
|
|
|
|
|
return "HDCP_V2_3";
|
|
|
|
|
case HDCP_NO_DIGITAL_OUTPUT:
|
|
|
|
|
return "HDCP_NO_DIGITAL_OUTPUT";
|
|
|
|
|
}
|
|
|
|
|
// Not reachable unless the enum value is invalid
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
const char* WatermarkingSupportName(OEMCrypto_WatermarkingSupport value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case OEMCrypto_WatermarkingError:
|
|
|
|
|
return "OEMCrypto_WatermarkingError";
|
|
|
|
|
case OEMCrypto_WatermarkingNotSupported:
|
|
|
|
|
return "OEMCrypto_WatermarkingNotSupported";
|
|
|
|
|
case OEMCrypto_WatermarkingConfigurable:
|
|
|
|
|
return "OEMCrypto_WatermarkingConfigurable";
|
|
|
|
|
case OEMCrypto_WatermarkingAlwaysOn:
|
|
|
|
|
return "OEMCrypto_WatermarkingAlwaysOn";
|
|
|
|
|
}
|
|
|
|
|
// Not reachable unless the enum value is invalid
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
const char* DTCP2CapabiityName(OEMCrypto_DTCP2_Capability value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case OEMCrypto_NO_DTCP2:
|
|
|
|
|
return "OEMCrypto_NO_DTCP2";
|
|
|
|
|
case OEMCrypto_DTCP2_V1:
|
|
|
|
|
return "OEMCrypto_DTCP2_V1";
|
|
|
|
|
}
|
|
|
|
|
// Not reachable unless the enum value is invalid
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
|
|
|
|
@@ -269,6 +369,10 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
|
|
|
|
return OEMCrypto_CopyBuffer(session, input_buffer, input_buffer_size,
|
|
|
|
|
dest_buffer_descriptor, subsample_flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RecordWvProperty(const std::string& key, const std::string& value) {
|
|
|
|
|
RecordProperty("widevine_metadata_oec_" + key, value);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
|
|
|
|
|
@@ -292,7 +396,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(OEMCryptoClientTest, VersionNumber) {
|
|
|
|
|
const std::string log_message =
|
|
|
|
|
"OEMCrypto unit tests for API 17.5. Tests last updated 2024-09-04";
|
|
|
|
|
"OEMCrypto unit tests for API 17.6. Tests last updated 2024-11-04";
|
|
|
|
|
cout << " " << log_message << "\n";
|
|
|
|
|
cout << " "
|
|
|
|
|
<< "These tests are part of Android T."
|
|
|
|
|
@@ -301,31 +405,45 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
|
|
|
|
// If any of the following fail, then it is time to update the log message
|
|
|
|
|
// above.
|
|
|
|
|
EXPECT_EQ(ODK_MAJOR_VERSION, 17);
|
|
|
|
|
EXPECT_EQ(ODK_MINOR_VERSION, 5);
|
|
|
|
|
EXPECT_EQ(ODK_MINOR_VERSION, 6);
|
|
|
|
|
EXPECT_EQ(kCurrentAPI, 17u);
|
|
|
|
|
RecordWvProperty("test_major_version", std::to_string(ODK_MAJOR_VERSION));
|
|
|
|
|
RecordWvProperty("test_minor_version", std::to_string(ODK_MINOR_VERSION));
|
|
|
|
|
|
|
|
|
|
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
|
|
|
|
|
EXPECT_GT(level, OEMCrypto_Level_Unknown);
|
|
|
|
|
EXPECT_LE(level, OEMCrypto_Level3);
|
|
|
|
|
cout << " OEMCrypto Security Level is L" << level << endl;
|
|
|
|
|
RecordWvProperty("security_level", SecurityLevelName(level));
|
|
|
|
|
|
|
|
|
|
uint32_t version = OEMCrypto_APIVersion();
|
|
|
|
|
uint32_t minor_version = OEMCrypto_MinorAPIVersion();
|
|
|
|
|
cout << " OEMCrypto API version is " << version << "."
|
|
|
|
|
<< minor_version << endl;
|
|
|
|
|
if (OEMCrypto_SupportsUsageTable()) {
|
|
|
|
|
RecordWvProperty("major_version", std::to_string(version));
|
|
|
|
|
RecordWvProperty("minor_version", std::to_string(minor_version));
|
|
|
|
|
|
|
|
|
|
const bool supports_usage_tables = OEMCrypto_SupportsUsageTable();
|
|
|
|
|
if (supports_usage_tables) {
|
|
|
|
|
cout << " OEMCrypto supports usage tables" << endl;
|
|
|
|
|
} else {
|
|
|
|
|
cout << " OEMCrypto does not support usage tables" << endl;
|
|
|
|
|
}
|
|
|
|
|
RecordWvProperty("supports_usage_tables", BoolName(supports_usage_tables));
|
|
|
|
|
|
|
|
|
|
if (version >= 15) {
|
|
|
|
|
const uint32_t tier = OEMCrypto_ResourceRatingTier();
|
|
|
|
|
cout << " Resource Rating Tier: " << tier << endl;
|
|
|
|
|
RecordWvProperty("resource_rating_tier", std::to_string(tier));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (version >= 17) {
|
|
|
|
|
OEMCryptoResult sts = OEMCrypto_ProductionReady();
|
|
|
|
|
if (sts != OEMCrypto_SUCCESS) {
|
|
|
|
|
LOGW("Device is not production ready, returns %d", sts);
|
|
|
|
|
}
|
|
|
|
|
sts = OEMCrypto_SUCCESS;
|
|
|
|
|
RecordWvProperty("is_production_ready", BoolName(sts == OEMCrypto_SUCCESS));
|
|
|
|
|
|
|
|
|
|
std::string build_info;
|
|
|
|
|
size_t buf_length = 0;
|
|
|
|
|
sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length);
|
|
|
|
|
@@ -338,9 +456,13 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
|
|
|
|
build_info.resize(buf_length);
|
|
|
|
|
}
|
|
|
|
|
cout << " BuildInformation: " << build_info << endl;
|
|
|
|
|
RecordWvProperty("build_information", build_info);
|
|
|
|
|
|
|
|
|
|
OEMCrypto_WatermarkingSupport support = OEMCrypto_GetWatermarkingSupport();
|
|
|
|
|
cout << " WatermarkingSupport: " << support << endl;
|
|
|
|
|
RecordWvProperty("watermarking_support", WatermarkingSupportName(support));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ASSERT_GE(version, 8u);
|
|
|
|
|
ASSERT_LE(version, kCurrentAPI);
|
|
|
|
|
}
|
|
|
|
|
@@ -461,42 +583,12 @@ TEST_F(OEMCryptoClientTest, ResourceRatingAPI15) {
|
|
|
|
|
TEST_F(OEMCryptoClientTest, ProvisioningDeclaredAPI12) {
|
|
|
|
|
OEMCrypto_ProvisioningMethod provisioning_method =
|
|
|
|
|
OEMCrypto_GetProvisioningMethod();
|
|
|
|
|
cout << " Provisioning method = "
|
|
|
|
|
<< ProvisioningMethodName(provisioning_method) << endl;
|
|
|
|
|
const char* const name = ProvisioningMethodName(provisioning_method);
|
|
|
|
|
cout << " Provisioning method = " << name << endl;
|
|
|
|
|
RecordWvProperty("provisioning_method", name);
|
|
|
|
|
ASSERT_NE(OEMCrypto_ProvisioningError, provisioning_method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
|
|
|
|
switch (value) {
|
|
|
|
|
case HDCP_NONE:
|
|
|
|
|
return "No HDCP supported, no secure data path";
|
|
|
|
|
case HDCP_V1:
|
|
|
|
|
return "HDCP version 1.x";
|
|
|
|
|
case HDCP_V1_0:
|
|
|
|
|
return "HDCP version 1.0";
|
|
|
|
|
case HDCP_V1_1:
|
|
|
|
|
return "HDCP version 1.1";
|
|
|
|
|
case HDCP_V1_2:
|
|
|
|
|
return "HDCP version 1.2";
|
|
|
|
|
case HDCP_V1_3:
|
|
|
|
|
return "HDCP version 1.3";
|
|
|
|
|
case HDCP_V1_4:
|
|
|
|
|
return "HDCP version 1.4";
|
|
|
|
|
case HDCP_V2:
|
|
|
|
|
return "HDCP version 2.0";
|
|
|
|
|
case HDCP_V2_1:
|
|
|
|
|
return "HDCP version 2.1";
|
|
|
|
|
case HDCP_V2_2:
|
|
|
|
|
return "HDCP version 2.2";
|
|
|
|
|
case HDCP_V2_3:
|
|
|
|
|
return "HDCP version 2.3";
|
|
|
|
|
case HDCP_NO_DIGITAL_OUTPUT:
|
|
|
|
|
return "No HDCP device attached/using local display with secure path";
|
|
|
|
|
default:
|
|
|
|
|
return "<INVALID VALUE>";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(OEMCryptoClientTest, CheckHDCPCapabilityAPI09) {
|
|
|
|
|
OEMCryptoResult sts;
|
|
|
|
|
OEMCrypto_HDCP_Capability current, maximum;
|
|
|
|
|
@@ -506,6 +598,8 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapabilityAPI09) {
|
|
|
|
|
static_cast<unsigned int>(current), HDCPCapabilityAsString(current));
|
|
|
|
|
printf(" Maximum HDCP Capability: 0x%02x = %s.\n",
|
|
|
|
|
static_cast<unsigned int>(maximum), HDCPCapabilityAsString(maximum));
|
|
|
|
|
RecordWvProperty("hdcp_current", HDCPCapabilityName(current));
|
|
|
|
|
RecordWvProperty("hdcp_max", HDCPCapabilityName(maximum));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) {
|
|
|
|
|
@@ -514,11 +608,15 @@ TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) {
|
|
|
|
|
OEMCryptoResult current_result = OEMCrypto_GetCurrentSRMVersion(&version);
|
|
|
|
|
if (current_result == OEMCrypto_SUCCESS) {
|
|
|
|
|
printf(" Current SRM Version: %d.\n", version);
|
|
|
|
|
RecordWvProperty("srm_supported", BoolName(true));
|
|
|
|
|
RecordWvProperty("srm_version", std::to_string(version));
|
|
|
|
|
EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_GetCurrentSRMVersion(nullptr));
|
|
|
|
|
} else if (current_result == OEMCrypto_LOCAL_DISPLAY_ONLY) {
|
|
|
|
|
printf(" Current SRM Status: Local Display Only.\n");
|
|
|
|
|
RecordWvProperty("srm_supported", BoolName(false));
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result);
|
|
|
|
|
RecordWvProperty("srm_supported", BoolName(false));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -669,6 +767,7 @@ TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
|
|
|
|
OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum);
|
|
|
|
|
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
|
|
|
|
printf(" Max Number of Sessions: %zu.\n", maximum);
|
|
|
|
|
RecordWvProperty("max_number_of_sessions", std::to_string(maximum));
|
|
|
|
|
size_t required_max = GetResourceValue(kMaxConcurrentSession);
|
|
|
|
|
ASSERT_GE(maximum, required_max);
|
|
|
|
|
}
|
|
|
|
|
@@ -676,6 +775,7 @@ TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
|
|
|
|
TEST_F(OEMCryptoClientTest, CheckUsageTableSizeAPI16) {
|
|
|
|
|
const size_t maximum = OEMCrypto_MaximumUsageTableHeaderSize();
|
|
|
|
|
printf(" Max Usage Table Size: %zu.\n", maximum);
|
|
|
|
|
RecordWvProperty("max_usage_table_size", std::to_string(maximum));
|
|
|
|
|
// A maximum of 0 means the table is constrained by dynamic memory allocation.
|
|
|
|
|
if (maximum > 0) {
|
|
|
|
|
ASSERT_GE(maximum, RequiredUsageSize());
|
|
|
|
|
@@ -718,6 +818,7 @@ TEST_F(OEMCryptoClientTest, CheckDTCP2CapabilityAPI17) {
|
|
|
|
|
"DTCP2 is supported.\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
RecordWvProperty("dtcp2_capability", DTCP2CapabiityName(capability));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
@@ -1185,6 +1286,7 @@ TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) {
|
|
|
|
|
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
|
|
|
|
cout << " NormalGetDeviceId: dev_id = "
|
|
|
|
|
<< MaybeHex(dev_id, dev_id_len) << " len = " << dev_id_len << endl;
|
|
|
|
|
RecordWvProperty("device_id", wvutil::HexEncode(dev_id, dev_id_len));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @ingroup security
|
|
|
|
|
@@ -1226,8 +1328,12 @@ TEST_F(OEMCryptoKeyboxTest, NormalGetKeyData) {
|
|
|
|
|
sts = OEMCrypto_GetKeyData(key_data, &key_data_len);
|
|
|
|
|
|
|
|
|
|
uint32_t* data = reinterpret_cast<uint32_t*>(key_data);
|
|
|
|
|
const uint32_t system_id = htonl(data[1]);
|
|
|
|
|
const uint32_t version = htonl(data[0]);
|
|
|
|
|
printf(" NormalGetKeyData: system_id = %u = 0x%04X, version=%u\n",
|
|
|
|
|
htonl(data[1]), htonl(data[1]), htonl(data[0]));
|
|
|
|
|
system_id, system_id, version);
|
|
|
|
|
RecordWvProperty("system_id", std::to_string(system_id));
|
|
|
|
|
RecordWvProperty("key_data_version", std::to_string(version));
|
|
|
|
|
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1339,6 +1445,8 @@ TEST_F(OEMCryptoProv30Test, GetDeviceId) {
|
|
|
|
|
dev_id.resize(dev_id_len);
|
|
|
|
|
cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id)
|
|
|
|
|
<< " len = " << dev_id_len << endl;
|
|
|
|
|
RecordWvProperty("device_id",
|
|
|
|
|
wvutil::HexEncode(dev_id.data(), dev_id.size()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The OEM certificate must be valid.
|
|
|
|
|
@@ -1735,6 +1843,8 @@ TEST_F(OEMCryptoProv40Test, GetDeviceId) {
|
|
|
|
|
dev_id.resize(dev_id_len);
|
|
|
|
|
cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id)
|
|
|
|
|
<< " len = " << dev_id_len << endl;
|
|
|
|
|
RecordWvProperty("device_id",
|
|
|
|
|
wvutil::HexEncode(dev_id.data(), dev_id.size()));
|
|
|
|
|
// Device id should be stable. Query again.
|
|
|
|
|
std::vector<uint8_t> dev_id2(dev_id_len);
|
|
|
|
|
sts = OEMCrypto_GetDeviceID(dev_id2.data(), &dev_id_len);
|
|
|
|
|
@@ -4363,6 +4473,7 @@ TEST_P(OEMCryptoLicenseTest, MaxTotalKeysManySessions) {
|
|
|
|
|
TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
|
|
|
|
uint8_t patch_level = OEMCrypto_Security_Patch_Level();
|
|
|
|
|
printf(" Current Patch Level: %u.\n", patch_level);
|
|
|
|
|
RecordWvProperty("security_patch_level", std::to_string(patch_level));
|
|
|
|
|
{
|
|
|
|
|
Session s;
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
|
|
|
|
|