Catch null pst in OEMCrypto

This is a copy of
https://widevine-internal-review.googlesource.com/#/c/11030

It is an error for the key control block to have a nonzero replay
control flag and a null pst.  This CL adds unit tests to
oemcrypto_test to verify that oemcrypto checkes this.  A unit test is
also added for verifying that an offline license has a valid nonce the
first time it is loaded.

It also updates the reference implementation (mock) to check that the
pst is not empty when the replay control flag is nonzero.

It also updates the level 3 implementation to check that the pst is
not empty when the replay control flag is nonzero.

This change is compiled into the arm library, but because of
compilation errors, is not included in x86 or mips.

    Current Library Version:
    arm:  Level3 Library Aug 27 2014 18:42:40

bug: 16525204 OEMCrypto unit test for reloading offline license
bug: 16844305 Mock OEMCrypto does not catch null pst
Change-Id: Icdb090e80fc92522c187b26f30e5ba082f26363b
This commit is contained in:
Fred Gylys-Colwell
2014-09-03 11:46:10 -07:00
parent 5800ecc15e
commit e51f8ba7a1
5 changed files with 95 additions and 12 deletions

View File

@@ -4525,9 +4525,7 @@ class DISABLED_UsageTableTest : public DISABLED_GenericDRMTest,
void LoadOfflineLicense(Session& s, const std::string& pst) {
s.open();
s.GenerateDerivedKeys();
s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceOrEntry,
s.get_nonce(), pst);
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst);
s.EncryptAndSign();
s.LoadTestKeys(pst, new_mac_keys_);
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
@@ -4613,6 +4611,27 @@ TEST_P(DISABLED_UsageTableTest, RepeatOnlineLicense) {
}
}
// A license with non-zero replay control bits needs a valid pst..
TEST_P(DISABLED_UsageTableTest, OnlineEmptyPST) {
if (OEMCrypto_SupportsUsageTable()) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
Session s;
s.open();
s.GenerateDerivedKeys();
s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
s.get_nonce());
s.EncryptAndSign();
OEMCryptoResult sts = 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);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
s.close();
}
}
TEST_P(DISABLED_UsageTableTest, EmptyTable) {
if (OEMCrypto_SupportsUsageTable()) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
@@ -5178,9 +5197,8 @@ TEST_P(DISABLED_UsageTableTest, BadReloadOfflineLicense) {
Session s2;
s2.open();
s2.GenerateDerivedKeys();
s2.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceOrEntry,
s2.get_nonce(), pst);
s2.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry,
s2.get_nonce(), pst);
s2.EncryptAndSign();
uint8_t* pst_ptr = s2.encrypted_license().pst;
ASSERT_NE(OEMCrypto_SUCCESS,
@@ -5201,6 +5219,50 @@ TEST_P(DISABLED_UsageTableTest, BadReloadOfflineLicense) {
}
}
// An offline license should not load on the first call if the nonce is bad.
TEST_P(DISABLED_UsageTableTest, OfflineBadNonce) {
if (OEMCrypto_SupportsUsageTable()) {
std::string pst = "my_pst";
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
Session s;
s.open();
s.GenerateDerivedKeys();
s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceOrEntry,
42, pst);
s.EncryptAndSign();
uint8_t* pst_ptr = s.encrypted_license().pst;
OEMCryptoResult sts = 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(),
pst_ptr, pst.length());
ASSERT_NE(OEMCrypto_SUCCESS, sts);
s.close();
}
}
// An offline license needs a valid pst.
TEST_P(DISABLED_UsageTableTest, OfflineEmptyPST) {
if (OEMCrypto_SupportsUsageTable()) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
Session s;
s.open();
s.GenerateDerivedKeys();
s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceOrEntry,
s.get_nonce());
s.EncryptAndSign();
OEMCryptoResult sts = 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);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
s.close();
}
}
TEST_P(DISABLED_UsageTableTest, DeactivateOfflineLicense) {
if (OEMCrypto_SupportsUsageTable()) {
std::string pst = "my_pst";
@@ -5248,9 +5310,8 @@ TEST_P(DISABLED_UsageTableTest, BadRange) {
Session s;
s.open();
s.GenerateDerivedKeys();
s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceOrEntry,
s.get_nonce(), pst);
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry,
s.get_nonce(), pst);
s.EncryptAndSign();
uint8_t* pst_ptr = s.license().pst; // Bad: not in encrypted_license.
ASSERT_NE(