Correct request_license_test failures

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

* While deprecating keyboxes as identification, some code to
  restore a license was mistakenly removed in http:://go/wvgerrit/36740,
  http://ag/3442777

* Corrections to keep track of cipher mode, call SelectKeys when cipher
  mode changes and to use the backward compatible LoadKeys call in case
  OEMCrypto is v13.

Bug: 70160032

Test: Ran WV unit/integration tests. Request license test failures
      have been addressed.

Change-Id: Id03c50874085af6d9985d10c19a74a02efb7a1f5
This commit is contained in:
Rahul Frias
2018-01-31 00:19:00 -08:00
parent 51212b1505
commit d9d53dee3b
7 changed files with 279 additions and 33 deletions

View File

@@ -74,12 +74,14 @@ OEMCryptoResult ContentKeySession::LoadKeys(
OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id,
CdmCipherMode cipher_mode) {
// Crypto session lock already locked.
if (!cached_key_id_.empty() && cached_key_id_ == key_id) {
// Already using the desired key.
if (!cached_key_id_.empty() && cached_key_id_ == key_id &&
cipher_mode_ == cipher_mode) {
// Already using the desired key and cipher mode.
return OEMCrypto_SUCCESS;
}
cached_key_id_ = key_id;
cipher_mode_ = cipher_mode;
const uint8_t* key_id_string =
reinterpret_cast<const uint8_t*>(cached_key_id_.data());
@@ -87,7 +89,7 @@ OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id,
OEMCryptoResult sts;
M_TIME(sts = OEMCrypto_SelectKey(
oec_session_id_, key_id_string, cached_key_id_.size(),
static_cast<OEMCryptoCipherMode>(cipher_mode)),
ToOEMCryptoCipherMode(cipher_mode)),
metrics_, oemcrypto_select_key_, sts);
if (OEMCrypto_SUCCESS != sts) {
@@ -120,16 +122,17 @@ OEMCryptoResult ContentKeySession::LoadKeys(
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
const uint8_t* enc_mac_key = NULL;
const uint8_t* enc_mac_key_iv = NULL;
cached_key_id_.clear();
if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) {
enc_mac_key = msg + GetOffset(message, mac_key);
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
} else {
LOGV("ContentKeySession::LoadKeys: enc_mac_key not set");
}
std::vector<OEMCrypto_KeyObject> load_keys(keys.size());
std::vector<OEMCrypto_KeyObject_V13> load_keys(keys.size());
for (size_t i = 0; i < keys.size(); ++i) {
const CryptoKey* ki = &keys[i];
OEMCrypto_KeyObject* ko = &load_keys[i];
OEMCrypto_KeyObject_V13* ko = &load_keys[i];
ko->key_id = msg + GetOffset(message, ki->key_id());
ko->key_id_length = ki->key_id().length();
ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv());
@@ -144,6 +147,8 @@ OEMCryptoResult ContentKeySession::LoadKeys(
ko->key_control_iv = NULL;
ko->key_control = NULL;
}
ko->cipher_mode = ToOEMCryptoCipherMode(ki->cipher_mode());
// TODO(jfore): Is returning the cipher needed. If not drop this.
*cipher_mode = ki->cipher_mode();
}
@@ -162,7 +167,7 @@ OEMCryptoResult ContentKeySession::LoadKeys(
LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult sts;
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = ::OEMCrypto_LoadKeys_Back_Compat(
oec_session_id_, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst,
@@ -171,4 +176,4 @@ OEMCryptoResult ContentKeySession::LoadKeys(
return sts;
}
} // namespace wvcdm
} // namespace wvcdm

View File

@@ -41,6 +41,9 @@ const uint32_t kRsaSignatureLength = 256;
const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB
const size_t kEstimatedInitialUsageTableHeader = 40;
const size_t kOemCryptoApiVersionSupportsBigUsageTables = 13;
// Ability to switch cipher modes in SelectKey() was introduced in this
// OEMCrypto version
const size_t kOemCryptoApiVersionSupportsSwitchingCipherMode = 14;
// Constants and utility objects relating to OEM Certificates
const int kExtensionOidSize = 64;
@@ -126,6 +129,11 @@ OEMCrypto_LicenseType OEMCryptoLicenseType(CdmLicenseKeyType cdm_license_type) {
: OEMCrypto_EntitlementLicense;
}
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode) {
return cipher_mode == kCipherModeCtr
? OEMCrypto_CipherMode_CTR : OEMCrypto_CipherMode_CBC;
}
CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
: metrics_(metrics),
system_id_(-1),
@@ -137,7 +145,8 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
usage_support_type_(kUnknownUsageSupport),
usage_table_header_(NULL),
request_id_base_(0),
cipher_mode_(kCipherModeCtr) {
cipher_mode_(kCipherModeCtr),
api_version_(0) {
assert(metrics);
Init();
life_span_.Start();
@@ -664,6 +673,11 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
metrics_->oemcrypto_get_random_.Increment(random_sts);
++request_id_index_;
if (!GetApiVersion(&api_version_)) {
LOGE("CryptoSession::Open: GetApiVersion failed");
return USAGE_SUPPORT_GET_API_FAILED;
}
CdmUsageSupportType usage_support_type;
CdmResponseType result = GetUsageSupportType(&usage_support_type);
if (result == NO_ERROR) {
@@ -1071,8 +1085,10 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
sts = CopyBufferInChunks(params, buffer_descriptor);
}
}
if (params.is_encrypted && params.cipher_mode != cipher_mode_) {
return INCORRECT_CRYPTO_MODE;
if (api_version_ < kOemCryptoApiVersionSupportsSwitchingCipherMode) {
if (params.is_encrypted && params.cipher_mode != cipher_mode_) {
return INCORRECT_CRYPTO_MODE;
}
}
if (params.is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
OEMCrypto_CENCEncryptPatternDesc pattern_descriptor;
@@ -1928,14 +1944,8 @@ CdmResponseType CryptoSession::GetUsageSupportType(
return NO_ERROR;
}
uint32_t api_version = 0;
if (!GetApiVersion(&api_version)) {
LOGE("GetUsageSupportType: GetApiVersion failed");
return USAGE_SUPPORT_GET_API_FAILED;
}
*usage_support_type = usage_support_type_ =
(api_version >= kOemCryptoApiVersionSupportsBigUsageTables)
(api_version_ >= kOemCryptoApiVersionSupportsBigUsageTables)
? kUsageEntrySupport
: kUsageTableSupport;
return NO_ERROR;

View File

@@ -955,6 +955,8 @@ bool CdmLicense::RestoreLicenseForRelease(
if (!crypto_session_->GenerateDerivedKeys(key_request_,
signed_response.session_key()))
return false;
} else {
return KEY_ADDED == HandleKeyResponse(license_response);
}
if (license.policy().has_renewal_server_url())

View File

@@ -100,7 +100,7 @@ OEMCryptoResult SubLicenseKeySession::SelectKey(const std::string& key_id,
it->second,
reinterpret_cast<const uint8_t*>(keys_[i].key_id().data()),
keys_[i].key_id().size(),
static_cast<OEMCryptoCipherMode>(cipher_mode)),
ToOEMCryptoCipherMode(cipher_mode)),
metrics_, oemcrypto_select_key_, status);
if (OEMCrypto_SUCCESS != status) {
return status;
@@ -184,7 +184,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
}
for (size_t i = 0; i < keys.size(); i++) {
OEMCrypto_KeyObject key_object;
OEMCrypto_KeyObject_V13 key_object;
const CryptoKey& key_data = keys[i];
key_object.key_id = msg + GetOffset(message, key_data.key_id());
key_object.key_id_length = key_data.key_id().length();
@@ -201,6 +201,8 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
key_object.key_control_iv = NULL;
key_object.key_control = NULL;
}
key_object.cipher_mode = ToOEMCryptoCipherMode(key_data.cipher_mode());
// TODO(jfore): Does returning the cipher mode serve any purpose?
// If not drop.
*cipher_mode = key_data.cipher_mode();
@@ -215,7 +217,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
OEMCryptoResult sts;
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = OEMCrypto_LoadKeys_Back_Compat(
oec_session_id->second, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()),
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
@@ -230,7 +232,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
oec_session_id->second,
reinterpret_cast<const uint8_t*>(key_data.key_id().data()),
key_data.key_id().size(),
static_cast<OEMCryptoCipherMode>(key_data.cipher_mode())),
ToOEMCryptoCipherMode(key_data.cipher_mode())),
metrics_, oemcrypto_select_key_, sts);
if (sts != OEMCrypto_SUCCESS) {
@@ -312,7 +314,7 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
return sts;
}
OEMCrypto_KeyObject key_object;
OEMCrypto_KeyObject_V13 key_object;
key_object.key_id = msg + GetOffset(message, keys_[key_index].key_id());
key_object.key_id_length = keys_[key_index].key_id().length();
key_object.key_data_iv =
@@ -325,9 +327,11 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
key_object.key_control =
msg + GetOffset(message, keys_[key_index].key_control());
}
key_object.cipher_mode =
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode());
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = OEMCrypto_LoadKeys_Back_Compat(
it->second, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
@@ -342,7 +346,7 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
it->second,
reinterpret_cast<const uint8_t*>(keys_[key_index].key_id().data()),
keys_[key_index].key_id().size(),
static_cast<OEMCryptoCipherMode>(keys_[key_index].cipher_mode())),
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode())),
metrics_, oemcrypto_select_key_, sts);
return sts;