Refine TwoHundredEntries tests
Merge from Widevine repo of http://go/wvgerrit/58440 This CL modifies the oemcrypto test TwoHundredEntries so that it attempts to create more than 200 entries. A device is allowed to fail when such an attempt is made, but it must return an insufficient resources error. The test then verifies that each of the entries that were succesfully created can be used to reload its license and the keys can be used for decryption. It then shrinks the usage table header, and verifies that the remaining licenses can still be used for decryption. bug: 112486006 test: unit tests (test code only) Change-Id: I6e6edfb00f0553724e0f99fb4e5ea5c817450937
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -4684,66 +4685,6 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||
}
|
||||
|
||||
TEST_F(UsageTableTest, TwoHundredEntries) {
|
||||
Session s1;
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
std::string pst1 = "pst saved";
|
||||
ASSERT_NO_FATAL_FAILURE(s1.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
s1.get_nonce(), pst1));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.CreateNewUsageEntry());
|
||||
ASSERT_EQ(0u, s1.usage_entry_number());
|
||||
time_t start = time(NULL);
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst1, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
|
||||
// API says should hold at least 200 entries. Subtract one for s1's entry.
|
||||
const size_t ENTRY_COUNT = 200 - 1;
|
||||
vector<Session> sessions(ENTRY_COUNT);
|
||||
for (size_t i = 0; i < ENTRY_COUNT; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&sessions[i]));
|
||||
std::string pst = "pst ";
|
||||
char c1 = 'A' + (i/26);
|
||||
char c2 = 'A' + (i%26);
|
||||
pst = pst + c1 + c2;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].CreateNewUsageEntry());
|
||||
ASSERT_EQ(sessions[i].usage_entry_number(), i + 1);
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].close());
|
||||
}
|
||||
sleep(kShortSleep);
|
||||
for (size_t i = 0; i < ENTRY_COUNT; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
std::string pst = "pst ";
|
||||
char c1 = 'A' + (i/26);
|
||||
char c2 = 'A' + (i%26);
|
||||
pst = pst + c1 + c2;
|
||||
// Reuse license message created above.
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&sessions[i]));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].LoadTestKeys(pst, new_mac_keys_))
|
||||
<< "Failed to reload license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].close());
|
||||
}
|
||||
// Make sure s1's entry is still in the table.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.GenerateVerifyReport(pst1, kUnused, start));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
|
||||
std::string pst = "A PST";
|
||||
uint32_t nonce = session_.get_nonce();
|
||||
@@ -5418,6 +5359,95 @@ TEST_F(UsageTableDefragTest, ReloadUsageEntryBadData) {
|
||||
&data[0], data.size()));
|
||||
}
|
||||
|
||||
static std::string MakePST(size_t n) {
|
||||
std::stringstream stream;
|
||||
stream << "pst-" << n;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
TEST_F(UsageTableDefragTest, TwoHundredEntries) {
|
||||
// OEMCrypto is required to store at least 200 entries in the usage table
|
||||
// header, but it is allowed to store more. This test verifies that if we keep
|
||||
// adding entries, the error indicates a resource limit. It then verifies
|
||||
// that all of the successful entries are still valid after we throw out the
|
||||
// last invalid entry.
|
||||
const size_t ENTRY_COUNT = 2000;
|
||||
vector<Session> sessions(ENTRY_COUNT);
|
||||
size_t successful_count = 0;
|
||||
for (size_t i = 0; i < ENTRY_COUNT; i++) {
|
||||
if (i % 50 == 0) LOGD("Creating license %zd", i);
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&sessions[i]));
|
||||
std::string pst = MakePST(i);
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].EncryptAndSign());
|
||||
// We attempt to create a new usage table entry for this session.
|
||||
OEMCryptoResult status;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].CreateNewUsageEntry(&status));
|
||||
if (status == OEMCrypto_SUCCESS) {
|
||||
ASSERT_EQ(sessions[i].usage_entry_number(), i);
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_));
|
||||
successful_count++;
|
||||
} else {
|
||||
// If we failed to create this many entries because of limited resources,
|
||||
// then the error returned should be insufficient resources.
|
||||
EXPECT_EQ(OEMCrypto_ERROR_INSUFFICIENT_RESOURCES, status)
|
||||
<< "Failed to create license " << i << " with pst = " << pst;
|
||||
break;
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].close());
|
||||
}
|
||||
LOGD("successful_count = %d", successful_count);
|
||||
EXPECT_GE(successful_count, 200u);
|
||||
sleep(kShortSleep);
|
||||
// Now we will loop through each valid entry, and verify that we can still
|
||||
// reload the license and perform a decrypt.
|
||||
for (size_t i = 0; i < successful_count; i++) {
|
||||
if (i % 50 == 0) LOGD("Reloading license %zd", i);
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
std::string pst = MakePST(i);
|
||||
// Reuse license message created above.
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&sessions[i]));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].LoadTestKeys(pst, new_mac_keys_))
|
||||
<< "Failed to reload license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_))
|
||||
<< "Failed to update license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].TestDecryptCTR())
|
||||
<< "Failed to use license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_))
|
||||
<< "Failed to update license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].close());
|
||||
}
|
||||
// We also need to verify that a full table can be shrunk, and the remaining
|
||||
// licenses still work.
|
||||
size_t smaller_size = 10u; // 10 is smaller than 200.
|
||||
ASSERT_NO_FATAL_FAILURE(ShrinkHeader(smaller_size));
|
||||
for (size_t i = 0; i < smaller_size; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
std::string pst = MakePST(i);
|
||||
// Reuse license message created above.
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&sessions[i]));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].LoadTestKeys(pst, new_mac_keys_))
|
||||
<< "Failed to reload license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_))
|
||||
<< "Failed to update license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].TestDecryptCTR())
|
||||
<< "Failed to use license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
sessions[i].UpdateUsageEntry(&encrypted_usage_header_))
|
||||
<< "Failed to update license " << i << " with pst = " << pst;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].close());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UsageTableTest, CopyOldEntries) {
|
||||
// First create three old entries. We open sessions first to force creation
|
||||
// of the mac keys.
|
||||
|
||||
Reference in New Issue
Block a user