Cherry pick 18.4 changes to udc-widevine-dev
Get the udc-widevine-dev Android branch and oemcrypto-v18 cdm branch in sync. The commit ID for 18.4 on oemcrypto-v18 is https://widevine-internal.git.corp.google.com/cdm/+/a2f23a2281e5e06dc2867585bdc516fa132b639. Merged from go/wvgerrit/190151 Bug: 290252845 Test: unit tests passing on Panther device Change-Id: I63fa3f1c784f737ca1480e5febe4f3f5a8a49948
This commit is contained in:
@@ -2404,9 +2404,9 @@ CdmResponseType CdmEngine::SignRsa(const std::string& wrapped_key,
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lock(session_map_lock_);
|
||||
if (!session_map_.FindSession(session_id, &session)) {
|
||||
LOGE("Session not found: session_id = %s", IdToString(session_id));
|
||||
CloseSession(session_id);
|
||||
return CdmResponseType(SESSION_NOT_FOUND_24);
|
||||
LOGE("Session not found: session_id = %s", IdToString(session_id));
|
||||
CloseSession(session_id);
|
||||
return CdmResponseType(SESSION_NOT_FOUND_24);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,14 +263,8 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
usage_entry_ = std::move(license_data.usage_entry);
|
||||
usage_entry_index_ = license_data.usage_entry_index;
|
||||
|
||||
// If ATSC mode is enabled, use ATSC DRM cert/private key, rather than any
|
||||
// cert/private key embedded in the license.
|
||||
CdmResponseType result =
|
||||
atsc_mode_enabled_
|
||||
? LoadPrivateKey()
|
||||
: LoadPrivateOrLegacyKey(license_data.drm_certificate,
|
||||
license_data.wrapped_private_key);
|
||||
|
||||
CdmResponseType result = LoadPrivateOrLegacyKey(
|
||||
license_data.drm_certificate, license_data.wrapped_private_key);
|
||||
if (result != NO_ERROR) return result;
|
||||
|
||||
// Attempts to restore a released offline license are treated as a release
|
||||
|
||||
@@ -3375,6 +3375,11 @@ CdmResponseType CryptoSession::SetDebugIgnoreKeyboxCount(uint32_t count) {
|
||||
return MapOEMCryptoResult(status, UNKNOWN_ERROR, "SetDebugIgnoreKeyboxCount");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::SetAllowTestKeybox(bool allow) {
|
||||
OEMCryptoResult status = OEMCrypto_SetAllowTestKeybox(allow);
|
||||
return MapOEMCryptoResult(status, UNKNOWN_ERROR, "SetAllowTestKeybox");
|
||||
}
|
||||
|
||||
okp::SystemFallbackPolicy* CryptoSession::GetOkpFallbackPolicy() {
|
||||
const auto getter = [&]() -> okp::SystemFallbackPolicy* {
|
||||
// If not set, then OTA keybox provisioning is not supported or
|
||||
|
||||
@@ -626,6 +626,17 @@ std::string GetIgnoreCountFile() {
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetAllowTestKeyboxFile() {
|
||||
std::string path;
|
||||
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL1,
|
||||
&path)) {
|
||||
LOGW("GetAllowTestKeyboxFile: Unable to get base path");
|
||||
path = "/data/";
|
||||
}
|
||||
path += "debug_allow_test_keybox.txt";
|
||||
return path;
|
||||
}
|
||||
|
||||
uint32_t GetDebugIgnoreKeyboxCount() {
|
||||
const std::string filename = GetIgnoreCountFile();
|
||||
wvutil::FileSystem file_system;
|
||||
@@ -678,6 +689,49 @@ OEMCryptoResult SetDebugIgnoreKeyboxCount(uint32_t count) {
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
bool GetAllowTestKeybox() {
|
||||
const std::string filename = GetAllowTestKeyboxFile();
|
||||
wvutil::FileSystem file_system;
|
||||
if (!file_system.Exists(filename)) {
|
||||
return 0;
|
||||
}
|
||||
auto file = file_system.Open(filename, file_system.kReadOnly);
|
||||
if (!file) {
|
||||
LOGE("Error opening %s", filename.c_str());
|
||||
return 0;
|
||||
}
|
||||
ssize_t size = file_system.FileSize(filename);
|
||||
std::string contents(size, ' ');
|
||||
ssize_t size_read = file->Read(const_cast<char*>(contents.data()), size);
|
||||
if (size != size_read) {
|
||||
LOGE("Short allow_test_keybox = %zu", size_read);
|
||||
return 0;
|
||||
}
|
||||
// skip whitespace or any extra garbage.
|
||||
return (std::string::npos != contents.find("true"));
|
||||
}
|
||||
|
||||
OEMCryptoResult SetAllowTestKeybox(bool allow) {
|
||||
const std::string filename = GetAllowTestKeyboxFile();
|
||||
wvutil::FileSystem file_system;
|
||||
auto file =
|
||||
file_system.Open(filename, file_system.kCreate | file_system.kTruncate);
|
||||
if (!file) {
|
||||
LOGE("Could not create file %s", filename.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
const std::string contents = allow ? "true\n" : "false\n";
|
||||
const size_t size = contents.size();
|
||||
ssize_t size_written = file->Write(contents.data(), size);
|
||||
if (static_cast<ssize_t>(size) != size_written) {
|
||||
LOGE("Wrote %zd bytes of %s, not %zd, to file %s", size_written,
|
||||
contents.c_str(), size, filename.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
LOGD("Wrote %s to %s", contents.c_str(), filename.c_str());
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
typedef enum OEMCryptoSessionType {
|
||||
SESSION_TYPE_OEMCRYPTO = 0,
|
||||
SESSION_TYPE_ENTITLED_KEY = 1,
|
||||
@@ -1260,6 +1314,18 @@ class Adapter {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check the system ID of the keybox. This should only be called if the device
|
||||
// uses provisioning 2.0.
|
||||
bool UsingTestKeybox() {
|
||||
uint8_t key_data[256];
|
||||
size_t key_data_len = sizeof(key_data);
|
||||
OEMCryptoResult sts = OEMCrypto_GetKeyData(key_data, &key_data_len);
|
||||
if (sts != OEMCrypto_SUCCESS) return true;
|
||||
uint32_t* data = reinterpret_cast<uint32_t*>(key_data);
|
||||
uint32_t system_id = htonl(data[1]);
|
||||
return system_id == 7912;
|
||||
}
|
||||
|
||||
// Check the L1 keybox or cert. If it is valid, return success. If not, try to
|
||||
// install one. If one is not available, but OTA provisioning is supported,
|
||||
// return OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING. If none of these work,
|
||||
@@ -1295,6 +1361,19 @@ class Adapter {
|
||||
// Check if the keybox or oem certificate is valid, if so, we are finished
|
||||
// with initialization. Record some metrics and return success.
|
||||
const OEMCryptoResult rot_valid = level1_.IsKeyboxOrOEMCertValid();
|
||||
// For production systems, we do wish to use a test keybox. We do not force
|
||||
// a fallback to L3 at this point, because this can be overridden by test
|
||||
// code that requires a test keybox.
|
||||
if ((rot_valid == OEMCrypto_SUCCESS) &&
|
||||
(provisioning_method == OEMCrypto_Keybox) && UsingTestKeybox()) {
|
||||
if (GetAllowTestKeybox()) {
|
||||
LOGW("Allowing device with test keybox installed.");
|
||||
} else {
|
||||
LOGW("Device has test keybox installed.");
|
||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (rot_valid == OEMCrypto_SUCCESS) {
|
||||
// The keybox or certificate is valid -- that means initialization is done
|
||||
// and we only have save some metrics and return.
|
||||
@@ -1745,6 +1824,9 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
|
||||
OEMCryptoResult OEMCrypto_SetDebugIgnoreKeyboxCount(uint32_t count) {
|
||||
return SetDebugIgnoreKeyboxCount(count);
|
||||
}
|
||||
OEMCryptoResult OEMCrypto_SetAllowTestKeybox(bool allow) {
|
||||
return SetAllowTestKeybox(allow);
|
||||
}
|
||||
|
||||
OEMCrypto_WatermarkingSupport OEMCrypto_GetWatermarkingSupport(
|
||||
wvcdm::RequestedSecurityLevel level) {
|
||||
|
||||
Reference in New Issue
Block a user