Widevine CENC drm engine update: enable decryption
This import syncs to the widevine git repostiory change commit ab3e1e43642cf36900f55169597a33f222709fdb Change-Id: I3a6f1e2969e5fe7ed1ca12f90b0eb0a3b7899835
This commit is contained in:
@@ -35,10 +35,16 @@ namespace wvcdm {
|
||||
|
||||
// CryptoSession methods
|
||||
|
||||
CryptoSession::CryptoSession() : valid_(false), open_(false) {}
|
||||
CryptoSession::CryptoSession() :
|
||||
valid_(false),
|
||||
open_(false),
|
||||
is_destination_buffer_type_valid_(false) {}
|
||||
|
||||
CryptoSession::CryptoSession(const std::string& sname) : valid_(true),
|
||||
open_(false), cdm_session_id_(sname) {}
|
||||
CryptoSession::CryptoSession(const std::string& sname) :
|
||||
valid_(true),
|
||||
open_(false),
|
||||
cdm_session_id_(sname),
|
||||
is_destination_buffer_type_valid_(false) {}
|
||||
|
||||
CryptoSession::~CryptoSession() {
|
||||
if (open_) {
|
||||
@@ -222,7 +228,7 @@ bool CryptoSession::LoadKeys(const std::string& message,
|
||||
enc_mac_key = msg + GetOffset(message, mac_key);
|
||||
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
|
||||
}
|
||||
OEMCrypto_KeyObject load_key_array[num_keys];
|
||||
std::vector<OEMCrypto_KeyObject> load_key_array(num_keys);
|
||||
for (int i=0; i<num_keys; ++i) {
|
||||
const CryptoKey* ki = &key_array[i];
|
||||
OEMCrypto_KeyObject* ko = &load_key_array[i];
|
||||
@@ -246,7 +252,7 @@ bool CryptoSession::LoadKeys(const std::string& message,
|
||||
oec_session_id_, msg, message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(), enc_mac_key_iv, enc_mac_key,
|
||||
num_keys, load_key_array));
|
||||
num_keys, &load_key_array[0]));
|
||||
}
|
||||
|
||||
bool CryptoSession::RefreshKeys(const std::string& message,
|
||||
@@ -258,7 +264,7 @@ bool CryptoSession::RefreshKeys(const std::string& message,
|
||||
AutoLock auto_lock(crypto_engine->crypto_lock_);
|
||||
|
||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||
OEMCrypto_KeyRefreshObject load_key_array[num_keys];
|
||||
std::vector<OEMCrypto_KeyRefreshObject> load_key_array(num_keys);
|
||||
for (int i=0; i<num_keys; ++i) {
|
||||
const CryptoKey* ki = &key_array[i];
|
||||
OEMCrypto_KeyRefreshObject* ko = &load_key_array[i];
|
||||
@@ -285,7 +291,7 @@ bool CryptoSession::RefreshKeys(const std::string& message,
|
||||
oec_session_id_, msg, message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(),
|
||||
num_keys, load_key_array));
|
||||
num_keys, &load_key_array[0]));
|
||||
}
|
||||
|
||||
bool CryptoSession::SelectKey(const std::string& key_id) {
|
||||
@@ -304,55 +310,49 @@ bool CryptoSession::SelectKey(const std::string& key_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CryptoSession::Decrypt(const InputDescriptor input,
|
||||
const OutputDescriptor output) {
|
||||
LOGV("CryptoSession::Decrypt: Lock");
|
||||
CryptoEngine* crypto_engine = CryptoEngine::GetInstance();
|
||||
AutoLock auto_lock(crypto_engine->crypto_lock_);
|
||||
// TODO(gmorgan): handle inputs and outputs to decrypt call
|
||||
const uint8_t* data_addr = NULL;
|
||||
uint32_t data_length = 0;
|
||||
bool is_encrypted = false;
|
||||
uint8_t* iv = NULL;
|
||||
uint32_t offset = 0;
|
||||
const OEMCrypto_DestBufferDesc* out_buffer = NULL;
|
||||
OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, data_addr,
|
||||
data_length, is_encrypted, iv,
|
||||
offset, out_buffer);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return false;
|
||||
CdmResponseType CryptoSession::Decrypt(bool is_encrypted,
|
||||
const uint8_t* encrypt_buffer,
|
||||
size_t encrypt_length,
|
||||
const std::vector<uint8_t>& iv,
|
||||
size_t block_offset,
|
||||
void* decrypt_buffer,
|
||||
bool is_video) {
|
||||
if (!is_destination_buffer_type_valid_) {
|
||||
if (!SetDestinationBufferType())
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO(jfore): Define InputDescriptor and OutputDecriptor and
|
||||
// remove this method. For now this is a level 3 decrypt.
|
||||
bool CryptoSession::Decrypt(const uint8_t* encrypted_buffer,
|
||||
size_t encrypted_size,
|
||||
size_t block_offset,
|
||||
const std::vector<uint8_t>& iv,
|
||||
uint8_t* decrypted_buffer) {
|
||||
LOGV("CryptoSession::Decrypt: Lock");
|
||||
CryptoEngine* crypto_engine = CryptoEngine::GetInstance();
|
||||
AutoLock auto_lock(crypto_engine->crypto_lock_);
|
||||
// TODO(gmorgan): handle inputs and outputs to decrypt call
|
||||
const uint8_t* data_addr = NULL;
|
||||
uint32_t data_length = 0;
|
||||
bool is_encrypted = false;
|
||||
uint32_t offset = block_offset;
|
||||
OEMCrypto_DestBufferDesc out_buffer;
|
||||
OEMCrypto_DestBufferDesc buffer_descriptor;
|
||||
buffer_descriptor.type = destination_buffer_type_;
|
||||
|
||||
out_buffer.type = OEMCrypto_BufferType_Clear;
|
||||
out_buffer.buffer.clear.address = decrypted_buffer;
|
||||
out_buffer.buffer.clear.max_length = encrypted_size;
|
||||
if (!is_encrypted)
|
||||
buffer_descriptor.type = OEMCrypto_BufferType_Clear;
|
||||
|
||||
OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, encrypted_buffer,
|
||||
encrypted_size, true, &iv[0],
|
||||
offset, &out_buffer);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return false;
|
||||
switch (buffer_descriptor.type) {
|
||||
case OEMCrypto_BufferType_Clear:
|
||||
buffer_descriptor.buffer.clear.address =
|
||||
static_cast<uint8_t*>(decrypt_buffer);
|
||||
buffer_descriptor.buffer.clear.max_length = encrypt_length;
|
||||
break;
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
buffer_descriptor.buffer.secure.handle = decrypt_buffer;
|
||||
buffer_descriptor.buffer.secure.max_length = encrypt_length;
|
||||
break;
|
||||
case OEMCrypto_BufferType_Direct:
|
||||
buffer_descriptor.type = OEMCrypto_BufferType_Direct;
|
||||
buffer_descriptor.buffer.direct.is_video = is_video;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, encrypt_buffer,
|
||||
encrypt_length, is_encrypted,
|
||||
&iv[0], block_offset,
|
||||
&buffer_descriptor);
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool CryptoSession::GenerateNonce(uint32_t* nonce) {
|
||||
@@ -366,4 +366,33 @@ bool CryptoSession::GenerateNonce(uint32_t* nonce) {
|
||||
AutoLock auto_lock(crypto_engine->crypto_lock_);
|
||||
return(OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(oec_session_id_, nonce));
|
||||
}
|
||||
|
||||
bool CryptoSession::SetDestinationBufferType() {
|
||||
CryptoEngine* crypto_engine = CryptoEngine::GetInstance();
|
||||
|
||||
if (!crypto_engine->properties_valid())
|
||||
return false;
|
||||
|
||||
if (crypto_engine->oem_crypto_use_secure_buffers()) {
|
||||
if (crypto_engine->GetSecurityLevel() == CryptoEngine::kSecurityLevelL1) {
|
||||
destination_buffer_type_ = OEMCrypto_BufferType_Secure;
|
||||
}
|
||||
else {
|
||||
destination_buffer_type_ = OEMCrypto_BufferType_Clear;
|
||||
}
|
||||
}
|
||||
else if (crypto_engine->oem_crypto_use_fifo()) {
|
||||
destination_buffer_type_ = OEMCrypto_BufferType_Direct;
|
||||
}
|
||||
else if (crypto_engine->oem_crypto_use_userspace_buffers()) {
|
||||
destination_buffer_type_ = OEMCrypto_BufferType_Clear;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
is_destination_buffer_type_valid_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace wvcdm
|
||||
|
||||
Reference in New Issue
Block a user