Pick widevine oemcrypto-v18 change
No-Typo-Check: From a third party header file Bug: 260918793 Test: unit tests Test: atp v2/widevine-eng/drm_compliance Change-Id: I36effd6a10a99bdb2399ab1f4a0fad026d607c70
This commit is contained in:
@@ -16,10 +16,12 @@
|
||||
|
||||
#include "advance_iv_ctr.h"
|
||||
#include "arraysize.h"
|
||||
#include "cdm_random.h"
|
||||
#include "content_key_session.h"
|
||||
#include "crypto_key.h"
|
||||
#include "entitlement_key_session.h"
|
||||
#include "log.h"
|
||||
#include "odk_structs.h"
|
||||
#include "okp_fallback_policy.h"
|
||||
#include "platform.h"
|
||||
#include "privacy_crypto.h"
|
||||
@@ -407,6 +409,8 @@ void CryptoSession::ReinitializeForTest() {
|
||||
LOGE("OEMCrypto_Initialize failed: %d", status);
|
||||
return;
|
||||
}
|
||||
OEMCrypto_SetMaxAPIVersion(ODK_MAJOR_VERSION);
|
||||
OEMCrypto_EnterTestMode();
|
||||
initialized_ = true;
|
||||
// For integration and unit tests we will install a test keybox and do not
|
||||
// need to do keybox provisioning.
|
||||
@@ -926,13 +930,8 @@ CdmResponseType CryptoSession::Open(
|
||||
open_ = true;
|
||||
|
||||
// Set up request ID
|
||||
uint64_t request_id_base;
|
||||
OEMCryptoResult random_sts;
|
||||
WithOecReadLock("Open() calling OEMCrypto_GetRandom", [&] {
|
||||
random_sts = OEMCrypto_GetRandom(
|
||||
reinterpret_cast<uint8_t*>(&request_id_base), sizeof(request_id_base));
|
||||
});
|
||||
metrics_->oemcrypto_get_random_.Increment(random_sts);
|
||||
uint64_t request_id_base =
|
||||
wvutil::CdmRandom::RandomInRange(std::numeric_limits<uint64_t>::max());
|
||||
uint64_t request_id_index =
|
||||
request_id_index_source_.fetch_add(1, std::memory_order_relaxed);
|
||||
request_id_ = wvutil::HexEncode(reinterpret_cast<uint8_t*>(&request_id_base),
|
||||
@@ -942,7 +941,8 @@ CdmResponseType CryptoSession::Open(
|
||||
|
||||
// Initialize key session
|
||||
WithOecSessionLock("Open() calling key_session_.reset()", [&] {
|
||||
key_session_.reset(new ContentKeySession(oec_session_id_, metrics_));
|
||||
key_session_.reset(new ContentKeySession(requested_security_level_,
|
||||
oec_session_id_, metrics_));
|
||||
});
|
||||
|
||||
if (!GetApiVersion(&api_version_)) {
|
||||
@@ -987,13 +987,27 @@ void CryptoSession::Close() {
|
||||
|
||||
CdmResponseType CryptoSession::PrepareAndSignLicenseRequest(
|
||||
const std::string& message, std::string* core_message,
|
||||
std::string* signature) {
|
||||
std::string* signature, bool& should_specify_algorithm,
|
||||
OEMCrypto_SignatureHashAlgorithm& algorithm) {
|
||||
LOGV("Preparing and signing license request: id = %u", oec_session_id_);
|
||||
RETURN_IF_NULL(signature, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(core_message, PARAMETER_NULL);
|
||||
RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN);
|
||||
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GetSignatureHashAlgorithm", [&] {
|
||||
sts = OEMCrypto_GetSignatureHashAlgorithm(oec_session_id_, &algorithm);
|
||||
});
|
||||
metrics_->oemcrypto_get_signature_hash_algorithm_.Increment(sts, algorithm);
|
||||
if (sts == OEMCrypto_SUCCESS) {
|
||||
should_specify_algorithm = true;
|
||||
} else if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
should_specify_algorithm = false;
|
||||
} else {
|
||||
return MapOEMCryptoResult(sts, GET_SIGNATURE_HASH_ALGORITHM_ERROR_1,
|
||||
"PrepareAndSignLicenseRequest");
|
||||
}
|
||||
|
||||
size_t signature_length = 0;
|
||||
size_t core_message_length = 0;
|
||||
*core_message = "";
|
||||
@@ -1081,7 +1095,8 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message,
|
||||
WithOecSessionLock("LoadLicense", [&] {
|
||||
if (key_type == kLicenseKeyTypeEntitlement &&
|
||||
key_session_->Type() != KeySession::kEntitlement) {
|
||||
key_session_.reset(new EntitlementKeySession(oec_session_id_, metrics_));
|
||||
key_session_.reset(new EntitlementKeySession(requested_security_level_,
|
||||
oec_session_id_, metrics_));
|
||||
}
|
||||
|
||||
M_TIME(sts = OEMCrypto_LoadLicense(
|
||||
@@ -1110,7 +1125,8 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message,
|
||||
|
||||
CdmResponseType CryptoSession::PrepareAndSignRenewalRequest(
|
||||
const std::string& message, std::string* core_message,
|
||||
std::string* signature) {
|
||||
std::string* signature, bool& should_specify_algorithm,
|
||||
OEMCrypto_SignatureHashAlgorithm& algorithm) {
|
||||
LOGV("Preparing and signing renewal request: id = %u", oec_session_id_);
|
||||
if (signature == nullptr) {
|
||||
LOGE("Output parameter |signature| not provided");
|
||||
@@ -1122,6 +1138,19 @@ CdmResponseType CryptoSession::PrepareAndSignRenewalRequest(
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GetSignatureHashAlgorithm", [&] {
|
||||
sts = OEMCrypto_GetSignatureHashAlgorithm(oec_session_id_, &algorithm);
|
||||
});
|
||||
metrics_->oemcrypto_get_signature_hash_algorithm_.Increment(sts, algorithm);
|
||||
if (sts == OEMCrypto_SUCCESS) {
|
||||
should_specify_algorithm = true;
|
||||
} else if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
should_specify_algorithm = false;
|
||||
} else {
|
||||
return MapOEMCryptoResult(sts, GET_SIGNATURE_HASH_ALGORITHM_ERROR_2,
|
||||
"PrepareAndSignRenewalRequest");
|
||||
}
|
||||
|
||||
size_t signature_length = 0;
|
||||
size_t core_message_length = 0;
|
||||
*core_message = "";
|
||||
@@ -1197,7 +1226,8 @@ CdmResponseType CryptoSession::LoadRenewal(const std::string& signed_message,
|
||||
|
||||
CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
|
||||
const std::string& message, std::string* core_message,
|
||||
std::string* signature) {
|
||||
std::string* signature, bool& should_specify_algorithm,
|
||||
OEMCrypto_SignatureHashAlgorithm& algorithm) {
|
||||
LOGV("Preparing and signing provisioning request: id = %u", oec_session_id_);
|
||||
if (signature == nullptr) {
|
||||
LOGE("Output parameter |signature| not provided");
|
||||
@@ -1208,21 +1238,42 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
|
||||
return CdmResponseType(PARAMETER_NULL);
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
should_specify_algorithm = false;
|
||||
const CdmResponseType status = GenerateDerivedKeys(message);
|
||||
if (status != NO_ERROR) return status;
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
const OEMCryptoResult status = OEMCrypto_LoadOEMPrivateKey(oec_session_id_);
|
||||
if (status != OEMCrypto_SUCCESS) {
|
||||
return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR,
|
||||
should_specify_algorithm = true;
|
||||
WithOecSessionLock("LoadOEMPrivateKey", [&] {
|
||||
sts = OEMCrypto_LoadOEMPrivateKey(oec_session_id_);
|
||||
});
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
return MapOEMCryptoResult(sts, GET_TOKEN_FROM_OEM_CERT_ERROR,
|
||||
"PrepareAndSignProvisioningRequest");
|
||||
}
|
||||
} else if (pre_provision_token_type_ == kClientTokenBootCertChain) {
|
||||
should_specify_algorithm = true;
|
||||
// Do nothing here. The key to signing the provisioning 4.0 request for each
|
||||
// stage has been loaded already when it was generated by OEMCrypto.
|
||||
} else {
|
||||
LOGE("Unknown method %d", pre_provision_token_type_);
|
||||
return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE);
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
if (should_specify_algorithm) {
|
||||
WithOecSessionLock("GetSignatureHashAlgorithm", [&] {
|
||||
sts = OEMCrypto_GetSignatureHashAlgorithm(oec_session_id_, &algorithm);
|
||||
});
|
||||
metrics_->oemcrypto_get_signature_hash_algorithm_.Increment(sts, algorithm);
|
||||
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
should_specify_algorithm = false;
|
||||
} else if (sts != OEMCrypto_SUCCESS) {
|
||||
return MapOEMCryptoResult(sts, GET_SIGNATURE_HASH_ALGORITHM_ERROR_3,
|
||||
"PrepareAndSignProvisioningRequest");
|
||||
}
|
||||
}
|
||||
|
||||
size_t signature_length = 0;
|
||||
size_t core_message_length = 0;
|
||||
*core_message = "";
|
||||
@@ -2091,18 +2142,6 @@ bool CryptoSession::GetSupportedCertificateTypes(
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetRandom(size_t data_length,
|
||||
uint8_t* random_data) {
|
||||
RETURN_IF_NULL(random_data, PARAMETER_NULL);
|
||||
|
||||
OEMCryptoResult sts;
|
||||
WithOecReadLock("GetRandom",
|
||||
[&] { sts = OEMCrypto_GetRandom(random_data, data_length); });
|
||||
metrics_->oemcrypto_get_random_.Increment(sts);
|
||||
|
||||
return MapOEMCryptoResult(sts, RANDOM_GENERATION_ERROR, "GetRandom");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetNumberOfOpenSessions(
|
||||
RequestedSecurityLevel security_level, size_t* count) {
|
||||
LOGV("Getting number of open sessions: id = %u, security_level = %s",
|
||||
@@ -2435,14 +2474,8 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer,
|
||||
OEMCryptoResult sts;
|
||||
|
||||
WithOecSessionLock("GenericEncrypt", [&] {
|
||||
M_TIME(
|
||||
sts = OEMCrypto_Generic_Encrypt(
|
||||
oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()),
|
||||
in_buffer.size(), reinterpret_cast<const uint8_t*>(iv.data()),
|
||||
oec_algorithm,
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(out_buffer->data()))),
|
||||
metrics_, oemcrypto_generic_encrypt_, sts,
|
||||
metrics::Pow2Bucket(in_buffer.size()));
|
||||
sts =
|
||||
key_session_->GenericEncrypt(in_buffer, iv, oec_algorithm, out_buffer);
|
||||
});
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
@@ -2496,14 +2529,8 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer,
|
||||
OEMCryptoResult sts;
|
||||
|
||||
WithOecSessionLock("GenericDecrypt", [&] {
|
||||
M_TIME(
|
||||
sts = OEMCrypto_Generic_Decrypt(
|
||||
oec_session_id_, reinterpret_cast<const uint8_t*>(in_buffer.data()),
|
||||
in_buffer.size(), reinterpret_cast<const uint8_t*>(iv.data()),
|
||||
oec_algorithm,
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(out_buffer->data()))),
|
||||
metrics_, oemcrypto_generic_decrypt_, sts,
|
||||
metrics::Pow2Bucket(in_buffer.size()));
|
||||
sts =
|
||||
key_session_->GenericDecrypt(in_buffer, iv, oec_algorithm, out_buffer);
|
||||
});
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
@@ -2542,45 +2569,20 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message,
|
||||
return CdmResponseType(INVALID_PARAMETERS_ENG_15);
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
size_t length = signature->size();
|
||||
|
||||
// TODO(jfore): We need to select a key with a cipher mode and algorithm
|
||||
// doesn't seem to fit. Is it ok to just use a default value here?
|
||||
// Or do we need to pass it in?
|
||||
CdmResponseType result = SelectKey(key_id, kCipherModeCbc);
|
||||
if (result != NO_ERROR) return result;
|
||||
|
||||
// At most two attempts.
|
||||
// The first attempt may fail due to buffer too short
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
WithOecSessionLock("GenericSign", [&] {
|
||||
M_TIME(
|
||||
sts = OEMCrypto_Generic_Sign(
|
||||
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
|
||||
message.size(), oec_algorithm,
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(signature->data())),
|
||||
&length),
|
||||
metrics_, oemcrypto_generic_sign_, sts,
|
||||
metrics::Pow2Bucket(message.size()));
|
||||
});
|
||||
|
||||
if (OEMCrypto_SUCCESS == sts) {
|
||||
// Trim signature buffer and done
|
||||
signature->resize(length);
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Retry with proper-sized return buffer
|
||||
signature->resize(length);
|
||||
}
|
||||
|
||||
LOGE("OEMCrypto_Generic_Sign failed: status = %d", static_cast<int>(sts));
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GenericSign", [&] {
|
||||
sts = key_session_->GenericSign(message, oec_algorithm, signature);
|
||||
});
|
||||
|
||||
switch (sts) {
|
||||
case OEMCrypto_SUCCESS:
|
||||
return CdmResponseType(NO_ERROR);
|
||||
case OEMCrypto_ERROR_KEY_EXPIRED:
|
||||
return CRYPTO_ERROR(NEED_KEY, sts);
|
||||
case OEMCrypto_ERROR_NO_CONTENT_KEY:
|
||||
@@ -2616,14 +2618,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
|
||||
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GenericVerify", [&] {
|
||||
M_TIME(
|
||||
sts = OEMCrypto_Generic_Verify(
|
||||
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
|
||||
message.size(), oec_algorithm,
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size()),
|
||||
metrics_, oemcrypto_generic_verify_, sts,
|
||||
metrics::Pow2Bucket(signature.size()));
|
||||
sts = key_session_->GenericVerify(message, oec_algorithm, signature);
|
||||
});
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
@@ -2921,12 +2916,6 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output,
|
||||
return true;
|
||||
}
|
||||
|
||||
// OEMCryptoResult OEMCrypto_DecryptCENC(
|
||||
// OEMCrypto_SESSION session,
|
||||
// const OEMCrypto_SampleDescription* samples, // an array of samples.
|
||||
// size_t samples_length, // the number of samples.
|
||||
// const OEMCrypto_CENCEncryptPatternDesc* pattern);
|
||||
|
||||
OEMCryptoResult CryptoSession::DecryptMultipleSamples(
|
||||
const std::vector<OEMCrypto_SampleDescription>& samples,
|
||||
CdmCipherMode cipher_mode,
|
||||
|
||||
Reference in New Issue
Block a user