Merges to android Pi release (part 7)

These are a set of CLs merged from the wv cdm repo to the android repo.

* Resolve intermittent decrypt error.

  Author: Jeff Fore <jfore@google.com>

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

  The CdmSession's closed state was not properly
  initialized resulting in intermittent
  SESSION_NOT_FOUND_FOR_DECRYPT errors.

  In CdmEngine::Decrypt the session is looked up by
  the key id. A list of open sessions is acquired
  by calling CdmSessionMap::GetSessionList and each
  session in the list is queried to see if it has
  the key.

  In building the list in CdmSessionMap::GetSessionList,
  sessions are only added to the query list *if* the session
  is not closed.

  The closed status was not initialized and during testing
  the query list would not contain the session causing
  CdmEngine::Decrypt to return SESSION_NOT_FOUND_FOR_DECRYPT
  resulting in the ce cdm api returning widevine::Cdm::kNoKey.

* No support for pre- C++11 compilation.

  Author: Gene Morgan <gmorgan@google.com>

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

* Handle unaligned nonce pointer in RewrapDeviceRSAKey calls.

  Author: Gene Morgan <gmorgan@google.com>

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

  The pointer points into a message and it may not be aligned.
  Always copy the nonce into aligned memory before checking it.

  BUG: 38140370

  Add note to CHANGELOG for this.

* Compiler strictness: more checks and code cleanup.

  Author: Gene Morgan <gmorgan@google.com>

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

  Use the switches proposed in b/38033653 (as much as possible - some
  conflicts with protobufs and gtest prevent fully accepting them).

  Switch to clang for x32 build; ensure that both x86-64 and x86-32 builds
  compile and link cleanly.

  BUG: 38032429
  BUG: 38033653

  This partially resolves b/38458986

* Android build fixes

  Author: Rahul Frias <rfrias@google.com>

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

  These corrections address compile warnings and errors for android
  and unit tests.

* Embedded License: Add sub license key sessions.

  Author: Jeff Fore <jfore@google.com>

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

  NOTE: this adds the AddSubSession() method, but it is not yet being
  used. Use and proper cleanup is in an upcoming CL.

* Embedded license: Add track label field.

  Author: Jeff Fore <jfore@google.com>

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

  A new track label field (a string) is added to the key container and the
  sub session data objects.

  This field will be used in handling sub license requests.

* Embedded license: extract keys from init_data.

  Author: Jeff Fore <jfore@google.com>

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

* Embedded license: add protobuf messages.

  Author: Jeff Fore <jfore@google.com>

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

  also sync the widevine header definition with recent naming changes.

* Improve handling of provisioning response errors.

  Author: Gene Morgan <gmorgan@google.com>

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

  Separate out the case of no response and the case
  where the message is believed to be a JSON+base64
  message but it doesn't parse properly.

BUG: 71650075
Test: Not currently passing. Will be addressed in a subsequent
  commit in the chain.

Change-Id: I3c86f1c54980b071aec7461ac58541836551f896
This commit is contained in:
Rahul Frias
2018-01-09 23:36:42 -08:00
parent 00da44bb68
commit 80659961ac
38 changed files with 1249 additions and 360 deletions

View File

