diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index d892e6af..1ea5e86b 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -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 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; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp index 2285b90b..29fbe293 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp @@ -116,7 +116,7 @@ void UsageTableEntry::Deactivate(const std::vector& 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& 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(&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()); diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index f2263f60..f581f59e 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -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(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(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 computed_signature(SHA_DIGEST_LENGTH); unsigned int sig_len = SHA_DIGEST_LENGTH; HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(), diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index 36a6c22b..af8a2581 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -286,11 +286,12 @@ class Session { const vector& 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* header_buffer, diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 54402f01..fec4cc9c 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -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()); }