From d2ba3a3f91c8096a5425b3de2118b0b74256b60f Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Wed, 18 Mar 2015 18:09:37 -0700 Subject: [PATCH] Allow selective removal of Usage Table Entries by PST This is a merge of http://go/wvgerrit/13693 in the Widevine repository. This adds level 3 and mock implementation and unit tests for the OEMCrypto function OEMCrypto_ForceDeleteUsageEntry. It also plumbs this function up into CdmEngine, CdmSession, and CryptoSession so that deleting all usage information for a given app id will now delete the entries in OEMCrypto, too. b/18194071 Change-Id: Iaea4034a507b323878657215784edfe95876386a --- libwvdrmengine/cdm/core/include/cdm_session.h | 4 +- .../cdm/core/include/crypto_session.h | 8 ++++ .../cdm/core/include/device_files.h | 7 ++- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 15 ++++-- libwvdrmengine/cdm/core/src/cdm_session.cpp | 23 ++++------ .../cdm/core/src/crypto_session.cpp | 46 ++++++++++++++++++- libwvdrmengine/cdm/core/src/device_files.cpp | 27 +++++++++-- .../core/src/oemcrypto_adapter_dynamic.cpp | 19 ++++++++ .../cdm/core/test/device_files_unittest.cpp | 46 +++++++++++++++++++ .../cdm/core/test/policy_engine_unittest.cpp | 2 +- .../cdm/test/cdm_extended_duration_test.cpp | 3 +- .../cdm/test/request_license_test.cpp | 6 ++- .../oemcrypto/mock/src/oemcrypto_mock.cpp | 16 +++++++ .../oemcrypto/test/oemcrypto_test.cpp | 32 +++++++++++++ 14 files changed, 226 insertions(+), 28 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index 4f83aaf4..3b2ca841 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -90,7 +90,9 @@ class CdmSession { } virtual CdmSecurityLevel GetSecurityLevel() { return security_level_; } - virtual CdmResponseType DeleteUsageInformation(const std::string& app_id); + // Delete usage information for the list of tokens, |provider_session_tokens|. + virtual CdmResponseType DeleteMultipleUsageInformation( + const std::vector& provider_session_tokens); virtual CdmResponseType UpdateUsageInformation(); virtual bool is_initial_usage_update() { return is_initial_usage_update_; } diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index eb3ae485..d30bcdb0 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -96,6 +96,14 @@ class CryptoSession { virtual CdmResponseType ReleaseUsageInformation( const std::string& message, const std::string& signature, const std::string& provider_session_token); + // Delete a usage information for a single token. This does not require + // a signed message from the server. + virtual CdmResponseType DeleteUsageInformation( + const std::string& provider_session_token); + // Delete usage information for a list of tokens. This does not require + // a signed message from the server. + virtual CdmResponseType DeleteMultipleUsageInformation( + const std::vector& provider_session_tokens); virtual CdmResponseType DeleteAllUsageReports(); virtual bool IsAntiRollbackHwPresent(); diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index 9ea25613..bfcd3000 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -63,7 +63,11 @@ class DeviceFiles { const std::string& app_id); virtual bool DeleteUsageInfo(const std::string& app_id, const std::string& provider_session_token); - virtual bool DeleteAllUsageInfoForApp(const std::string& app_id); + // Delete usage information from the file system. Puts a list of all the + // psts that were deleted from the file into |provider_session_tokens|. + virtual bool DeleteAllUsageInfoForApp( + const std::string& app_id, + std::vector* provider_session_tokens); // Retrieve one usage info from the file. Subsequent calls will retrieve // subsequent entries in the table for this app_id. virtual bool RetrieveUsageInfo( @@ -104,6 +108,7 @@ class DeviceFiles { FRIEND_TEST(DeviceFilesTest, StoreLicenses); FRIEND_TEST(DeviceFilesTest, UpdateLicenseState); FRIEND_TEST(DeviceFilesUsageInfoTest, Delete); + FRIEND_TEST(DeviceFilesUsageInfoTest, DeleteAll); FRIEND_TEST(DeviceFilesUsageInfoTest, Read); FRIEND_TEST(DeviceFilesUsageInfoTest, Store); FRIEND_TEST(WvCdmRequestLicenseTest, UnprovisionTest); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 001bbf7f..f2b74e29 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -732,13 +732,20 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) { CdmResponseType status = NO_ERROR; - DeviceFiles handle[kSecurityLevelUnknown - kSecurityLevelL1]; - for (int i = 0, j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++i, ++j) { - if (handle[i].Init(static_cast(j))) { - if (!handle[i].DeleteAllUsageInfoForApp(app_id)) { + for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) { + DeviceFiles handle; + if (handle.Init(static_cast(j))) { + std::vector provider_session_tokens; + if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) { LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure" "stops", j); status = UNKNOWN_ERROR; + } else { + CdmResponseType status2 = usage_session_-> + DeleteMultipleUsageInformation(provider_session_tokens); + if (status2 != NO_ERROR) { + status = status2; + } } } else { LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device" diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index f36e3c4a..e3ff2e36 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -526,11 +526,16 @@ bool CdmSession::DeleteLicense() { if (!is_offline_ && license_parser_->provider_session_token().empty()) return false; + if (!license_parser_->provider_session_token().empty()) { + if(crypto_session_->DeleteUsageInformation( + license_parser_->provider_session_token()) != NO_ERROR) { + LOGE("CdmSession::DeleteLicense: error deleting usage info"); + } + } if (!file_handle_->Reset(security_level_)) { LOGE("CdmSession::DeleteLicense: Unable to initialize device files"); return false; } - if (is_offline_) { return file_handle_->DeleteLicense(key_set_id_); } else { @@ -590,18 +595,10 @@ void CdmSession::GetApplicationId(std::string* app_id) { } } -CdmResponseType CdmSession::DeleteUsageInformation(const std::string& app_id) { - if (!file_handle_->Reset(security_level_)) { - LOGE("CdmSession::StoreLicense: Unable to initialize device files"); - return UNKNOWN_ERROR; - } - - if (file_handle_->DeleteAllUsageInfoForApp(app_id)) { - return NO_ERROR; - } else { - LOGE("CdmSession::DeleteUsageInformation: failed"); - return UNKNOWN_ERROR; - } +CdmResponseType CdmSession::DeleteMultipleUsageInformation( + const std::vector& provider_session_tokens) { + return crypto_session_ + ->DeleteMultipleUsageInformation(provider_session_tokens); } CdmResponseType CdmSession::UpdateUsageInformation() { diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index cf1ba6a8..d3bf0991 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -846,6 +846,50 @@ CdmResponseType CryptoSession::ReleaseUsageInformation( return NO_ERROR; } +CdmResponseType CryptoSession::DeleteUsageInformation( + const std::string& provider_session_token) { + CdmResponseType response = NO_ERROR; + LOGV("CryptoSession::DeleteUsageInformation"); + OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(provider_session_token.c_str()), + provider_session_token.length()); + if (OEMCrypto_SUCCESS != status) { + LOGE("CryptoSession::DeleteUsageInformation: Delete Usage Table error =%ld", + status); + response = UNKNOWN_ERROR; + } + status = OEMCrypto_UpdateUsageTable(); + if (status != OEMCrypto_SUCCESS) { + LOGE("CryptoSession::DeleteUsageInformation: update table error=%ld", + status); + response = UNKNOWN_ERROR; + } + return response; +} + +CdmResponseType CryptoSession::DeleteMultipleUsageInformation( + const std::vector& provider_session_tokens) { + LOGV("CryptoSession::DeleteMultipleUsageInformation"); + CdmResponseType response = NO_ERROR; + for (size_t i=0; i < provider_session_tokens.size(); ++i) { + OEMCryptoResult status = OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(provider_session_tokens[i].c_str()), + provider_session_tokens[i].length()); + if (OEMCrypto_SUCCESS != status) { + LOGW("CryptoSession::DeleteMultipleUsageInformation: " + "Delete Usage Table error =%ld", status); + response = UNKNOWN_ERROR; + } + } + OEMCryptoResult status = OEMCrypto_UpdateUsageTable(); + if (status != OEMCrypto_SUCCESS) { + LOGE("CryptoSession::DeleteMultipleUsageInformation: update table error=%ld", + status); + response = UNKNOWN_ERROR; + } + return response; +} + CdmResponseType CryptoSession::DeleteAllUsageReports() { LOGV("DeleteAllUsageReports"); OEMCryptoResult status = OEMCrypto_DeleteUsageTable(); @@ -859,8 +903,8 @@ CdmResponseType CryptoSession::DeleteAllUsageReports() { if (status != OEMCrypto_SUCCESS) { LOGE("CryptoSession::DeletaAllUsageReports: update table error=%ld", status); + return UNKNOWN_ERROR; } - return NO_ERROR; } diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 17098919..1342cb41 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -378,7 +378,6 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id, LOGW("DeviceFiles::DeleteUsageInfo: not initialized"); return false; } - std::string serialized_file; std::string file_name = GetUsageInfoFileName(app_id); if (!RetrieveHashedFile(file_name.c_str(), &serialized_file)) return false; @@ -418,12 +417,18 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id, return StoreFileWithHash(file_name.c_str(), serialized_file); } -bool DeviceFiles::DeleteAllUsageInfoForApp(const std::string& app_id) { +bool DeviceFiles::DeleteAllUsageInfoForApp( + const std::string& app_id, + std::vector* provider_session_tokens) { if (!initialized_) { LOGW("DeviceFiles::DeleteAllUsageInfoForApp: not initialized"); return false; } - + if (NULL == provider_session_tokens) { + LOGW("DeviceFiles::DeleteAllUsageInfoForApp: pst destination not provided"); + return false; + } + provider_session_tokens->clear(); std::string path; if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) { LOGW("DeviceFiles::DeleteAllUsageInfoForApp: Unable to get base path"); @@ -431,7 +436,21 @@ bool DeviceFiles::DeleteAllUsageInfoForApp(const std::string& app_id) { } std::string file_name = GetUsageInfoFileName(app_id); path.append(file_name); - + if (!file_->Exists(path)) return true; + std::string serialized_file; + if (RetrieveHashedFile(file_name.c_str(), &serialized_file)) { + video_widevine_client::sdk::File file_proto; + if (!file_proto.ParseFromString(serialized_file)) { + LOGW("DeviceFiles::DeleteAllUsageInfoForApp: Unable to parse file"); + } else { + for (int i = 0; i < file_proto.usage_info().sessions_size(); ++i) { + provider_session_tokens->push_back( + file_proto.usage_info().sessions(i).token()); + } + } + } else { + LOGW("DeviceFiles::DeleteAllUsageInfoForApp: Unable to retrieve file"); + } return file_->Remove(path); } diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 5cb83b06..3ccfaab8 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -325,6 +325,7 @@ class Adapter { LOOKUP(IsAntiRollbackHwPresent, OEMCrypto_IsAntiRollbackHwPresent); LOOKUP(GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions); LOOKUP(GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions); + LOOKUP(ForceDeleteUsageEntry, OEMCrypto_ForceDeleteUsageEntry); } } if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) { @@ -924,6 +925,24 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry( } } +extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry( + const uint8_t* pst, size_t pst_length) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault); + const FunctionPointers* fcn3 = kAdapter->get(kLevel3); + OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED; + if (fcn3 && fcn3->version > 9) { + sts = fcn3->ForceDeleteUsageEntry(pst, pst_length); + } + if (fcn1 && fcn1 != fcn3 && fcn1->version > 9) { + OEMCryptoResult sts1 = fcn1->ForceDeleteUsageEntry(pst, pst_length); + if ((sts1 != OEMCrypto_SUCCESS) && (sts == OEMCrypto_SUCCESS)) { + sts = sts1; + } + } + return sts; +} + extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault); diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index 0fcda278..a21d7c51 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -1938,6 +1938,52 @@ TEST_P(DeviceFilesUsageInfoTest, Delete) { } } +TEST_P(DeviceFilesUsageInfoTest, DeleteAll) { + MockFile file; + std::string app_id; // TODO(fredgc): expand tests. + std::string path = + device_base_path_ + DeviceFiles::GetUsageInfoFileName(app_id); + + int index = GetParam(); + EXPECT_CALL(file, IsDirectory(StrEq(device_base_path_))) + .WillRepeatedly(Return(true)); + EXPECT_CALL(file, CreateDirectory(_)).Times(0); + EXPECT_CALL(file, Write(_, _)).Times(0); + + std::string data; + if (index < 0) { + EXPECT_CALL(file, Exists(StrEq(path))).WillOnce(Return(false)); + } else { + data = kUsageInfoTestData[index].file_data; + EXPECT_CALL(file, Exists(StrEq(path))).WillRepeatedly(Return(true)); + EXPECT_CALL(file, FileSize(StrEq(path))).WillOnce(Return(data.size())); + EXPECT_CALL(file, Open(StrEq(path), IsBinaryFileFlagSet())) + .WillOnce(Return(true)); + EXPECT_CALL(file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + EXPECT_CALL(file, Close()).Times(1); + EXPECT_CALL(file, Remove(StrEq(path))).WillOnce(Return(true)); + } + + DeviceFiles device_files; + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + device_files.SetTestFile(&file); + + std::vector psts; + ASSERT_TRUE(device_files.DeleteAllUsageInfoForApp(app_id, &psts)); + if (index < 0) { + EXPECT_EQ(0u, psts.size()); + } else { + // DeleteAllUsageInfoForApp returns a list of all psts that + // should be deleted by oemcrypto. + EXPECT_EQ(static_cast(index), psts.size()); + for(int i=0; i < index; i++) { + EXPECT_EQ(kUsageInfoTestData[i+1].provider_session_token, psts[i]); + } + } +} + INSTANTIATE_TEST_CASE_P(UsageInfo, DeviceFilesUsageInfoTest, ::testing::Values(-1, 0, 1, 2, 3)); diff --git a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp index e23ac0a4..33cdf773 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp @@ -845,7 +845,7 @@ TEST_F(PolicyEngineTest, QuerySuccess_LicenseStartTimeNotSet) { CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, policy_engine_->Query(&query_info)); - EXPECT_EQ(0, query_info.size()); + EXPECT_EQ(0u, query_info.size()); } TEST_F(PolicyEngineTest, QuerySuccess) { diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 649f66ae..67a5a85b 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -834,7 +834,8 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) { EXPECT_TRUE(handle.Init(security_level)); File file; handle.SetTestFile(&file); - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("")); + std::vector provider_session_tokens; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &provider_session_tokens)); for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) { decryptor_.OpenSession(g_key_system, property_set, &session_id_); diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index c453faab..c4d4b480 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -1210,7 +1210,8 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { EXPECT_TRUE(handle.Init(security_level)); File file; handle.SetTestFile(&file); - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id)); + std::vector psts; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts)); SubSampleInfo* data = &usage_info_sub_samples_icp[0]; decryptor_.OpenSession(g_key_system, NULL, &session_id_); @@ -1286,7 +1287,8 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { EXPECT_TRUE(handle.Init(security_level)); File file; handle.SetTestFile(&file); - EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(usage_info_data->app_id)); + std::vector psts; + EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(usage_info_data->app_id, &psts)); for (size_t i = 0; i < usage_info_data->usage_info; ++i) { SubSampleInfo* data = usage_info_data->sub_sample + i; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 85e1abb8..4edaa21c 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -1316,6 +1316,22 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } +extern "C" +OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, + size_t pst_length) { + if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { + LOGI("-- OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry()\n"); + if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) { + dump_hex("pst", pst, pst_length); + } + } + std::vector pstv(pst, pst + pst_length); + if (crypto_engine->usage_table()->DeleteEntry(pstv)) { + return OEMCrypto_SUCCESS; + } + return OEMCrypto_ERROR_UNKNOWN_FAILURE; +} + extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() { if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 40f11fe2..6fa6a4b2 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -1522,6 +1522,12 @@ class Session { &signature_[0], signature_.size())); } + void ForceDeleteEntry(const std::string& pst) { + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_ForceDeleteUsageEntry( + reinterpret_cast(pst.c_str()), pst.length())); + } + MessageData& license() { return license_; } MessageData& encrypted_license() { return encrypted_license_; } const uint8_t* message_ptr() { @@ -4877,6 +4883,32 @@ TEST_P(DISABLED_UsageTableTest, DeleteActiveEntry) { } } +TEST_P(DISABLED_UsageTableTest, ForceDeleteActiveEntry) { + if (OEMCrypto_SupportsUsageTable()) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); + Session s; + s.open(); + s.GenerateDerivedKeys(); + std::string pst = "my pst"; + s.FillSimpleMessage( + 0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired, + s.get_nonce(), pst); + s.EncryptAndSign(); + s.LoadTestKeys(pst, new_mac_keys_); + s.TestDecryptCTR(); + s.GenerateReport(pst); + s.close(); + + s.ForceDeleteEntry(pst); + + // Now that session is deleted, we can't generate a report for it. + Session s3; + s3.open(); + s3.GenerateReport(pst, false); + s3.close(); + } +} + TEST_P(DISABLED_UsageTableTest, DeleteInactiveEntry) { if (OEMCrypto_SupportsUsageTable()) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());