diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index dd5a5311..ecf816a9 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -152,6 +152,10 @@ class CryptoEngine { // Rate limit for nonce generation. Default to 20 nonce/second. virtual int nonce_flood_count() { return 20; } + // Limit for size of usage table. If this is zero, then the + // size is unlimited -- or limited only by memory size. + virtual size_t max_usage_table_size() { return 0; } + // Set destination pointer based on the output destination description. OEMCryptoResult SetDestination(OEMCrypto_DestBufferDesc* out_description, size_t data_length, uint8_t subsample_flags); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp index 5373d5da..b91ed78b 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp @@ -380,6 +380,11 @@ OEMCryptoResult UsageTable::CreateNewUsageEntry(SessionContext* session, if (!entry) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (!usage_entry_number) return OEMCrypto_ERROR_UNKNOWN_FAILURE; uint32_t index = generation_numbers_.size(); + size_t max = ce_->max_usage_table_size(); + if (max > 0 && index >= max) { + LOGE("Too many usage entries: %d/%d", index, max); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } UsageTableEntry* new_entry = MakeEntry(index); generation_numbers_.push_back(master_generation_number_); sessions_.push_back(session); @@ -404,6 +409,11 @@ OEMCryptoResult UsageTable::LoadUsageEntry(SessionContext* session, LOGE("LoadUsageEntry: index %d used by other session.", index); return OEMCrypto_ERROR_INVALID_SESSION; } + size_t max = ce_->max_usage_table_size(); + if (max > 0 && index >= max) { + LOGE("Too many usage entries: %d/%d", index, max); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } UsageTableEntry* new_entry = MakeEntry(index); OEMCryptoResult status = new_entry->LoadData(ce_, index, buffer); @@ -512,6 +522,12 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader( if (!LoadGenerationNumber(false)) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (buffer.size() < SignedHeaderSize(0)) return OEMCrypto_ERROR_SHORT_BUFFER; + size_t max = ce_->max_usage_table_size(); + if (max > 0 && buffer.size() > SignedHeaderSize(max)) { + LOGE("Header too big: %zd bytes/%zd bytes", + buffer.size(), SignedHeaderSize(max)); + return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; + } std::vector clear_buffer(buffer.size()); SignedHeaderBlock* clear = reinterpret_cast(&clear_buffer[0]);