OEMCrypto Mock SRM functionality

Merge from Widevine repo of http://go/wvgerrit/24730

This CL adds SRM functionality to the modable version of oemcrypto
mock.  This can be used for end-to-end testing.

b/28955873
b/37353534

Change-Id: I2c6f513495ccfd42f7a3d7a3449db6f810563c04
This commit is contained in:
Fred Gylys-Colwell
2017-04-14 13:51:57 -07:00
parent 5c768c896e
commit 426e53bbbf
9 changed files with 191 additions and 15 deletions

View File

@@ -391,7 +391,7 @@ OEMCryptoResult SessionContext::LoadKeys(
size_t signature_length, const uint8_t* enc_mac_key_iv,
const uint8_t* enc_mac_keys, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
size_t pst_length) {
size_t pst_length, const uint8_t* srm_requirement) {
// Validate message signature
if (!ValidateMessage(message, message_length, signature, signature_length)) {
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
@@ -399,6 +399,31 @@ OEMCryptoResult SessionContext::LoadKeys(
StartTimer();
if (srm_requirement) {
const std::string kSRMVerificationString = "HDCPDATA";
if (memcmp(srm_requirement, kSRMVerificationString.c_str(),
kSRMVerificationString.size())) {
LOGE("SRM Requirement Data has bad verification string: %8s",
srm_requirement);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
uint32_t minimum_version =
htonl(*reinterpret_cast<const uint32_t*>(srm_requirement + 8));
uint16_t current_version = 0;
if (OEMCrypto_SUCCESS == ce_->current_srm_version(&current_version) &&
current_version >= minimum_version) {
srm_requirements_status_ = ValidSRMVersion;
if (ce_->srm_blacklisted_device_attached()) {
LOGW("[LoadKeys: SRM blacklisted device attached]");
srm_requirements_status_ = InvalidSRMVersion;
}
} else {
LOGW("[LoadKeys: SRM Version too small %d, required: %d",
current_version, minimum_version);
srm_requirements_status_ = InvalidSRMVersion;
}
}
// If there are already keys installed in this session, then we can load
// a shared license.
bool second_license = (session_keys_.size() > 0);
@@ -557,6 +582,16 @@ OEMCryptoResult SessionContext::InstallKey(
return OEMCrypto_ERROR_MISSING_MASTER;
}
}
if (key_control_block.control_bits() & kControlSRMVersionRequired) {
if (srm_requirements_status_ == NoSRMVersion) {
LOGE("[LoadKeys: control bit says SRM version required]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (srm_requirements_status_ == InvalidSRMVersion) {
// If the SRM version is too small, treat this key as local display only.
key_control_block.RequireLocalDisplay();
}
}
Key key(content_key, key_control_block, ctr_mode);
session_keys_.Insert(key_id, key);
@@ -733,11 +768,15 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
}
}
if (!ce_->config_local_display_only()) {
// Only look at HDCP and Analog restrictions if the display is non-local.
// Only look at HDCP and Analog restrictions if the display can be
// non-local.
if (control.control_bits() & kControlHDCPRequired) {
uint8_t required_hdcp =
(control.control_bits() & kControlHDCPVersionMask) >>
kControlHDCPVersionShift;
if (ce_->srm_blacklisted_device_attached()) {
required_hdcp = HDCP_NO_DIGITAL_OUTPUT;
}
// For reference implementation, we pretend we can handle the current
// HDCP version.
if (required_hdcp > ce_->config_current_hdcp_capability() ||
@@ -745,10 +784,6 @@ OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
}
}
if (control.control_bits() & kControlSRMVersionRequired) {
LOGE("[%s(): control bit says SRM version required.", log_string.c_str());
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
}
}
if (!ce_->config_local_display_only() ||
buffer_type == OEMCrypto_BufferType_Clear) {