Merge latest oemcrypto-v17 change
No-Typo-Check: Not related to this change. Bug: 161477208 Change-Id: I99e4780f6855b7045aa0cd5a49c13d2d0d51ed64
This commit is contained in:
committed by
Fred Gylys-Colwell
parent
c924960962
commit
642965c678
@@ -31,7 +31,7 @@
|
||||
|
||||
// Stringify turns macro arguments into static C strings.
|
||||
// Example: STRINGIFY(this_argument) -> "this_argument"
|
||||
#define STRINGIFY(PARAM...) #PARAM
|
||||
#define STRINGIFY(PARAM) #PARAM
|
||||
|
||||
#define RETURN_IF_NULL(PARAM, ret_value) \
|
||||
if ((PARAM) == nullptr) { \
|
||||
@@ -51,6 +51,16 @@
|
||||
return ret_value; \
|
||||
}
|
||||
|
||||
#ifdef HAS_DUAL_KEY
|
||||
/**
|
||||
* Internal only OEMCrypto method. This is called before parsing the license
|
||||
* response to indicate the response uses dual keys. If this isn't called,
|
||||
* it is using single keys.
|
||||
*/
|
||||
extern "C" OEMCryptoResult OEMCrypto_UseSecondaryKey(OEMCrypto_SESSION session,
|
||||
bool dual_key);
|
||||
#endif
|
||||
|
||||
namespace wvcdm {
|
||||
namespace {
|
||||
using UsageTableLock = std::unique_lock<std::recursive_mutex>;
|
||||
@@ -83,7 +93,7 @@ constexpr size_t kMaxSubsampleRegionSizes[] = {
|
||||
};
|
||||
// The +1 in this calculation is because the bounds RESOURCE_RATING_TIER_MAX and
|
||||
// RESOURCE_RATING_TIER_MIN are inclusive.
|
||||
static_assert(ArraySize(kMaxSubsampleRegionSizes) ==
|
||||
static_assert(wvutil::ArraySize(kMaxSubsampleRegionSizes) ==
|
||||
RESOURCE_RATING_TIER_MAX - RESOURCE_RATING_TIER_MIN + 1,
|
||||
"The kMaxSubsampleRegionSizes table needs to be updated to "
|
||||
"reflect the supported range of resource rating tiers");
|
||||
@@ -128,8 +138,8 @@ CdmResponseType MapOEMCryptoResult(OEMCryptoResult result,
|
||||
void AdvanceDestBuffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) {
|
||||
switch (dest_buffer->type) {
|
||||
case OEMCrypto_BufferType_Clear:
|
||||
dest_buffer->buffer.clear.address += bytes;
|
||||
dest_buffer->buffer.clear.address_length -= bytes;
|
||||
dest_buffer->buffer.clear.clear_buffer += bytes;
|
||||
dest_buffer->buffer.clear.clear_buffer_length -= bytes;
|
||||
return;
|
||||
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
@@ -176,8 +186,8 @@ size_t GenericEncryptionBlockSize(CdmEncryptionAlgorithm algorithm) {
|
||||
} // namespace
|
||||
|
||||
// CryptoSession variables allocation.
|
||||
shared_mutex CryptoSession::static_field_mutex_;
|
||||
shared_mutex CryptoSession::oem_crypto_mutex_;
|
||||
wvutil::shared_mutex CryptoSession::static_field_mutex_;
|
||||
wvutil::shared_mutex CryptoSession::oem_crypto_mutex_;
|
||||
bool CryptoSession::initialized_ = false;
|
||||
bool CryptoSession::needs_keybox_provisioning_ = false;
|
||||
int CryptoSession::session_count_ = 0;
|
||||
@@ -233,7 +243,7 @@ void GenerateMacContext(const std::string& input_context,
|
||||
deriv_context->assign(kSigningKeyLabel);
|
||||
deriv_context->append(1, '\0');
|
||||
deriv_context->append(input_context);
|
||||
deriv_context->append(EncodeUint32(kSigningKeySizeBits * 2));
|
||||
deriv_context->append(wvutil::EncodeUint32(kSigningKeySizeBits * 2));
|
||||
}
|
||||
|
||||
void GenerateEncryptContext(const std::string& input_context,
|
||||
@@ -249,12 +259,12 @@ void GenerateEncryptContext(const std::string& input_context,
|
||||
deriv_context->assign(kEncryptionKeyLabel);
|
||||
deriv_context->append(1, '\0');
|
||||
deriv_context->append(input_context);
|
||||
deriv_context->append(EncodeUint32(kEncryptionKeySizeBits));
|
||||
deriv_context->append(wvutil::EncodeUint32(kEncryptionKeySizeBits));
|
||||
}
|
||||
|
||||
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode) {
|
||||
return cipher_mode == kCipherModeCtr ? OEMCrypto_CipherMode_CTR
|
||||
: OEMCrypto_CipherMode_CBC;
|
||||
return cipher_mode == kCipherModeCtr ? OEMCrypto_CipherMode_CENC
|
||||
: OEMCrypto_CipherMode_CBCS;
|
||||
}
|
||||
|
||||
CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
|
||||
@@ -306,6 +316,9 @@ CdmResponseType CryptoSession::GetProvisioningMethod(
|
||||
case OEMCrypto_DrmCertificate:
|
||||
type = kClientTokenDrmCert;
|
||||
break;
|
||||
case OEMCrypto_BootCertificateChain:
|
||||
type = kClientTokenBootCertChain;
|
||||
break;
|
||||
case OEMCrypto_ProvisioningError:
|
||||
default:
|
||||
if (static_cast<int>(method) == 0 && needs_keybox_provisioning_) {
|
||||
@@ -361,10 +374,18 @@ void CryptoSession::Init() {
|
||||
void CryptoSession::ReinitializeForTest() {
|
||||
if (initialized_) {
|
||||
initialized_ = false;
|
||||
if (OEMCrypto_SUCCESS != OEMCrypto_Terminate()) return;
|
||||
OEMCryptoResult status = OEMCrypto_Terminate();
|
||||
if (OEMCrypto_SUCCESS != status) {
|
||||
LOGE("OEMCrypto_Terminate failed: %d", status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Give up if we cannot initialize at all.
|
||||
if (OEMCrypto_SUCCESS != OEMCrypto_Initialize()) return;
|
||||
OEMCryptoResult status = OEMCrypto_Initialize();
|
||||
if (OEMCrypto_SUCCESS != status) {
|
||||
LOGE("OEMCrypto_Initialize failed: %d", status);
|
||||
return;
|
||||
}
|
||||
initialized_ = true;
|
||||
// For integration and unit tests we will install a test keybox and do not
|
||||
// need to do keybox provisioning.
|
||||
@@ -562,10 +583,12 @@ CdmResponseType CryptoSession::GetTokenFromOemCert(std::string* token) {
|
||||
}
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetProvisioningToken(std::string* token) {
|
||||
if (token == nullptr) {
|
||||
CdmResponseType CryptoSession::GetProvisioningToken(
|
||||
std::string* token, std::string* additional_token) {
|
||||
if (token == nullptr || additional_token == nullptr) {
|
||||
metrics_->crypto_session_get_token_.Increment(PARAMETER_NULL);
|
||||
RETURN_IF_NULL(token, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(additional_token, PARAMETER_NULL);
|
||||
}
|
||||
|
||||
if (!IsInitialized()) {
|
||||
@@ -579,6 +602,8 @@ CdmResponseType CryptoSession::GetProvisioningToken(std::string* token) {
|
||||
status = GetTokenFromKeybox(token);
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
status = GetTokenFromOemCert(token);
|
||||
} else if (pre_provision_token_type_ == kClientTokenBootCertChain) {
|
||||
status = GetBootCertificateChain(token, additional_token);
|
||||
}
|
||||
metrics_->crypto_session_get_token_.Increment(status);
|
||||
return status;
|
||||
@@ -595,41 +620,28 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel(
|
||||
LOGV("Getting security level: requested_security_level = %s",
|
||||
SecurityLevelToString(requested_security_level));
|
||||
RETURN_IF_UNINITIALIZED(kSecurityLevelUninitialized);
|
||||
const char* const level = WithOecReadLock("GetSecurityLevel", [&] {
|
||||
return OEMCrypto_SecurityLevel(requested_security_level);
|
||||
});
|
||||
if (level == nullptr) {
|
||||
LOGE("Security level is null: requested_security_level = %d",
|
||||
const OEMCrypto_Security_Level level = WithOecReadLock(
|
||||
"GetSecurityLevel",
|
||||
[&] { return OEMCrypto_SecurityLevel(requested_security_level); });
|
||||
if (level == 0) {
|
||||
LOGE("Security level is unknown: requested_security_level = %d",
|
||||
static_cast<int>(requested_security_level));
|
||||
return kSecurityLevelUnknown;
|
||||
}
|
||||
// Check length in the event of a bad pointer.
|
||||
// |kMaxSecurityLevelLength| is a value larger than expected to
|
||||
// be able to detect an overrun.
|
||||
constexpr size_t kMaxSecurityLevelLength = 5;
|
||||
const size_t length = strnlen(level, kMaxSecurityLevelLength);
|
||||
constexpr size_t kExpectedSecurityLevelLength = 2;
|
||||
if (length != kExpectedSecurityLevelLength) {
|
||||
LOGE(
|
||||
"Unexpected security level length: "
|
||||
"length = %zu, requested_security_level = %s",
|
||||
length, SecurityLevelToString(requested_security_level));
|
||||
return kSecurityLevelUnknown;
|
||||
}
|
||||
const std::string security_level(level);
|
||||
if (security_level == "L1") {
|
||||
if (level == OEMCrypto_Level1) {
|
||||
return kSecurityLevelL1;
|
||||
}
|
||||
if (security_level == "L2") {
|
||||
if (level == OEMCrypto_Level2) {
|
||||
return kSecurityLevelL2;
|
||||
}
|
||||
if (security_level == "L3") {
|
||||
if (level == OEMCrypto_Level3) {
|
||||
return kSecurityLevelL3;
|
||||
}
|
||||
LOGE(
|
||||
"Ill-formed security level: "
|
||||
"level = \"%s\", requested_security_level = %s",
|
||||
security_level.c_str(), SecurityLevelToString(requested_security_level));
|
||||
"level = \"L%u\", requested_security_level = %s",
|
||||
static_cast<unsigned int>(level),
|
||||
SecurityLevelToString(requested_security_level));
|
||||
return kSecurityLevelUnknown;
|
||||
}
|
||||
|
||||
@@ -815,6 +827,11 @@ CdmResponseType CryptoSession::GetSystemIdInternal(uint32_t* system_id) {
|
||||
// Drm certificate.
|
||||
return NO_ERROR;
|
||||
}
|
||||
if (pre_provision_token_type_ == kClientTokenBootCertChain) {
|
||||
// A system id can not be inferred from BCC. If the provisioning process has
|
||||
// come to the second stage, we may read system id from the stored OEM cert.
|
||||
return NO_ERROR;
|
||||
}
|
||||
LOGE("Unsupported pre-provision token type: %d",
|
||||
static_cast<int>(pre_provision_token_type_));
|
||||
return UNKNOWN_CLIENT_TOKEN_TYPE;
|
||||
@@ -938,10 +955,10 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
metrics_->oemcrypto_get_random_.Increment(random_sts);
|
||||
uint64_t request_id_index =
|
||||
request_id_index_source_.fetch_add(1, std::memory_order_relaxed);
|
||||
request_id_ = HexEncode(reinterpret_cast<uint8_t*>(&request_id_base),
|
||||
sizeof(request_id_base)) +
|
||||
HexEncode(reinterpret_cast<uint8_t*>(&request_id_index),
|
||||
sizeof(request_id_index));
|
||||
request_id_ = wvutil::HexEncode(reinterpret_cast<uint8_t*>(&request_id_base),
|
||||
sizeof(request_id_base)) +
|
||||
wvutil::HexEncode(reinterpret_cast<uint8_t*>(&request_id_index),
|
||||
sizeof(request_id_index));
|
||||
|
||||
// Initialize key session
|
||||
WithOecSessionLock("Open() calling key_session_.reset()", [&] {
|
||||
@@ -1058,6 +1075,19 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest(
|
||||
"PrepareAndSignLicenseRequest");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::UseSecondaryKey(bool dual_key) {
|
||||
#ifdef HAS_DUAL_KEY
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("UseSecondaryKey", [&] {
|
||||
sts = OEMCrypto_UseSecondaryKey(oec_session_id_, dual_key);
|
||||
});
|
||||
|
||||
return MapOEMCryptoResult(sts, LOAD_KEY_ERROR, "UseSecondaryKey");
|
||||
#else
|
||||
return NO_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::LoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
const std::string& mac_key_iv, const std::string& mac_key,
|
||||
@@ -1388,6 +1418,122 @@ CdmResponseType CryptoSession::LoadCertificatePrivateKey(
|
||||
"LoadCertificatePrivateKey");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetBootCertificateChain(
|
||||
std::string* bcc, std::string* additional_signature) {
|
||||
RETURN_IF_NULL(bcc, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(additional_signature, PARAMETER_NULL);
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
LOGV("GetBootCertificateChain");
|
||||
if (pre_provision_token_type_ != kClientTokenBootCertChain) {
|
||||
return PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
size_t bcc_length = 0;
|
||||
size_t additional_signature_length = 0;
|
||||
OEMCryptoResult sts;
|
||||
WithOecReadLock("GetBootCertificateChain Attempt 1", [&] {
|
||||
sts = OEMCrypto_GetBootCertificateChain(nullptr, &bcc_length, nullptr,
|
||||
&additional_signature_length);
|
||||
});
|
||||
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
bcc->resize(bcc_length);
|
||||
additional_signature->resize(additional_signature_length);
|
||||
WithOecReadLock("GetBootCertificateChain Attempt 2", [&] {
|
||||
sts = OEMCrypto_GetBootCertificateChain(
|
||||
reinterpret_cast<uint8_t*>(&bcc->front()), &bcc_length,
|
||||
reinterpret_cast<uint8_t*>(&additional_signature->front()),
|
||||
&additional_signature_length);
|
||||
});
|
||||
}
|
||||
return MapOEMCryptoResult(sts, GET_BOOT_CERTIFICATE_CHAIN_ERROR,
|
||||
"GetBootCertificateChain");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GenerateCertificateKeyPair(
|
||||
std::string* public_key, std::string* public_key_signature,
|
||||
std::string* wrapped_private_key, CryptoWrappedKey::Type* key_type) {
|
||||
LOGV("Generating certificate key pair: id = %u", oec_session_id_);
|
||||
RETURN_IF_NULL(public_key, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(public_key_signature, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(wrapped_private_key, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(key_type, PARAMETER_NULL);
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
|
||||
// Round 1, get the size of all the fields.
|
||||
size_t public_key_length = 0;
|
||||
size_t public_key_signature_length = 0;
|
||||
size_t wrapped_private_key_length = 0;
|
||||
OEMCrypto_PrivateKeyType oemcrypto_key_type;
|
||||
OEMCryptoResult status;
|
||||
WithOecSessionLock("GenerateCertificateKeyPair Attempt 1", [&] {
|
||||
M_TIME(status = OEMCrypto_GenerateCertificateKeyPair(
|
||||
oec_session_id_, nullptr, &public_key_length, nullptr,
|
||||
&public_key_signature_length, nullptr,
|
||||
&wrapped_private_key_length, &oemcrypto_key_type),
|
||||
metrics_, oemcrypto_generate_certificate_key_pair_, status);
|
||||
});
|
||||
|
||||
if (status != OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
return MapOEMCryptoResult(status, GENERATE_CERTIFICATE_KEY_PAIR_ERROR,
|
||||
"GenerateCertificateKeyPair");
|
||||
}
|
||||
|
||||
public_key->resize(public_key_length);
|
||||
public_key_signature->resize(public_key_signature_length);
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
WithOecSessionLock("GenerateCertificateKeyPair Attempt 2", [&] {
|
||||
M_TIME(
|
||||
status = OEMCrypto_GenerateCertificateKeyPair(
|
||||
oec_session_id_, reinterpret_cast<uint8_t*>(&public_key->front()),
|
||||
&public_key_length,
|
||||
reinterpret_cast<uint8_t*>(&public_key_signature->front()),
|
||||
&public_key_signature_length,
|
||||
reinterpret_cast<uint8_t*>(&wrapped_private_key->front()),
|
||||
&wrapped_private_key_length, &oemcrypto_key_type),
|
||||
metrics_, oemcrypto_generate_certificate_key_pair_, status);
|
||||
});
|
||||
public_key->resize(public_key_length);
|
||||
public_key_signature->resize(public_key_signature_length);
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
|
||||
if (oemcrypto_key_type == OEMCrypto_RSA_Private_Key) {
|
||||
*key_type = CryptoWrappedKey::kRsa;
|
||||
} else if (oemcrypto_key_type == OEMCrypto_ECC_Private_Key) {
|
||||
*key_type = CryptoWrappedKey::kEcc;
|
||||
} else {
|
||||
LOGE("Unexpected key type returned from GenerateCertificateKeyPair: %d",
|
||||
static_cast<int>(oemcrypto_key_type));
|
||||
return MapOEMCryptoResult(status,
|
||||
GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR,
|
||||
"GenerateCertificateKeyPair");
|
||||
}
|
||||
|
||||
return MapOEMCryptoResult(status, GENERATE_CERTIFICATE_KEY_PAIR_ERROR,
|
||||
"GenerateCertificateKeyPair");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::LoadOemCertificatePrivateKey(
|
||||
const CryptoWrappedKey& private_key) {
|
||||
LOGV("Load OEM cert and private key: id = %u", oec_session_id_);
|
||||
const OEMCrypto_PrivateKeyType key_type =
|
||||
(private_key.type() == CryptoWrappedKey::kEcc)
|
||||
? OEMCrypto_ECC_Private_Key
|
||||
: OEMCrypto_RSA_Private_Key;
|
||||
const std::string& wrapped_private_key = private_key.key();
|
||||
|
||||
OEMCryptoResult status;
|
||||
WithOecSessionLock("InstallOemPrivateKey", [&] {
|
||||
M_TIME(status = OEMCrypto_InstallOemPrivateKey(
|
||||
oec_session_id_, key_type,
|
||||
reinterpret_cast<const uint8_t*>(wrapped_private_key.data()),
|
||||
wrapped_private_key.size()),
|
||||
metrics_, oemcrypto_install_oem_private_key_, status);
|
||||
});
|
||||
|
||||
return MapOEMCryptoResult(status, LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR,
|
||||
"InstallOemPrivateKey");
|
||||
}
|
||||
|
||||
// Private.
|
||||
CdmResponseType CryptoSession::SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode) {
|
||||
@@ -1502,7 +1648,7 @@ size_t CryptoSession::GetMaxSubsampleRegionSize() {
|
||||
// Subtract RESOURCE_RATING_TIER_MIN to get a 0-based index into the
|
||||
// table.
|
||||
const uint32_t index = tier - RESOURCE_RATING_TIER_MIN;
|
||||
if (index < ArraySize(kMaxSubsampleRegionSizes)) {
|
||||
if (index < wvutil::ArraySize(kMaxSubsampleRegionSizes)) {
|
||||
max_subsample_region_size_ = kMaxSubsampleRegionSizes[index];
|
||||
}
|
||||
}
|
||||
@@ -1563,16 +1709,16 @@ CdmResponseType CryptoSession::Decrypt(
|
||||
output_descriptor.type = output_descriptor_type;
|
||||
switch (output_descriptor.type) {
|
||||
case OEMCrypto_BufferType_Clear:
|
||||
output_descriptor.buffer.clear.address =
|
||||
output_descriptor.buffer.clear.clear_buffer =
|
||||
static_cast<uint8_t*>(sample.decrypt_buffer) +
|
||||
sample.decrypt_buffer_offset;
|
||||
output_descriptor.buffer.clear.address_length =
|
||||
output_descriptor.buffer.clear.clear_buffer_length =
|
||||
sample.decrypt_buffer_size - sample.decrypt_buffer_offset;
|
||||
break;
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
output_descriptor.buffer.secure.handle = sample.decrypt_buffer;
|
||||
output_descriptor.buffer.secure.secure_buffer = sample.decrypt_buffer;
|
||||
output_descriptor.buffer.secure.offset = sample.decrypt_buffer_offset;
|
||||
output_descriptor.buffer.secure.handle_length =
|
||||
output_descriptor.buffer.secure.secure_buffer_length =
|
||||
sample.decrypt_buffer_size;
|
||||
break;
|
||||
case OEMCrypto_BufferType_Direct:
|
||||
@@ -1824,7 +1970,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
|
||||
(*usage_report) =
|
||||
std::string(reinterpret_cast<const char*>(&buffer[0]), buffer.size());
|
||||
|
||||
Unpacked_PST_Report pst_report(&buffer[0]);
|
||||
wvutil::Unpacked_PST_Report pst_report(&buffer[0]);
|
||||
*usage_duration_status = kUsageDurationsInvalid;
|
||||
if (usage_length < pst_report.report_size()) {
|
||||
LOGE(
|
||||
@@ -1852,7 +1998,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
|
||||
pst_report.seconds_since_first_decrypt());
|
||||
LOGV("OEMCrypto_PST_Report.seconds_since_last_decrypt: %" PRId64 "\n",
|
||||
pst_report.seconds_since_last_decrypt());
|
||||
LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str());
|
||||
LOGV("OEMCrypto_PST_Report: %s\n", wvutil::b2a_hex(*usage_report).c_str());
|
||||
|
||||
if (kInactiveUnused == pst_report.status()) {
|
||||
*usage_duration_status = kUsageDurationPlaybackNotBegun;
|
||||
@@ -2096,29 +2242,6 @@ CdmResponseType CryptoSession::GetSrmVersion(uint16_t* srm_version) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoSession::IsSrmUpdateSupported() {
|
||||
LOGV("Checking if SRM update is supported");
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
return WithOecReadLock("IsSrmUpdateSupported",
|
||||
[&] { return OEMCrypto_IsSRMUpdateSupported(); });
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::LoadSrm(const std::string& srm) {
|
||||
LOGV("Loading SRM");
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
if (srm.empty()) {
|
||||
LOGE("SRM is empty");
|
||||
return INVALID_SRM_LIST;
|
||||
}
|
||||
|
||||
const OEMCryptoResult status = WithOecWriteLock("LoadSrm", [&] {
|
||||
return OEMCrypto_LoadSRM(reinterpret_cast<const uint8_t*>(srm.data()),
|
||||
srm.size());
|
||||
});
|
||||
|
||||
return MapOEMCryptoResult(status, LOAD_SRM_ERROR, "LoadSRM");
|
||||
}
|
||||
|
||||
bool CryptoSession::GetResourceRatingTier(uint32_t* tier) {
|
||||
LOGV("Getting resource rating tier");
|
||||
RETURN_IF_NOT_OPEN(false);
|
||||
@@ -2160,16 +2283,28 @@ bool CryptoSession::GetBuildInformation(SecurityLevel security_level,
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
RETURN_IF_NULL(info, false);
|
||||
|
||||
const char* build_information;
|
||||
OEMCryptoResult build_information;
|
||||
std::string buf;
|
||||
size_t buf_length = 0;
|
||||
WithOecReadLock("GetBuildInformation", [&] {
|
||||
build_information = OEMCrypto_BuildInformation(security_level);
|
||||
build_information =
|
||||
OEMCrypto_BuildInformation(&buf[0], &buf_length, security_level);
|
||||
});
|
||||
if (build_information == nullptr) {
|
||||
LOGE("OEMCrypto_BuildInformation failed: Returned null");
|
||||
if (build_information == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
buf.resize(buf_length);
|
||||
WithOecReadLock("GetBuildInformation Attempt 2", [&] {
|
||||
build_information =
|
||||
OEMCrypto_BuildInformation(&buf[0], &buf_length, security_level);
|
||||
});
|
||||
}
|
||||
|
||||
if (build_information == OEMCrypto_SUCCESS) {
|
||||
*info = buf;
|
||||
} else {
|
||||
LOGE("Unexpected return value");
|
||||
return false;
|
||||
}
|
||||
|
||||
info->assign(build_information);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2892,9 +3027,9 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
||||
fake_sample.buffers.input_data += length;
|
||||
AdvanceDestBuffer(&fake_sample.buffers.output_descriptor, length);
|
||||
if (cipher_mode == kCipherModeCtr) {
|
||||
AdvanceIvCtr(&fake_sample.iv,
|
||||
original_subsample.block_offset +
|
||||
original_subsample.num_bytes_encrypted);
|
||||
wvutil::AdvanceIvCtr(&fake_sample.iv,
|
||||
original_subsample.block_offset +
|
||||
original_subsample.num_bytes_encrypted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3049,7 +3184,8 @@ OEMCryptoResult CryptoSession::LegacyDecryptInChunks(
|
||||
if (cipher_mode == kCipherModeCtr) {
|
||||
// For 'cenc', update the IV depending on how many encrypted blocks
|
||||
// we passed.
|
||||
AdvanceIvCtr(&fake_sample.iv, chunk_size + fake_subsample.block_offset);
|
||||
wvutil::AdvanceIvCtr(&fake_sample.iv,
|
||||
chunk_size + fake_subsample.block_offset);
|
||||
} else if (cipher_mode == kCipherModeCbc) {
|
||||
// For 'cbcs', use the last ciphertext block as the next IV. The last
|
||||
// block that was encrypted is probably not the last block of the
|
||||
@@ -3154,7 +3290,7 @@ template <class Func>
|
||||
auto CryptoSession::WithStaticFieldWriteLock(const char* tag, Func body)
|
||||
-> decltype(body()) {
|
||||
LOGV("Static field write lock: %s", tag);
|
||||
std::unique_lock<shared_mutex> auto_lock(static_field_mutex_);
|
||||
std::unique_lock<wvutil::shared_mutex> auto_lock(static_field_mutex_);
|
||||
return body();
|
||||
}
|
||||
|
||||
@@ -3162,7 +3298,7 @@ template <class Func>
|
||||
auto CryptoSession::WithStaticFieldReadLock(const char* tag, Func body)
|
||||
-> decltype(body()) {
|
||||
LOGV("Static field read lock: %s", tag);
|
||||
shared_lock<shared_mutex> auto_lock(static_field_mutex_);
|
||||
wvutil::shared_lock<wvutil::shared_mutex> auto_lock(static_field_mutex_);
|
||||
return body();
|
||||
}
|
||||
|
||||
@@ -3170,7 +3306,7 @@ template <class Func>
|
||||
auto CryptoSession::WithOecWriteLock(const char* tag, Func body)
|
||||
-> decltype(body()) {
|
||||
LOGV("OEMCrypto write lock: %s", tag);
|
||||
std::unique_lock<shared_mutex> auto_lock(oem_crypto_mutex_);
|
||||
std::unique_lock<wvutil::shared_mutex> auto_lock(oem_crypto_mutex_);
|
||||
return body();
|
||||
}
|
||||
|
||||
@@ -3178,7 +3314,7 @@ template <class Func>
|
||||
auto CryptoSession::WithOecReadLock(const char* tag, Func body)
|
||||
-> decltype(body()) {
|
||||
LOGV("OEMCrypto read lock: %s", tag);
|
||||
shared_lock<shared_mutex> auto_lock(oem_crypto_mutex_);
|
||||
wvutil::shared_lock<wvutil::shared_mutex> auto_lock(oem_crypto_mutex_);
|
||||
return body();
|
||||
}
|
||||
|
||||
@@ -3186,7 +3322,7 @@ template <class Func>
|
||||
auto CryptoSession::WithOecSessionLock(const char* tag, Func body)
|
||||
-> decltype(body()) {
|
||||
LOGV("OEMCrypto session lock: %s", tag);
|
||||
shared_lock<shared_mutex> oec_auto_lock(oem_crypto_mutex_);
|
||||
wvutil::shared_lock<wvutil::shared_mutex> oec_auto_lock(oem_crypto_mutex_);
|
||||
std::unique_lock<std::mutex> session_auto_lock(oem_crypto_session_mutex_);
|
||||
return body();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user