From 48b8fa860e21cbe0f33c112011e18900c1f093ff Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Tue, 18 Sep 2018 16:41:36 -0700 Subject: [PATCH] Parameterize "forbid analog" in mod mock Merge from Widevine repo of http://go/wvgerrit/43660 This CL adds parameters to the mod mock to control various analog output behaviour. bug: 38005556 Change-Id: I308b300a2dd73f6bb7fb798d56c2c631a09f3765 --- .../oemcrypto/ref/src/oemcrypto_engine_ref.h | 14 +++++++++++ .../oemcrypto/ref/src/oemcrypto_ref.cpp | 11 ++++++-- .../oemcrypto/ref/src/oemcrypto_session.cpp | 25 ++++++++++++++----- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index ecf816a9..60c9d096 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -94,6 +94,20 @@ class CryptoEngine { // Returns the max HDCP version supported. virtual OEMCrypto_HDCP_Capability config_maximum_hdcp_capability(); + // Return true if there might be analog video output enabled. + virtual bool analog_display_active() { + return !config_local_display_only(); + } + + // Return true if there is an analog display, and CGMS A is turned on. + virtual bool cgms_a_active() { return false; } + + // Return the analog output flags. + virtual uint32_t analog_output_flags() { + return config_local_display_only() ? OEMCrypto_No_Analog_Output + : OEMCrypto_Supports_Analog_Output; + } + UsageTable& usage_table() { return *(usage_table_.get()); } wvcdm::FileSystem* file_system() { return file_system_.get(); } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index 3b5ee058..a3941385 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -1140,11 +1140,18 @@ extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability( } extern "C" uint32_t OEMCrypto_GetAnalogOutputFlags() { - // TODO(b/69867568, fredgc): parameterize this. - return 0; + if (!crypto_engine) { + LOGE("OEMCrypto_GetAnalogOutputFlags: OEMCrypto Not Initialized."); + return 0; + } + return crypto_engine->analog_output_flags(); } extern "C" bool OEMCrypto_SupportsUsageTable() { + if (!crypto_engine) { + LOGE("OEMCrypto_SupportsUsageTable: OEMCrypto Not Initialized."); + return 0; + } bool supports_usage = crypto_engine->config_supports_usage_table(); return supports_usage; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index b1c8d2a6..b6a4350e 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -917,8 +917,7 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string, } } if (!ce_->config_local_display_only()) { - // Only look at HDCP and Analog restrictions if the display can be - // non-local. + // Only look at HDCP restrictions if the display can be non-local. if (control.control_bits() & wvoec::kControlHDCPRequired) { uint8_t required_hdcp = (control.control_bits() & wvoec::kControlHDCPVersionMask) >> @@ -934,10 +933,24 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string, } } } - if (!ce_->config_local_display_only() || - buffer_type == OEMCrypto_BufferType_Clear) { - if (control.control_bits() & wvoec::kControlDisableAnalogOutput) { - LOGE("[%s(): control bit says disable analog.", log_string.c_str()); + // If the output buffer is clear, then we cannot control whether the output is + // an active analog display. In that case, return an error if analog displays + // should be disabled. + if ((control.control_bits() & wvoec::kControlDisableAnalogOutput) && + (ce_->analog_display_active() || + (buffer_type == OEMCrypto_BufferType_Clear))) { + LOGE("[%s(): control bit says disable analog.", log_string.c_str()); + return OEMCrypto_ERROR_ANALOG_OUTPUT; + } + // Check if CGMS is required. + if (control.control_bits() & wvoec::kControlCGMSMask) { + // We can't control CGMS for a clear buffer. + if (buffer_type == OEMCrypto_BufferType_Clear) { + LOGE("[%s(): CGMS required, but buffer is clear.", log_string.c_str()); + return OEMCrypto_ERROR_ANALOG_OUTPUT; + } + if ( ce_->analog_display_active() && !ce_->cgms_a_active()) { + LOGE("[%s(): control bit says CGMS required.", log_string.c_str()); return OEMCrypto_ERROR_ANALOG_OUTPUT; } }