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

@@ -35,7 +35,8 @@
// srm_load_version: If this is set, then it will be used as the
// new srm version after loading an SRM -- ignoring the contents of the SRM.
// srm_blacklisted_device_attached: If set to "1", then a
// oemcrypto will act as if a blacklisted device is attached.
// oemcrypto will act as if a blacklisted device is attached -- i.e.
// playback will be restricted to the local display only.
// security_patch_level: This is the value returned by
// OEMCrypto_Security_Patch_Level. If the key control block requires a
// higher level, then OEMCrypto_LoadKeys will fail.
@@ -336,6 +337,91 @@ class AndroidModifiableCryptoEngine : public CryptoEngine {
return max; // If 0, no restriction. If something else, use that restriction.
}
bool srm_update_supported() {
int supported = GetOption("srm_update_supported", 0);
LOGI("OEMCrypto mock %s supporting SRM update.",
supported ? "is" : "is not");
return supported != 0;
}
OEMCryptoResult current_srm_version(uint16_t *version) {
if (srm_loaded_) {
*version = srm_version_;
return OEMCrypto_SUCCESS;
}
int value = GetOption("srm_initial_version", -1);
if (value > 0) {
*version = srm_version_;
return OEMCrypto_SUCCESS;
} else {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
}
OEMCryptoResult load_srm(const uint8_t *buffer, size_t buffer_length) {
if (!srm_update_supported()) {
LOGE("OEMCrypto mock update not supported, but load_srm called.");
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
int result = GetOption("srm_load_fail", 0);
if (result > 0) {
LOGE("OEMCrypto mock load_srm returning error %d.", result);
return static_cast<OEMCryptoResult>(result);
}
int new_version = GetOption("srm_load_version", -1);
if (new_version >= 0) {
srm_version_ = new_version;
LOGI("OEMCrypto mock told to change SRM version to %d.", srm_version_);
srm_loaded_ = true;
return OEMCrypto_SUCCESS;
}
if (buffer_length < 4) {
LOGE("OEMCrypto mock bad buffer size: %d.", buffer_length);
return OEMCrypto_ERROR_SHORT_BUFFER;
}
uint8_t srm_id = buffer[0];
uint8_t first_nibble = srm_id >> 4;
uint8_t second_nibble = srm_id & 0x0F;
uint8_t reserved = buffer[1];
uint16_t version = htons(*reinterpret_cast<const uint16_t *>(&buffer[2]));
if (reserved)
LOGE("OEMCrypto mock. SRM's second byte nonzero: %02X.", reserved);
if (first_nibble == 8 && second_nibble == 0) {
LOGI("OEMCrypto mock loading HDCP1 SRM. version = %d.", version);
} else if (first_nibble == 9 && second_nibble == 1) {
LOGI("OEMCrypto mock loading HDCP2 SRM. version = %d.", version);
} else {
LOGE("OEMCrypto mock bad buffer start: %02X%02X%02X%02X...", buffer[0],
buffer[1], buffer[2], buffer[3]);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Note: we ignore the signature. Use system property srm_load_fail to
// simulate a bad signature.
srm_loaded_ = true;
return OEMCrypto_SUCCESS;
}
OEMCryptoResult remove_srm() {
if (!srm_update_supported()) {
LOGE("OEMCrypto mock update not supported, bug load_srm called.");
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
srm_version_ = 0;
srm_loaded_ = false;
return OEMCrypto_SUCCESS;
}
bool srm_blacklisted_device_attached() {
static int blacklisted = 0;
int new_value = GetOption("srm_blacklisted_device_attached", 0);
if (new_value != blacklisted) {
LOGI("SRM blacklisted device changed from %d to %d", blacklisted,
new_value);
blacklisted = new_value;
}
return blacklisted > 0;
}
virtual void adjust_destination(OEMCrypto_DestBufferDesc *out_description,
size_t data_length, uint8_t subsample_flags) {
if (out_description->type != OEMCrypto_BufferType_Secure) return;