Unit Tests for Security Patch Level

Merge of widevine change http://go/wvgerrit/16249

This CL adds unit tests and reference code for the security patch
level, which is a new feature in OEMCrypto v11.  This CL also adjusts
the dynamic and static adapters to still run with devices that have a
v10 OEMCrypto.

The level 3 haystack code will be updated in a future CL.

bug: 26188985

Change-Id: I518ef46b4098cf3718fe0c0390bfb6825db4fb6b
This commit is contained in:
Fred Gylys-Colwell
2015-12-16 13:27:36 -08:00
parent 17faabee44
commit ce6d392041
13 changed files with 134 additions and 36 deletions

View File

@@ -443,6 +443,7 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
if (!usage_table) FilterOut(&filter, "*UsageTable*");
if (derive_key_method == NO_METHOD) FilterOut(&filter, "*SessionTest*");
if (api_version < 10) FilterOut(&filter, "*API10*");
if (api_version < 11) FilterOut(&filter, "*API11*");
// Performance tests take a long time. Filter them out if they are not
// specifically requested.
if (filter.find("Performance") == std::string::npos) {
@@ -717,7 +718,9 @@ class Session {
EXPECT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetRandom(license_.keys[i].control_iv,
sizeof(license_.keys[i].control_iv)));
if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
memcpy(license_.keys[i].control.verification, "kc11", 4);
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
memcpy(license_.keys[i].control.verification, "kc10", 4);
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
wvoec_mock::kControlReplayMask)) {
@@ -882,7 +885,7 @@ class Session {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = outputBuffer.data();
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
OEMCrypto_CENCEncryptPatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
@@ -2088,6 +2091,48 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) {
}
}
TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
uint8_t patch_level = OEMCrypto_Security_Patch_Level();
printf(" Current Patch Level: %u.\n", patch_level);
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.GenerateTestSessionKeys());
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, patch_level
<< wvoec_mock::kControlSecurityPatchLevelShift, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0));
if (patch_level < 0x3F) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.GenerateTestSessionKeys());
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, (patch_level+1)
<< wvoec_mock::kControlSecurityPatchLevelShift, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(OEMCrypto_ERROR_UNKNOWN_FAILURE, OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0));
}
if (patch_level > 0) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.GenerateTestSessionKeys());
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, (patch_level-1)
<< wvoec_mock::kControlSecurityPatchLevelShift, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0));
}
}
class SessionTestDecryptWithHDCP : public OEMCryptoSessionTests,
public WithParamInterface<int> {
public:
@@ -2243,7 +2288,7 @@ TEST_F(OEMCryptoSessionTests, DecryptPerformance) {
OEMCrypto_DestBufferDesc destBuffer;
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &output[0];
OEMCrypto_PatternDesc pattern;
OEMCrypto_CENCEncryptPatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
@@ -2361,7 +2406,7 @@ class OEMCryptoSessionTestsDecryptEdgeCases : public OEMCryptoSessionTests {
s.license().keys[0].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
OEMCrypto_PatternDesc pattern;
OEMCrypto_CENCEncryptPatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
@@ -2521,7 +2566,7 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencrypted) {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &outputBuffer[0];
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
OEMCrypto_CENCEncryptPatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;
@@ -2560,7 +2605,7 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencryptedNoKey) {
destBuffer.type = OEMCrypto_BufferType_Clear;
destBuffer.buffer.clear.address = &outputBuffer[0];
destBuffer.buffer.clear.max_length = outputBuffer.size();
OEMCrypto_PatternDesc pattern;
OEMCrypto_CENCEncryptPatternDesc pattern;
pattern.encrypt = 1; // TODO(fredgc): test other values.
pattern.skip = 0;
pattern.offset = 0;