Refine TwoHundredEntries tests

am: a963e90bb8

Change-Id: I38d4ccb9c7e517e72a2b4555557db0de01f01302
This commit is contained in:
Fred Gylys-Colwell
2018-08-29 18:10:22 -07:00
committed by android-build-merger
3 changed files with 101 additions and 64 deletions

View File

@@ -1096,9 +1096,14 @@ void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) {
GenerateDerivedKeysFromSessionKey();
}
void Session::CreateNewUsageEntry() {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_CreateNewUsageEntry(session_id(), &usage_entry_number_));
void Session::CreateNewUsageEntry(OEMCryptoResult* status) {
OEMCryptoResult result =
OEMCrypto_CreateNewUsageEntry(session_id(), &usage_entry_number_);
if (status) {
*status = result;
return;
}
ASSERT_EQ(OEMCrypto_SUCCESS, result);
}
void Session::UpdateUsageEntry(std::vector<uint8_t>* header_buffer) {

View File

@@ -290,7 +290,9 @@ class Session {
// GenerateDerivedKeysFromSessionKey to install known encryption and mac keys.
void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key);
// Creates a new usage entry, and keeps track of the index.
void CreateNewUsageEntry();
// If status is null, we expect success, otherwise status is set to the
// return value.
void CreateNewUsageEntry(OEMCryptoResult *status = NULL);
// Copy encrypted usage entry from other session, and then load it.
// This session must already be open.
void LoadUsageEntry(uint32_t index, const vector<uint8_t>& buffer);

View File

@@ -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.