Force a reprovisioning on device renewal

[ Merge of http://go/wvgerrit/169374 ]

Device renewals used to require that OEMs remove provisioning
certificates as part of the OTA update process. Instead, a change
in system ID is relied upon to indicate a change in root of trust.
If a change in System ID is detected, reprovisioning will be forced.

This is not enabled for ATSC devices or L3 devices. For the latter a
change in system ID may occurs without a change in RoT.

Bug: 258361396
Test: GtsMediaTestCases
Change-Id: I6e8b0b2149fc2ed5362a32bb6e869826f5fa8ef7
This commit is contained in:
Rahul Frias
2023-03-30 10:57:05 -07:00
parent 0ab8f029a0
commit d31a4dec56
3 changed files with 196 additions and 8 deletions

View File

@@ -20,6 +20,7 @@
#include "log.h"
#include "properties.h"
#include "string_conversions.h"
#include "system_id_extractor.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
@@ -160,6 +161,9 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
if (!file_handle_->HasCertificate(atsc_mode_enabled_))
return CdmResponseType(NEED_PROVISIONING);
// Require reprovisioning if the root of trust has changed
if (HasRootOfTrustBeenRenewed()) return CdmResponseType(NEED_PROVISIONING);
if (forced_session_id) {
key_set_id_ = *forced_session_id;
} else {
@@ -1243,6 +1247,49 @@ CdmResponseType CdmSession::LoadPrivateKey(
}
}
// Use a change in system ID as an indication that Root of Trust
// has been renewed.
bool CdmSession::HasRootOfTrustBeenRenewed() {
if (atsc_mode_enabled_) return false;
// Ignore System ID changes for L3 as the root of trust might not have
// changed even if the system ID has
if (crypto_session_->GetSecurityLevel() == kSecurityLevelL3) return false;
std::string drm_certificate;
CryptoWrappedKey private_key;
uint32_t drm_cert_system_id;
if (file_handle_->RetrieveCertificate(
atsc_mode_enabled_, &drm_certificate, &private_key, nullptr,
&drm_cert_system_id) != DeviceFiles::kCertificateValid) {
LOGE("Failed to retrieve DRM certificate");
return true;
}
wvutil::FileSystem global_file_system;
SystemIdExtractor system_id_extractor(kLevelDefault, crypto_session_.get(),
&global_file_system);
SystemIdExtractor* extractor = &system_id_extractor;
if (mock_system_id_extractor_) {
extractor = mock_system_id_extractor_.get();
}
uint32_t system_id;
if (!extractor->ExtractSystemId(&system_id)) {
LOGW("ExtractSystemId failed");
return false;
}
if (system_id == drm_cert_system_id) return false;
LOGI(
"System Id changed from %d to %d. Removing certificates and "
"reprovisioning",
drm_cert_system_id, system_id);
file_handle_->RemoveCertificate();
return true;
}
// For testing only - takes ownership of pointers
void CdmSession::set_license_parser(CdmLicense* license_parser) {
@@ -1262,4 +1309,8 @@ void CdmSession::set_policy_engine(PolicyEngine* policy_engine) {
void CdmSession::set_file_handle(DeviceFiles* file_handle) {
file_handle_.reset(file_handle);
}
void CdmSession::set_system_id_extractor(SystemIdExtractor* extractor) {
mock_system_id_extractor_.reset(extractor);
}
} // namespace wvcdm