Add recoverable errors

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

Nonce flood, frame size, session and system invalidation errors
will now bubble up to the app. OEMCrypto v15 returns
OEMCrypto_ERROR_BUFFER_TOO_LARGE, OEMCrypto_ERROR_SESSION_LOST_STATE,
OEMCrypto_ERROR_SYSTEM_INVALIDATED and a variety of nonce errors.
These will be reported to HIDL as OUTPUT_TOO_LARGE_ERROR,
ERROR_DRM_SESSION_LOST_STATE, ERROR_DRM_INVALID_STATE and
ERROR_DRM_RESOURCE_CONTENTION.

Bug: 120572706
Test: Unit/Integration tests
Change-Id: Ida177300046327ce81592a273028ef6c3a0d9fd9
This commit is contained in:
Rahul Frias
2019-01-30 02:15:52 -08:00
parent 54104c7a22
commit 272e60db27
27 changed files with 977 additions and 648 deletions

View File

@@ -321,8 +321,16 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
// Get/set the nonce. This value will be reflected in the Key Control Block
// of the license response.
uint32_t nonce;
if (!crypto_session_->GenerateNonce(&nonce)) {
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
status = crypto_session_->GenerateNonce(&nonce);
switch (status) {
case NO_ERROR:
break;
case SESSION_LOST_STATE_ERROR:
case SYSTEM_INVALIDATED_ERROR:
return status;
default:
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
}
license_request.set_key_control_nonce(nonce);
LOGD("PrepareKeyRequest: nonce=%u", nonce);
@@ -337,10 +345,12 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
// Derive signing and encryption keys and construct signature.
std::string license_request_signature;
if (!crypto_session_->PrepareRequest(serialized_license_req, false,
&license_request_signature)) {
status = crypto_session_->PrepareRequest(serialized_license_req, false,
&license_request_signature);
if (status != NO_ERROR) {
signed_request->clear();
return LICENSE_REQUEST_SIGNING_ERROR;
return status;
}
if (license_request_signature.empty()) {
@@ -455,8 +465,16 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
// Get/set the nonce. This value will be reflected in the Key Control Block
// of the license response.
uint32_t nonce;
if (!crypto_session_->GenerateNonce(&nonce)) {
return LICENSE_RENEWAL_NONCE_GENERATION_ERROR;
CdmResponseType status = crypto_session_->GenerateNonce(&nonce);
switch (status) {
case NO_ERROR:
break;
case SESSION_LOST_STATE_ERROR:
case SYSTEM_INVALIDATED_ERROR:
return status;
default:
return LICENSE_RENEWAL_NONCE_GENERATION_ERROR;
}
license_request.set_key_control_nonce(nonce);
LOGD("PrepareKeyUpdateRequest: nonce=%u", nonce);
@@ -468,9 +486,9 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
// Construct signature.
std::string license_request_signature;
if (!crypto_session_->PrepareRenewalRequest(serialized_license_req,
&license_request_signature))
return LICENSE_RENEWAL_SIGNING_ERROR;
status = crypto_session_->PrepareRenewalRequest(serialized_license_req,
&license_request_signature);
if (status != NO_ERROR) return status;
if (license_request_signature.empty()) {
LOGE(
@@ -544,9 +562,11 @@ CdmResponseType CdmLicense::HandleKeyResponse(
LOGE("CdmLicense::HandleKeyResponse: no session keys present");
return SESSION_KEYS_NOT_FOUND;
}
if (!crypto_session_->GenerateDerivedKeys(key_request_,
signed_response.session_key()))
return GENERATE_DERIVED_KEYS_ERROR;
CdmResponseType status =
crypto_session_->GenerateDerivedKeys(key_request_,
signed_response.session_key());
if (status != NO_ERROR) return status;
// Extract mac key
std::string mac_key_iv;
@@ -584,7 +604,17 @@ CdmResponseType CdmLicense::HandleKeyResponse(
license_key_type_ = key_type;
provider_client_token_ = license.provider_client_token();
if (license.has_srm_update()) crypto_session_->LoadSrm(license.srm_update());
if (license.has_srm_update()) {
CdmResponseType status = crypto_session_->LoadSrm(license.srm_update());
switch (status) {
case NO_ERROR:
break;
case SYSTEM_INVALIDATED_ERROR:
return status;
default:
break; // Ignore
}
}
if (license.id().type() == video_widevine::OFFLINE &&
license.policy().can_persist())
@@ -689,15 +719,16 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
std::vector<CryptoKey> key_array = ExtractContentKeys(license);
if (crypto_session_->RefreshKeys(signed_response.msg(),
CdmResponseType status =
crypto_session_->RefreshKeys(signed_response.msg(),
signed_response.signature(),
key_array.size(), &key_array[0])) {
policy_engine_->UpdateLicense(license);
key_array.size(), &key_array[0]);
return KEY_ADDED;
} else {
return REFRESH_KEYS_ERROR;
if (status == KEY_ADDED) {
policy_engine_->UpdateLicense(license);
}
return status;
}
CdmResponseType CdmLicense::HandleEmbeddedKeyData(