More OEMCrypto Usage Table Unit Tests
Merge from widevine repo of http://go/wvgerrit/23421 This CL adds some more unit tests for big usage tables, and corrects a problem found in the reference code. Change-Id: Iae9a4406d79a13362223c2b4da7365b845d92382
This commit is contained in:
@@ -948,7 +948,6 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
||||
LOGE("[_RewrapDeviceRSAKey30(): RAND_bytes failed.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
// TODO(fredgc): Don't use the keybox to encrypt the wrapped RSA key.
|
||||
const std::vector<uint8_t> context(
|
||||
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
||||
// Generate mac and encryption keys for encrypting the signature.
|
||||
@@ -1157,7 +1156,6 @@ extern "C" OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(
|
||||
dump_hex("iv", wrapped->iv, sizeof(wrapped->iv));
|
||||
}
|
||||
}
|
||||
// TODO(fredgc): Don't use the keybox to encrypt the wrapped RSA key.
|
||||
if (!crypto_engine->ValidRootOfTrust()) {
|
||||
LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_KEYBOX_INVALID]");
|
||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
||||
|
||||
@@ -116,7 +116,7 @@ void UsageTableEntry::Deactivate(const std::vector<uint8_t>& pst) {
|
||||
} else if (data_.status == kActive) {
|
||||
data_.status = kInactiveUsed;
|
||||
}
|
||||
forbid_report_ = false;
|
||||
forbid_report_ = true;
|
||||
data_.generation_number++;
|
||||
usage_table_->IncrementGeneration();
|
||||
}
|
||||
@@ -130,13 +130,13 @@ OEMCryptoResult UsageTableEntry::ReportUsage(const std::vector<uint8_t>& pst,
|
||||
pst.size() != data_.pst_length) {
|
||||
LOGE("ReportUsage: bad pst length = %d, should be %d.",
|
||||
pst.size(), data_.pst_length);
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
return OEMCrypto_ERROR_WRONG_PST;
|
||||
}
|
||||
if (memcmp(&pst[0], data_.pst, data_.pst_length)) {
|
||||
LOGE("ReportUsage: wrong pst %s, should be %s.",
|
||||
wvcdm::b2a_hex(pst).c_str(),
|
||||
wvcdm::HexEncode(data_.pst, data_.pst_length).c_str());
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
return OEMCrypto_ERROR_WRONG_PST;
|
||||
}
|
||||
size_t length_needed = wvcdm::Unpacked_PST_Report::report_size(pst.size());
|
||||
if (*buffer_length < length_needed) {
|
||||
@@ -658,7 +658,6 @@ bool UsageTable::LoadGenerationNumber(bool or_make_new_one) {
|
||||
if (or_make_new_one) {
|
||||
RAND_bytes(reinterpret_cast<uint8_t*>(&master_generation_number_),
|
||||
sizeof(int64_t));
|
||||
master_generation_number_ = 0; // TODO(fredgc): remove after debugging.
|
||||
return true;
|
||||
}
|
||||
LOGE("UsageTable: File open failed: %s (clearing table)", path.c_str());
|
||||
|
||||
@@ -872,7 +872,8 @@ void Session::MoveUsageEntry(uint32_t new_index,
|
||||
ASSERT_NO_FATAL_FAILURE(close());
|
||||
}
|
||||
|
||||
void Session::GenerateReport(const std::string& pst, bool expect_success,
|
||||
void Session::GenerateReport(const std::string& pst,
|
||||
OEMCryptoResult expected_result,
|
||||
Session* other) {
|
||||
ASSERT_TRUE(open_);
|
||||
if (other) { // If other is specified, copy mac keys.
|
||||
@@ -883,7 +884,7 @@ void Session::GenerateReport(const std::string& pst, bool expect_success,
|
||||
OEMCryptoResult sts = OEMCrypto_ReportUsage(
|
||||
session_id(), reinterpret_cast<const uint8_t*>(pst.c_str()), pst.length(),
|
||||
&pst_report_buffer_[0], &length);
|
||||
if (expect_success) {
|
||||
if (expected_result == OEMCrypto_SUCCESS) {
|
||||
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
|
||||
}
|
||||
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
@@ -893,12 +894,11 @@ void Session::GenerateReport(const std::string& pst, bool expect_success,
|
||||
sts = OEMCrypto_ReportUsage(session_id(),
|
||||
reinterpret_cast<const uint8_t*>(pst.c_str()),
|
||||
pst.length(), &pst_report_buffer_[0], &length);
|
||||
if (!expect_success) {
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_EQ(expected_result, sts);
|
||||
if (expected_result != OEMCrypto_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
ASSERT_EQ(pst_report_buffer_.size(), length);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
vector<uint8_t> computed_signature(SHA_DIGEST_LENGTH);
|
||||
unsigned int sig_len = SHA_DIGEST_LENGTH;
|
||||
HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(),
|
||||
|
||||
@@ -286,11 +286,12 @@ class Session {
|
||||
const vector<uint8_t>& encrypted_usage_entry() const {
|
||||
return encrypted_usage_entry_;
|
||||
}
|
||||
// Generates a usage report for the specified pst. If expect_success is true,
|
||||
// Generates a usage report for the specified pst. If there is success,
|
||||
// the report's signature is verified, and several fields are given sanity
|
||||
// checks. If other is not null, then the mac keys are copied from other in
|
||||
// order to verify signatures.
|
||||
void GenerateReport(const std::string& pst, bool expect_success = true,
|
||||
void GenerateReport(const std::string& pst,
|
||||
OEMCryptoResult expected_result = OEMCrypto_SUCCESS,
|
||||
Session* other = 0);
|
||||
// Move this usage entry to a new index.
|
||||
void MoveUsageEntry(uint32_t new_index, std::vector<uint8_t>* header_buffer,
|
||||
|
||||
@@ -4386,6 +4386,36 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) {
|
||||
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, ForbidReportWithNoUpdate) {
|
||||
std::string pst = "my_pst";
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused));
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
// Cannot generate a report without first updating the file.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.GenerateReport(pst, OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
// Now it's OK.
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kActive));
|
||||
// Flag the entry as inactive.
|
||||
ASSERT_NO_FATAL_FAILURE(s.DeactivateUsageEntry(pst));
|
||||
// Cannot generate a report without first updating the file.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.GenerateReport(pst, OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE));
|
||||
// Decrypt should fail.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) {
|
||||
std::string pst = "my_pst";
|
||||
Session s;
|
||||
@@ -4802,7 +4832,7 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithTerminate) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused));
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst, kActive));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kActive));
|
||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||
}
|
||||
|
||||
@@ -4934,7 +4964,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
|
||||
ASSERT_NO_FATAL_FAILURE(s3.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s3.LoadUsageEntry(s));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, true, &s));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s));
|
||||
EXPECT_EQ(kInactiveUsed, s3.pst_report().status());
|
||||
}
|
||||
|
||||
@@ -5265,7 +5295,8 @@ TEST_F(UsageTableTest, GenerateReportWrongPST) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateReport("wrong_pst", false));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateReport("wrong_pst",
|
||||
OEMCrypto_ERROR_WRONG_PST));
|
||||
}
|
||||
|
||||
TEST_F(UsageTableTest, TimingTest) {
|
||||
@@ -5548,7 +5579,7 @@ TEST_F(UsageTableTest, PSTLargeBuffer) {
|
||||
ASSERT_NO_FATAL_FAILURE(s3.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s3.LoadUsageEntry(s));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, true, &s));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s));
|
||||
EXPECT_EQ(kInactiveUsed, s3.pst_report().status());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user