Test Key Control Block with HDCP Version

This is a copy of the Widevine CL:
https://widevine-internal-review.googlesource.com/#/c/9480/

This change is part of OEMCrypto API version 9.

This CL adds verification that a key control block which requires a
specific version of HDCP can be loaded.  Also, if secure data path is
not set, it verifies that data is still decrypted.

This CL also adds test that verify DecryptCTR fails when the current
HDCP version is below that in the key control block.  The expected
error is OEMCrypto_ERROR_INSUFFICIENT_HDCP.  This error code is newly
introduced in this CL.

This is one attempt to clarify HDCP, as specified in b/13626021, and
is a slight modification from previous behavior for the mock and the
level 3 haystacked code.

This CL also tests the two valid verification codes "kctl"
and "kc09".

bug: 13626021
Change-Id: If380709d2306a3489470b29fb148a45b609b089d
This commit is contained in:
Fred Gylys-Colwell
2014-04-10 16:22:25 -07:00
parent 45dc595f92
commit 026a04701e
9 changed files with 188 additions and 16 deletions

View File

@@ -317,7 +317,6 @@ bool SessionContext::GenerateRSASignature(const uint8_t* message,
} else { // Bad RSA_Padding_Scheme
return false;
}
return true;
}
@@ -366,7 +365,22 @@ bool SessionContext::ParseKeyControl(
LOGD(" valid: %d", key_control_block.valid());
LOGD(" duration: %d", key_control_block.duration());
LOGD(" nonce: %08X", key_control_block.nonce());
LOGD(" magic: %08X", key_control_block.verification());
LOGD(" bits: %08X", key_control_block.control_bits());
switch(key_control_block.control_bits() & kControlReplayMask) {
case kControlNonceRequired:
LOGD(" bits kControlReplay kControlNonceRequired.");
break;
case kControlNonceOrEntry:
LOGD(" bits kControlReplay kControlNonceOrEntry.");
break;
default:
LOGD(" bits kControlReplay unset.");
break;
}
LOGD(" bits kControlKDCPVersion 0x%02x.",
(key_control_block.control_bits() & kControlHDCPVersionMask)
>> kControlHDCPVersionShift);
LOGD(" bit kControlAllowEncrypt %s.",
(key_control_block.control_bits() & kControlAllowEncrypt) ? "set" : "unset");
LOGD(" bit kControlAllowDecrypt %s.",
@@ -870,6 +884,12 @@ CryptoEngine::CryptoEngine() :
ce_state_(CE_INITIALIZED), current_session_(NULL) {
valid_ = true;
ERR_load_crypto_strings();
// These are made up numbers, just for illustration.
current_hdcp_capability_ = 0x1;
maximum_hdcp_capability_ = 0x2;
// If local_display_ is true, we pretend we are using a built-in display,
// instead of HDMI or WiFi output.
local_display_ = false;
}
CryptoEngine::~CryptoEngine() {
@@ -958,11 +978,20 @@ OEMCryptoResult CryptoEngine::DecryptCTR(SessionContext* session,
return OEMCrypto_ERROR_DECRYPT_FAILED;
}
}
if (control.control_bits() & kControlHDCPRequired) {
// For reference implementation, we do not implement any HDCP.
LOGE("[DecryptCTR(): DECRYPT FAILED: HDCP Required]");
return OEMCrypto_ERROR_DECRYPT_FAILED;
if (!local_display_) { // Only look at HDCP if the display is not local.
if (control.control_bits() & kControlHDCPRequired) {
uint8_t required_hdcp
= (control.control_bits() & kControlHDCPVersionMask)
>> kControlHDCPVersionShift;
// For reference implementation, we pretend we can handle the current
// HDCP version.
if (required_hdcp > current_hdcp_capability()
|| current_hdcp_capability() == 0) {
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
}
}
}
if (control.duration() > 0) {
if (control.duration() < session->CurrentTimer()) {
LOGE("[DecryptCTR(): KEY_EXPIRED]");