Allow Apps to Voluntarily Downgrade to L3 Crypto

This merges the following changes from the Widevine CDM repository:

564f4cc  Add CdmClientPropertySet to CDM
  Adds an interface to the CDM that allows it to query its client for
  certain properties.  In this case, this includes the ability to
  specify what security level is desired, as well as support for
  service ceritifcate privacy mode.

9cfbd3e  Force Level 3 fallback
  Adds support for voluntarily invoking L3 crypto to the OEMCrypto
  wrapper.

95d12c1  Add pointer to CdmClientPropertySet class to OpenSession.
  Adds support for storing the property set on a session-by-session
  basis and choosing the appropriate crypto level.

17de442  Add Settable Properties for Clank to Android
  Adds support for setting the aforementioned properties to the
  DrmEngine

bbe704d  Fixes to force fallback to level three security
  Corrections to invoke provisioning, OEMCrypto API with configured
  security level rather than the default. Unit tests were also revised.

Note that some parts of this are also support for the ability to use
a service certificate-based privacy mode. The remaining code for
supporting this mode is still forthcoming.

Bug: 10109249
Change-Id: I2755e4dea1de3e8a56cff237360298f7b7f1bddc
This commit is contained in:
Rahul Frias
2013-08-15 10:59:42 -07:00
parent 0fa3e16999
commit f6c2a60485
45 changed files with 2359 additions and 906 deletions

View File

@@ -10,8 +10,6 @@
#include "crypto_key.h"
#include "log.h"
// TODO(gmorgan,jtinker): decide if OEMCryptoCENC is needed here.
#include "OEMCryptoCENC.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -37,7 +35,7 @@ int CryptoSession::session_count_ = 0;
CryptoSession::CryptoSession()
: open_(false),
is_destination_buffer_type_valid_(false),
security_level_(kSecurityLevelUninitialized) {
requested_security_level_(kLevelDefault) {
Init();
}
@@ -79,7 +77,7 @@ bool CryptoSession::ValidateKeybox() {
if (!initialized_) {
return false;
}
OEMCryptoResult result = OEMCrypto_IsKeyboxValid();
OEMCryptoResult result = OEMCrypto_IsKeyboxValid(requested_security_level_);
return (OEMCrypto_SUCCESS == result);
}
@@ -95,7 +93,8 @@ bool CryptoSession::GetToken(std::string* token) {
if (!initialized_) {
return false;
}
OEMCryptoResult sts = OEMCrypto_GetKeyData(buf, &bufSize);
OEMCryptoResult sts =
OEMCrypto_GetKeyData(buf, &bufSize, requested_security_level_);
if (OEMCrypto_SUCCESS != sts) {
return false;
}
@@ -110,16 +109,8 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel() {
return kSecurityLevelUninitialized;
}
switch (security_level_) {
case kSecurityLevelL1:
case kSecurityLevelL2:
case kSecurityLevelL3:
return security_level_;
default:
break;
}
std::string security_level = OEMCrypto_SecurityLevel();
std::string security_level =
OEMCrypto_SecurityLevel(requested_security_level_);
if ((security_level.size() != 2) || (security_level.at(0) != 'L')) {
return kSecurityLevelUnknown;
@@ -127,20 +118,16 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel() {
switch (security_level.at(1)) {
case '1':
security_level_ = kSecurityLevelL1;
break;
return kSecurityLevelL1;
case '2':
security_level_ = kSecurityLevelL2;
break;
return kSecurityLevelL2;
case '3':
security_level_ = kSecurityLevelL3;
break;
return kSecurityLevelL3;
default:
security_level_ = kSecurityLevelUnknown;
break;
return kSecurityLevelUnknown;
}
return security_level_;
return kSecurityLevelUnknown;
}
bool CryptoSession::GetDeviceUniqueId(std::string* device_id) {
@@ -159,7 +146,8 @@ bool CryptoSession::GetDeviceUniqueId(std::string* device_id) {
if (!initialized_) {
return false;
}
OEMCryptoResult sts = OEMCrypto_GetDeviceID(&id[0], &id_length);
OEMCryptoResult sts =
OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_);
if (OEMCrypto_SUCCESS != sts) {
return false;
@@ -183,7 +171,8 @@ bool CryptoSession::GetSystemId(uint32_t* system_id) {
if (!initialized_) {
return false;
}
OEMCryptoResult sts = OEMCrypto_GetKeyData(buf, &buf_size);
OEMCryptoResult sts =
OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_);
if (OEMCrypto_SUCCESS != sts) {
return false;
@@ -211,7 +200,8 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
if (!initialized_) {
return false;
}
OEMCryptoResult sts = OEMCrypto_GetKeyData(buf, &buf_size);
OEMCryptoResult sts =
OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_);
if (OEMCrypto_SUCCESS != sts) {
return false;
@@ -221,14 +211,15 @@ bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
return true;
}
CdmResponseType CryptoSession::Open() {
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
LOGV("CryptoSession::Open: Lock");
AutoLock auto_lock(crypto_lock_);
if (!initialized_) return false;
if (open_) return true;
if (!initialized_) return UNKNOWN_ERROR;
if (open_) return NO_ERROR;
OEMCrypto_SESSION sid;
OEMCryptoResult sts = OEMCrypto_OpenSession(&sid);
requested_security_level_ = requested_security_level;
OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level);
if (OEMCrypto_SUCCESS == sts) {
oec_session_id_ = static_cast<CryptoSessionId>(sid);
LOGV("OpenSession: id= %ld", (uint32_t)oec_session_id_);
@@ -680,7 +671,11 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message,
return true;
}
bool CryptoSession::GetRandom(uint8_t* random_data, size_t data_length) {
bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) {
if (random_data == NULL) {
LOGE("CryptoSession::GetRandom: random data destination not provided");
return false;
}
OEMCryptoResult sts = OEMCrypto_GetRandom(random_data, data_length);
if (sts != OEMCrypto_SUCCESS) {