OEMCrypto Backwards Compatible Usage Table

Merge from widevine of http://go/wvgerrit/23283

This CL adds the backwards compatiblity functions to the new usage
tables in the oemcrypto mock reference code.

b/31458046
b/32554171

Change-Id: I04901d95aceb8910406f7c514c26c29c2c575322
This commit is contained in:
Fred Gylys-Colwell
2017-01-27 15:22:55 -08:00
parent d06fa606c7
commit 9e153438db
14 changed files with 1151 additions and 350 deletions

View File

@@ -332,6 +332,7 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
license_.keys[i].cipher_mode = OEMCrypto_CipherMode_CTR;
}
memcpy(license_.pst, pst.c_str(), min(sizeof(license_.pst), pst.length()));
pst_ = pst;
}
void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits,
@@ -857,6 +858,20 @@ void Session::LoadUsageEntry(uint32_t index, const vector<uint8_t>& buffer) {
OEMCrypto_LoadUsageEntry(session_id(), index, &buffer[0], buffer.size()));
}
void Session::MoveUsageEntry(uint32_t new_index,
std::vector<uint8_t>* header_buffer,
OEMCryptoResult expect_result) {
ASSERT_NO_FATAL_FAILURE(open());
ASSERT_NO_FATAL_FAILURE(ReloadUsageEntry());
ASSERT_EQ(expect_result, OEMCrypto_MoveEntry(session_id(), new_index));
if (expect_result == OEMCrypto_SUCCESS) {
usage_entry_number_ = new_index;
ASSERT_NO_FATAL_FAILURE(UpdateUsageEntry(header_buffer));
}
ASSERT_NO_FATAL_FAILURE(close());
}
void Session::GenerateReport(const std::string& pst, bool expect_success,
Session* other) {
ASSERT_TRUE(open_);
@@ -897,6 +912,84 @@ void Session::GenerateReport(const std::string& pst, bool expect_success,
EXPECT_EQ(0, memcmp(pst.c_str(), pst_report().pst(), pst.length()));
}
void Session::VerifyPST(const Test_PST_Report& expected) {
wvcdm::Unpacked_PST_Report computed = pst_report();
EXPECT_EQ(expected.status, computed.status());
char* pst_ptr = reinterpret_cast<char *>(computed.pst());
std::string computed_pst(pst_ptr, pst_ptr + computed.pst_length());
ASSERT_EQ(expected.pst, computed_pst);
EXPECT_NEAR(expected.seconds_since_license_received,
computed.seconds_since_license_received(),
kLicenseReceivedTimeTolerance);
// Decrypt times only valid on licenses that have been active.
if (expected.status == kActive || expected.status == kInactiveUsed) {
EXPECT_NEAR(expected.seconds_since_first_decrypt,
computed.seconds_since_first_decrypt(),
kUsageTableTimeTolerance);
EXPECT_NEAR(expected.seconds_since_last_decrypt,
computed.seconds_since_last_decrypt(),
kUsageTableTimeTolerance);
}
std::vector<uint8_t> signature(SHA_DIGEST_LENGTH);
unsigned int md_len = SHA_DIGEST_LENGTH;
if (!HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
&pst_report_buffer_[0] + SHA_DIGEST_LENGTH,
pst_report_buffer_.size() - SHA_DIGEST_LENGTH,
&signature[0], &md_len)) {
cout << "Error computing HMAC.\n";
dump_openssl_error();
}
EXPECT_EQ(0, memcmp(computed.signature(), &signature[0],
SHA_DIGEST_LENGTH));
}
static int64_t MaybeAdjustTime(int64_t t, time_t now) {
int64_t k10Minutes = 60 * 10; // in seconds.
if (t > k10Minutes) return now - t;
return t;
}
void Session::GenerateVerifyReport(const std::string& pst,
OEMCrypto_Usage_Entry_Status status,
int64_t time_license_received,
int64_t time_first_decrypt,
int64_t time_last_decrypt) {
ASSERT_NO_FATAL_FAILURE(GenerateReport(pst));
Test_PST_Report expected(pst, status);
time_t now = time(NULL);
expected.seconds_since_license_received =
MaybeAdjustTime(time_license_received, now);
expected.seconds_since_first_decrypt =
MaybeAdjustTime(time_first_decrypt, now);
expected.seconds_since_last_decrypt = MaybeAdjustTime(time_last_decrypt, now);
ASSERT_NO_FATAL_FAILURE(VerifyPST(expected));
}
void Session::CreateOldEntry(const Test_PST_Report& report) {
OEMCryptoResult result = OEMCrypto_CreateOldUsageEntry(
report.seconds_since_license_received,
report.seconds_since_first_decrypt,
report.seconds_since_last_decrypt,
report.status, &mac_key_server_[0],
&mac_key_client_[0],
reinterpret_cast<const uint8_t*>(report.pst.c_str()),
report.pst.length());
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;
ASSERT_EQ(OEMCrypto_SUCCESS, result);
}
void Session::CopyAndVerifyOldEntry(const Test_PST_Report& report,
std::vector<uint8_t>* header_buffer) {
ASSERT_NO_FATAL_FAILURE(CreateNewUsageEntry());
OEMCryptoResult result = OEMCrypto_CopyOldUsageEntry(
session_id(), reinterpret_cast<const uint8_t*>(report.pst.c_str()),
report.pst.length());
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;
ASSERT_NO_FATAL_FAILURE(UpdateUsageEntry(header_buffer));
ASSERT_NO_FATAL_FAILURE(GenerateReport(report.pst));
ASSERT_NO_FATAL_FAILURE(VerifyPST(report));
}
const uint8_t* Session::message_ptr() {
return reinterpret_cast<const uint8_t*>(&encrypted_license());
}