@@ -502,24 +502,25 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
CdmSecurityLevel security_level = GetSecurityLevel();
if (security_level == kSecurityLevelL1 ||
security_level == kSecurityLevelL3) {
UsageTableHeader* header = security_level == kSecurityLevelL1 ?
usage_table_header_l1_ : usage_table_header_l3_;
if (header == NULL) {
header = new UsageTableHeader();
UsageTableHeader** header = security_level == kSecurityLevelL1 ?
&usage_table_header_l1_ : &usage_table_header_l3_;
if (*header == NULL) {
*header = new UsageTableHeader();
// Ignore errors since we do not know when a session is opened,
// if it is intended to be used for offline/usage session related
// or otherwise.
if (!header->Init(security_level, this)) {
delete header;
crypto_lock_.Release();
bool is_usage_table_header_inited =
(*header)->Init(security_level, this);
crypto_lock_.Acquire();
if (!is_usage_table_header_inited) {
delete *header;
*header = NULL;
usage_table_header_ = NULL;
return NO_ERROR;
}
if (security_level == kSecurityLevelL1)
usage_table_header_l1_ = header;
else
usage_table_header_l3_ = header;
}
usage_table_header_ = header;
usage_table_header_ = *header;
}
}
}
@@ -2258,6 +2259,55 @@ CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) {
return NO_ERROR;
}
bool CryptoSession::CreateOldUsageEntry(
uint64_t time_since_license_received,
uint64_t time_since_first_decrypt,
uint64_t time_since_last_decrypt,
UsageDurationStatus usage_duration_status,
const std::string& server_mac_key,
const std::string& client_mac_key,
const std::string& provider_session_token) {
LOGV("CreateOldUsageEntry: Lock");
AutoLock auto_lock(crypto_lock_);
if (server_mac_key.size() < MAC_KEY_SIZE ||
client_mac_key.size() < MAC_KEY_SIZE) {
LOGE("CreateOldUsageEntry: Invalid mac key size: server mac key size %d, "
"client mac key size: %d", server_mac_key.size(),
client_mac_key.size());
return false;
}
OEMCrypto_Usage_Entry_Status status;
switch (usage_duration_status) {
case kUsageDurationsInvalid: status = kUnused; break;
case kUsageDurationPlaybackNotBegun: status = kInactiveUnused; break;
case kUsageDurationsValid: status = kActive; break;
default:
LOGE("CreateOldUsageEntry: Unrecognized usage entry status: %d", status);
status = kUnused;
return false;
}
OEMCryptoResult result =
OEMCrypto_CreateOldUsageEntry(
requested_security_level_, time_since_license_received,
time_since_first_decrypt, time_since_last_decrypt, status,
reinterpret_cast<uint8_t*>(
const_cast<char*>(server_mac_key.data())),
reinterpret_cast<uint8_t*>(
const_cast<char*>(client_mac_key.data())),
reinterpret_cast<const uint8_t*>(provider_session_token.data()),
provider_session_token.size());
if (result != OEMCrypto_SUCCESS) {
LOGE("CreateOldUsageEntry: OEMCrypto_CreateOldUsageEntry error: %d",
result);
return false;
}
return true;
}
CdmResponseType CryptoSession::CopyOldUsageEntry(
const std::string& provider_session_token) {
LOGV("CopyOldUsageEntry: id=%ld", (uint32_t)oec_session_id_);
@@ -2275,6 +2325,36 @@ CdmResponseType CryptoSession::CopyOldUsageEntry(
return NO_ERROR;
}
CdmResponseType CryptoSession::AddSubSession(
const std::string& sub_session_key_id) {
size_t exists = sub_license_oec_sessions_.count(sub_session_key_id);
if (exists > 0) {
// TODO(jfore): Should this be an error if the key exists? If so add a new
// error. If not, perhaps this should just print info message.
LOGE("AddSubSession: SubSession already exists for id: %s",
sub_session_key_id.c_str());
return UNKNOWN_ERROR;
}
OEMCryptoResult sts;
CryptoSessionId sid;
sts = OEMCrypto_OpenSession(&sid,requested_security_level_);
if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d",
sts, session_count_, (int)initialized_);
return INSUFFICIENT_CRYPTO_RESOURCES;
} else if (OEMCrypto_SUCCESS != sts) {
LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d",
sts, session_count_, (int)initialized_);
return UNKNOWN_ERROR;
}
// TODO(jfore): Is there some session count metrics that should be add or
// update?
sub_license_oec_sessions_[sub_session_key_id] = sid;
return NO_ERROR;
}
OEMCrypto_Algorithm CryptoSession::GenericSigningAlgorithm(
CdmSigningAlgorithm algorithm) {
if (kSigningAlgorithmHmacSha256 == algorithm) {