diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 9026f77d..f1192259 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -877,8 +877,12 @@ CdmResponseType CryptoSession::GenerateUsageReport( ntohll64(pst_report.seconds_since_last_decrypt)); LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str()); - // When usage report state is inactive, we have to deduce whether the - // license was ever used. + if (kInactiveUnused == pst_report.status) { + *usage_duration_status = kUsageDurationPlaybackNotBegun; + return NO_ERROR; + } + // Before OEMCrypto v13, When usage report state is inactive, we have to + // deduce whether the license was ever used. if (kInactive == pst_report.status && (0 > ntohll64(pst_report.seconds_since_first_decrypt) || ntohll64(pst_report.seconds_since_license_received) < diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 6b2a1b2f..cab083c6 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -571,7 +571,7 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { sizeof(usage_report)); EXPECT_EQ(sizeof(usage_report) + usage_report.pst_length, existing_license.session_usage_table_entry().size()); - EXPECT_EQ(kInactive, usage_report.status); + EXPECT_EQ(kInactiveUsed, usage_report.status); EXPECT_EQ(id.provider_session_token().size(), usage_report.pst_length); std::string pst(existing_license.session_usage_table_entry().data() + sizeof(OEMCrypto_PST_Report), diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 11862285..6795772c 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -242,7 +242,9 @@ typedef struct { typedef enum OEMCrypto_Usage_Entry_Status { kUnused = 0, kActive = 1, - kInactive = 2 // TODO(fredgc): http://b/32714323. used and unused. + kInactive = 2, // Deprecated. Used kInactiveUsed or kInactiveUnused. + kInactiveUsed = 3, + kInactiveUnused = 4, } OEMCrypto_Usage_Entry_Status; /* @@ -2631,8 +2633,9 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, * Valid values for status are: * 0 = kUnused -- the keys have not been used to decrypt. * 1 = kActive -- the keys have been used, and have not been deactivated. - * 2 = kInactiveUsed -- the keys have been marked inactive after a decrypt. - * 3 = kInactiveUnused -- the keys have been marked inactive, no decrypt. + * 2 = kInactive -- deprecated. Use kInactiveUsed or kInactiveUnused. + * 3 = kInactiveUsed -- the keys have been marked inactive after a decrypt. + * 4 = kInactiveUnused -- the keys have been marked inactive, no decrypt. * * The clock_security_level is reported as follows: * 0 = Insecure Clock - clock just uses system time. diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp index 545e6140..04570fca 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp @@ -381,13 +381,13 @@ bool SessionContext::CheckNonceOrEntry(const KeyControlBlock& key_control_block, if (!usage_entry_) { usage_entry_ = ce_->usage_table()->FindEntry(pst); if (usage_entry_) { - if (usage_entry_->status() == kInactive) return false; + if (usage_entry_->inactive()) return false; } else { if (!CheckNonce(key_control_block.nonce())) return false; usage_entry_ = ce_->usage_table()->CreateEntry(pst, this); } } else { - if (usage_entry_->status() == kInactive) return false; + if (usage_entry_->inactive()) return false; } break; // Usage table not required. Look at nonce enabled bit. default: diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp index d357c731..a33f0cdb 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp @@ -66,7 +66,11 @@ void UsageTableEntry::SaveToBuffer(StoredUsageEntry *buffer) { } void UsageTableEntry::Deactivate() { - status_ = kInactive; + if (status_ == kUnused) { + status_ = kInactiveUnused; + } else if (status_ == kActive) { + status_ = kInactiveUsed; + } if (session_) { session_->ReleaseUsageEntry(); session_ = NULL; @@ -85,6 +89,8 @@ bool UsageTableEntry::UpdateTime() { time_of_last_decrypt_ = now; return true; case kInactive: + case kInactiveUsed: + case kInactiveUnused: return false; } return false; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h index 093c6e61..ba3d0df5 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h @@ -50,6 +50,7 @@ class UsageTableEntry { ~UsageTableEntry(); void SaveToBuffer(StoredUsageEntry *buffer); OEMCrypto_Usage_Entry_Status status() const { return status_; } + bool inactive() const { return status_ >= kInactive; } void Deactivate(); bool UpdateTime(); OEMCryptoResult ReportUsage(SessionContext *session, diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index c9df8ac9..046e51ad 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -842,7 +842,7 @@ void Session::GenerateReport(const std::string& pst, bool expect_success, length - SHA_DIGEST_LENGTH, &computed_signature[0], &sig_len); EXPECT_EQ(0, memcmp(&computed_signature[0], pst_report()->signature, SHA_DIGEST_LENGTH)); - EXPECT_GE(kInactive, pst_report()->status); + EXPECT_GE(kInactiveUnused, pst_report()->status); EXPECT_GE(kHardwareSecureClock, pst_report()->clock_security_level); EXPECT_EQ(pst.length(), pst_report()->pst_length); EXPECT_EQ(0, memcmp(pst.c_str(), pst_report()->pst, pst.length())); diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 43c38872..d7c752f8 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -4405,7 +4405,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) { kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report()->status); EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -4696,7 +4696,7 @@ TEST_P(UsageTableTestWithMAC, DeleteInactiveEntry) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); s2.GenerateReport(pst, true, &s); - EXPECT_EQ(kInactive, s2.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s2.pst_report()->status); ASSERT_NO_FATAL_FAILURE(s2.DeleteEntry(pst)); ASSERT_NO_FATAL_FAILURE(s2.close()); @@ -4868,7 +4868,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) { kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); + EXPECT_EQ(kInactiveUsed, session_.pst_report()->status); EXPECT_NEAR( 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -4916,7 +4916,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) { kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); session_.GenerateReport(pst); - EXPECT_EQ(kInactive, session_.pst_report()->status); + EXPECT_EQ(kInactiveUsed, session_.pst_report()->status); EXPECT_NEAR( 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -4973,7 +4973,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) { kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); + EXPECT_EQ(kInactiveUsed, session_.pst_report()->status); EXPECT_NEAR( 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -5024,7 +5024,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) { kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); + EXPECT_EQ(kInactiveUsed, session_.pst_report()->status); EXPECT_NEAR( 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -5247,7 +5247,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); s.GenerateReport(pst); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report()->status); EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -5270,7 +5270,7 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); s3.GenerateReport(pst, true, &s); - EXPECT_EQ(kInactive, s3.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s3.pst_report()->status); } TEST_P(UsageTableTestWithMAC, BadRange) { @@ -5362,7 +5362,7 @@ TEST_F(UsageTableTest, TimingTest) { time_t report_generated3 = time(NULL); s3.GenerateReport(pst3); - EXPECT_EQ(kInactive, s1.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s1.pst_report()->status); EXPECT_NEAR(report_generated1 - loaded1, wvcdm::htonll64(s1.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -5485,7 +5485,7 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report()->status); ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); } @@ -5538,7 +5538,7 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report()->status); EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_license_received), kTimeTolerance); @@ -5561,7 +5561,7 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, true, &s)); - EXPECT_EQ(kInactive, s3.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s3.pst_report()->status); } TEST_F(UsageTableTest, DeleteEntryLargeBuffer) {