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:
@@ -1093,7 +1093,12 @@ class Session {
|
||||
OEMCrypto_GetRandom(data->keys[i].key_iv, sizeof(data->keys[i].key_iv));
|
||||
OEMCrypto_GetRandom(data->keys[i].control_iv,
|
||||
sizeof(data->keys[i].control_iv));
|
||||
memcpy(data->keys[i].control.verification, "kctl", 4);
|
||||
if (control & (wvoec_mock::kControlHDCPVersionMask
|
||||
| wvoec_mock::kControlReplayMask)) {
|
||||
memcpy(data->keys[i].control.verification, "kc09", 4);
|
||||
} else {
|
||||
memcpy(data->keys[i].control.verification, "kctl", 4);
|
||||
}
|
||||
data->keys[i].control.duration = htonl(duration);
|
||||
data->keys[i].control.nonce = htonl(nonce);
|
||||
data->keys[i].control.control_bits = htonl(control);
|
||||
@@ -1601,6 +1606,39 @@ TEST_F(OEMCryptoClientTest, NormalGetKeyData) {
|
||||
testTearDown();
|
||||
}
|
||||
|
||||
const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
||||
switch(value) {
|
||||
case 0x0:
|
||||
return "No HDCP supported, no secure data path";
|
||||
case 0x1:
|
||||
return "HDCP version 1.0";
|
||||
case 0x2:
|
||||
return "HDCP version 2.0";
|
||||
case 0x3:
|
||||
return "HDCP version 2.1";
|
||||
case 0x4:
|
||||
return "HDCP version 2.2";
|
||||
case 0xFF:
|
||||
return "No HDCP device attached/using local display with secure path";
|
||||
default:
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, CheckHDCPCapability) {
|
||||
testSetUp();
|
||||
|
||||
OEMCryptoResult sts;
|
||||
OEMCrypto_HDCP_Capability current, maximum;
|
||||
sts = OEMCrypto_GetHDCPCapability(¤t, &maximum);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
printf(" Current HDCP Capability: 0x%02x = %s.\n", current,
|
||||
HDCPCapabilityAsString(current));
|
||||
printf(" Maximum HDCP Capability: 0x%02x = %s.\n", maximum,
|
||||
HDCPCapabilityAsString(maximum));
|
||||
testTearDown();
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, KeyboxValid) {
|
||||
bool success;
|
||||
success = init();
|
||||
@@ -2448,6 +2486,93 @@ TEST_F(DISABLED_TestKeybox, LoadKeysWithNoDerivedKeys) {
|
||||
testTearDown();
|
||||
}
|
||||
|
||||
class DISABLED_DecryptWithHDCP : public DISABLED_TestKeybox {
|
||||
public:
|
||||
void DecryptWithHDCP(OEMCrypto_HDCP_Capability version) {
|
||||
OEMCryptoResult sts;
|
||||
testSetUp();
|
||||
InstallKeybox(kDefaultKeybox, true);
|
||||
OEMCrypto_HDCP_Capability current, maximum;
|
||||
sts = OEMCrypto_GetHDCPCapability(¤t, &maximum);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
Session& s = createSession("ONE");
|
||||
s.open();
|
||||
s.GenerateDerivedKeys();
|
||||
s.LoadTestKeys(0, (version << wvoec_mock::kControlHDCPVersionShift)
|
||||
| wvoec_mock::kControlObserveHDCP |
|
||||
wvoec_mock::kControlHDCPRequired, 0);
|
||||
|
||||
// Select the key (from FillSimpleMessage)
|
||||
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
|
||||
sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts)
|
||||
<< "SelectKey failed with version = " << version;
|
||||
// Set up our expected input and output
|
||||
vector<uint8_t> encryptedData = wvcdm::a2b_hex(
|
||||
"ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462"
|
||||
"337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca"
|
||||
"46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8"
|
||||
"efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913"
|
||||
"00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07"
|
||||
"cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c"
|
||||
"74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb"
|
||||
"fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b");
|
||||
vector<uint8_t> encryptionIv = wvcdm::a2b_hex(
|
||||
"719dbcb253b2ec702bb8c1b1bc2f3bc6");
|
||||
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
|
||||
"19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626"
|
||||
"fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e"
|
||||
"e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0"
|
||||
"1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17"
|
||||
"a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244"
|
||||
"ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280"
|
||||
"a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5"
|
||||
"de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b");
|
||||
|
||||
// Describe the output
|
||||
uint8_t outputBuffer[256];
|
||||
memset(outputBuffer, 0, sizeof(outputBuffer));
|
||||
OEMCrypto_DestBufferDesc destBuffer;
|
||||
destBuffer.type = OEMCrypto_BufferType_Clear;
|
||||
destBuffer.buffer.clear.address = outputBuffer;
|
||||
destBuffer.buffer.clear.max_length = sizeof(outputBuffer);
|
||||
|
||||
// Decrypt the data
|
||||
sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0],
|
||||
encryptedData.size(), true, &encryptionIv[0], 0,
|
||||
&destBuffer,
|
||||
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample);
|
||||
if (version > current) {
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INSUFFICIENT_HDCP, sts)
|
||||
<< "DecryptCTR did not fail with HDCP version = " << (int)version
|
||||
<< ", min=" << (int)current;
|
||||
EXPECT_NE(0, memcmp(&unencryptedData[0], outputBuffer,
|
||||
unencryptedData.size()))
|
||||
<< "DecryptCTR decrypted with HDCP version = " << (int)version
|
||||
<< ", min=" << (int)current;
|
||||
} else {
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, sts)
|
||||
<< "DecryptCTR failed with HDCP version = " << (int)version
|
||||
<< ", min=" << (int)current;
|
||||
EXPECT_EQ(0, memcmp(&unencryptedData[0], outputBuffer,
|
||||
unencryptedData.size()))
|
||||
<< "DecryptCTR failed with HDCP version = " << (int)version
|
||||
<< ", min=" << (int)current;
|
||||
}
|
||||
s.close();
|
||||
testTearDown();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(DISABLED_DecryptWithHDCP, DecryptWithHDCP) {
|
||||
DecryptWithHDCP(1); // Version 1.0
|
||||
DecryptWithHDCP(2); // Version 2.0
|
||||
DecryptWithHDCP(3); // Version 2.1
|
||||
DecryptWithHDCP(4); // Version 2.2
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Load, Refresh Keys Test
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user