Merge "Added CDM support for Watermarking reporting." into tm-dev

This commit is contained in:
Alex Dale
2022-04-02 01:07:07 +00:00
committed by Android (Google) Code Review
22 changed files with 191 additions and 9 deletions

View File

@@ -216,6 +216,11 @@ class CryptoSession {
std::string* info);
virtual bool GetBuildInformation(std::string* info);
virtual bool GetWatermarkingSupport(CdmWatermarkingSupport* support);
virtual bool GetWatermarkingSupport(
RequestedSecurityLevel requested_security_level,
CdmWatermarkingSupport* support);
virtual bool GetMaximumUsageTableEntries(
RequestedSecurityLevel security_level, size_t* number_of_entries);

View File

@@ -70,6 +70,8 @@ size_t OEMCrypto_MaximumUsageTableHeaderSize(RequestedSecurityLevel level);
OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(uint8_t* public_cert,
size_t* public_cert_length,
RequestedSecurityLevel level);
OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(
RequestedSecurityLevel level);
} // namespace wvcdm
/* The following functions are deprecated in OEMCrypto v13. They are defined

View File

@@ -110,6 +110,7 @@ static const std::string QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES =
"AnalogOutputCapabilities";
static const std::string QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT =
"CanDisableAnalogOutput";
static const std::string QUERY_KEY_WATERMARKING_SUPPORT = "WatermarkingSupport";
static const std::string QUERY_VALUE_TRUE = "True";
static const std::string QUERY_VALUE_FALSE = "False";
@@ -137,6 +138,9 @@ static const std::string QUERY_VALUE_OEM_CERTIFICATE = "OEMCertificate";
static const std::string QUERY_VALUE_CGMS_A = "CGMS-A";
static const std::string QUERY_VALUE_BOOT_CERTIFICATE_CHAIN =
"BootCertificateChain";
static const std::string QUERY_VALUE_NOT_SUPPORTED = "NotSupported";
static const std::string QUERY_VALUE_CONFIGURABLE = "Configurable";
static const std::string QUERY_VALUE_ALWAYS_ON = "AlwaysOn";
static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4";
static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4";

View File

@@ -593,6 +593,12 @@ enum CdmProvisioningStatus : int32_t {
kNeedsOemCertProvisioning,
};
enum CdmWatermarkingSupport : int32_t {
kWatermarkingNotSupported,
kWatermarkingConfigurable,
kWatermarkingAlwaysOn
};
class CdmKeyAllowedUsage {
public:
CdmKeyAllowedUsage() { Clear(); }
@@ -835,6 +841,7 @@ const char* CdmSecurityLevelToString(CdmSecurityLevel security_level);
const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type);
const char* RequestedSecurityLevelToString(
RequestedSecurityLevel security_level);
const char* CdmWatermarkingSupportToString(CdmWatermarkingSupport support);
// Converts a generic, unknown enum value to a string representation
// containing its numeric value.
// The pointer returned from this function is thread_local.

View File

@@ -795,6 +795,28 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level,
}
return NO_ERROR;
}
if (query_token == QUERY_KEY_WATERMARKING_SUPPORT) {
CdmWatermarkingSupport support;
if (!crypto_session->GetWatermarkingSupport(security_level, &support)) {
// Assume not supported.
support = kWatermarkingNotSupported;
}
switch (support) {
case kWatermarkingNotSupported:
*query_response = QUERY_VALUE_NOT_SUPPORTED;
break;
case kWatermarkingConfigurable:
*query_response = QUERY_VALUE_CONFIGURABLE;
break;
case kWatermarkingAlwaysOn:
*query_response = QUERY_VALUE_ALWAYS_ON;
break;
default:
LOGW("Unknown watermarking support: %d", static_cast<int>(support));
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
CdmResponseType status;
M_TIME(status = crypto_session->Open(security_level),

View File

@@ -343,6 +343,28 @@ CdmResponseType ClientIdentification::Prepare(
}
}
if (is_license_request_) {
CdmWatermarkingSupport support;
if (!crypto_session_->GetWatermarkingSupport(&support)) {
// Assume not supported.
support = kWatermarkingNotSupported;
}
switch (support) {
case kWatermarkingNotSupported:
client_capabilities->set_watermarking_support(
ClientCapabilities::WATERMARKING_NOT_SUPPORTED);
break;
case kWatermarkingConfigurable:
client_capabilities->set_watermarking_support(
ClientCapabilities::WATERMARKING_CONFIGURABLE);
break;
case kWatermarkingAlwaysOn:
client_capabilities->set_watermarking_support(
ClientCapabilities::WATERMARKING_ALWAYS_ON);
break;
}
}
return NO_ERROR;
}

View File

@@ -2309,6 +2309,41 @@ bool CryptoSession::GetBuildInformation(RequestedSecurityLevel security_level,
return true;
}
bool CryptoSession::GetWatermarkingSupport(CdmWatermarkingSupport* support) {
RETURN_IF_NOT_OPEN(false);
return GetWatermarkingSupport(requested_security_level_, support);
}
bool CryptoSession::GetWatermarkingSupport(
RequestedSecurityLevel security_level, CdmWatermarkingSupport* support) {
LOGV("security_level = %s", RequestedSecurityLevelToString(security_level));
RETURN_IF_UNINITIALIZED(false);
RETURN_IF_NULL(support, false);
const OEMCrypto_WatermarkingSupport oec_support = WithOecReadLock(
"GetWatermarkingSupport",
[&] { return OEMCrypto_GetWatermarkingSupport(security_level); });
switch (oec_support) {
case OEMCrypto_WatermarkingNotSupported:
*support = kWatermarkingNotSupported;
break;
case OEMCrypto_WatermarkingConfigurable:
*support = kWatermarkingConfigurable;
break;
case OEMCrypto_WatermarkingAlwaysOn:
*support = kWatermarkingAlwaysOn;
break;
case OEMCrypto_WatermarkingError:
default:
LOGE("GetWatermarkingSupport error: security_level = %s, result = %d",
RequestedSecurityLevelToString(security_level),
static_cast<int>(oec_support));
metrics_->oemcrypto_watermarking_support_.SetError(oec_support);
return false;
}
metrics_->oemcrypto_watermarking_support_.Record(oec_support);
return true;
}
bool CryptoSession::GetMaximumUsageTableEntries(
RequestedSecurityLevel security_level, size_t* number_of_entries) {
LOGV("Getting maximum usage table entries: security_level = %s",

View File

@@ -908,6 +908,13 @@ message ClientIdentification {
ANALOG_OUTPUT_SUPPORTS_CGMS_A = 3;
}
enum WatermarkingSupport {
WATERMARKING_SUPPORT_UNKNOWN = 0;
WATERMARKING_NOT_SUPPORTED = 1;
WATERMARKING_CONFIGURABLE = 2;
WATERMARKING_ALWAYS_ON = 3;
}
optional bool client_token = 1 [default = false];
optional bool session_token = 2 [default = false];
optional bool video_resolution_constraints = 3 [default = false];
@@ -932,6 +939,10 @@ message ClientIdentification {
// the resource rating is unavailable or reporting erroneous values
// for that device.
optional uint32 resource_rating_tier = 12 [default = 0];
// Watermarking support of OEMCrypto was introduced in v17.
// Support is optional.
// Value is only required to be set for license requests.
optional WatermarkingSupport watermarking_support = 13;
}
message ClientCredentials {

View File

@@ -1896,6 +1896,17 @@ OEMCryptoResult OEMCrypto_SetDebugIgnoreKeyboxCount(uint32_t count) {
OEMCryptoResult OEMCrypto_SetAllowTestKeybox(bool allow) {
return SetAllowTestKeybox(allow);
}
OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(
wvcdm::RequestedSecurityLevel level) {
if (!gAdapter) return OEMCrypto_WatermarkingError;
const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level);
if (!fcn) return OEMCrypto_WatermarkingError;
if (fcn->version < 17) return OEMCrypto_WatermarkingNotSupported;
if (fcn->GetWatermarkingSupport == nullptr)
return OEMCrypto_WatermarkingError;
return fcn->GetWatermarkingSupport();
}
} // namespace wvcdm
extern "C" OEMCryptoResult OEMCrypto_SetSandbox(const uint8_t* sandbox_id,
@@ -3403,12 +3414,7 @@ extern "C" OEMCryptoResult OEMCrypto_GetDTCP2Capability(
return fcn->GetDTCP2Capability(capability);
}
extern "C" OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport() {
if (!gAdapter) return OEMCrypto_WatermarkingError;
const FunctionPointers* fcn = gAdapter->GetFunctionPointers(kLevelDefault);
if (!fcn) return OEMCrypto_WatermarkingError;
if (fcn->version < 17) return OEMCrypto_WatermarkingError;
if (fcn->GetWatermarkingSupport == nullptr)
return OEMCrypto_WatermarkingError;
return fcn->GetWatermarkingSupport();
extern "C" OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(
void) {
return wvcdm::OEMCrypto_GetWatermarkingSupport(kLevelDefault);
}

View File

@@ -119,6 +119,18 @@ const char* RequestedSecurityLevelToString(
return UnknownValueRep(security_level);
}
const char* CdmWatermarkingSupportToString(CdmWatermarkingSupport support) {
switch (support) {
case kWatermarkingNotSupported:
return QUERY_VALUE_NOT_SUPPORTED.c_str();
case kWatermarkingConfigurable:
return QUERY_VALUE_CONFIGURABLE.c_str();
case kWatermarkingAlwaysOn:
return QUERY_VALUE_ALWAYS_ON.c_str();
}
return UnknownValueRep(support);
}
const char* UnknownEnumValueToString(int value) {
snprintf(tl_unknown_rep_buf, sizeof(tl_unknown_rep_buf), "<unknown(%d)>",
value);

View File

@@ -135,6 +135,7 @@ const std::string kFakeKeyTooLong =
a2bs_hex("d4bc8605d662878a46adb2adb6bf3c0b30a54a0c2f");
const std::string kFakeKeyTooShort = a2bs_hex("06e247e7f924208011");
const std::string kFakeIv = a2bs_hex("3d515a3ee0be1687080ac59da9e0d69a");
const std::string kFakeBuildInfo = "Mock Crypto Session - License Test";
class MockCryptoSession : public TestCryptoSession {
public:
@@ -154,6 +155,11 @@ class MockCryptoSession : public TestCryptoSession {
MOCK_METHOD(CdmResponseType, LoadEntitledContentKeys,
(const std::vector<CryptoKey>& key_array), (override));
MOCK_METHOD(bool, GetResourceRatingTier, (uint32_t*), (override));
MOCK_METHOD(bool, GetWatermarkingSupport, (CdmWatermarkingSupport*),
(override));
MOCK_METHOD(bool, GetBuildInformation, (std::string*), (override));
CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; }
};
class MockPolicyEngine : public PolicyEngine {
@@ -318,6 +324,11 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
.WillOnce(DoAll(SetArgPointee<1>(kFakeCoreMessage),
SetArgPointee<2>(kLicenseRequestSignature),
Return(NO_ERROR)));
EXPECT_CALL(*crypto_session_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kFakeBuildInfo), Return(true)));
EXPECT_CALL(*crypto_session_, GetWatermarkingSupport(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(kWatermarkingConfigurable), Return(true)));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(true, kDefaultServiceCertificate,
@@ -385,6 +396,8 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
ClientCapabilities::ECC_SECP384R1,
ClientCapabilities::ECC_SECP521R1));
EXPECT_TRUE(client_capabilities.has_resource_rating_tier());
EXPECT_EQ(client_capabilities.watermarking_support(),
ClientCapabilities::WATERMARKING_CONFIGURABLE);
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =
@@ -442,6 +455,11 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) {
.WillOnce(DoAll(SetArgPointee<1>(kFakeCoreMessage),
SetArgPointee<2>(kLicenseRequestSignature),
Return(NO_ERROR)));
EXPECT_CALL(*crypto_session_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kFakeBuildInfo), Return(true)));
EXPECT_CALL(*crypto_session_, GetWatermarkingSupport(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(kWatermarkingNotSupported), Return(true)));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(true, kDefaultServiceCertificate,
@@ -509,6 +527,8 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) {
ClientCapabilities::ECC_SECP384R1,
ClientCapabilities::ECC_SECP521R1));
EXPECT_EQ(resource_rating_tier, client_capabilities.resource_rating_tier());
EXPECT_EQ(client_capabilities.watermarking_support(),
ClientCapabilities::WATERMARKING_NOT_SUPPORTED);
// Verify Content Identification
const LicenseRequest_ContentIdentification& content_id =