Merge "Add cipher mode and pattern encryption support"

This commit is contained in:
Rahul Frias
2016-01-15 19:17:52 +00:00
committed by Android (Google) Code Review
6 changed files with 42 additions and 2 deletions

View File

@@ -17,6 +17,7 @@ class CryptoKey {
const std::string& key_data_iv() const { return key_data_iv_; }
const std::string& key_control() const { return key_control_; }
const std::string& key_control_iv() const { return key_control_iv_; }
CdmCipherMode cipher_mode() const { return cipher_mode_; }
void set_key_id(const std::string& key_id) { key_id_ = key_id; }
void set_key_data(const std::string& key_data) { key_data_ = key_data; }
void set_key_data_iv(const std::string& iv) { key_data_iv_ = iv; }
@@ -24,6 +25,9 @@ class CryptoKey {
void set_key_control_iv(const std::string& ctl_iv) {
key_control_iv_ = ctl_iv;
}
void set_cipher_mode(CdmCipherMode cipher_mode) {
cipher_mode_ = cipher_mode;
}
bool HasKeyControl() const { return key_control_.size() >= 16; }
@@ -33,6 +37,7 @@ class CryptoKey {
std::string key_data_;
std::string key_control_;
std::string key_control_iv_;
CdmCipherMode cipher_mode_;
};
} // namespace wvcdm

View File

@@ -271,6 +271,26 @@ struct CdmHlsData {
std::string uri;
};
enum CdmCipherMode {
kCipherModeCtr,
kCipherModeCbc,
};
// For schemes that do not use pattern encryption (cenc and cbc1), encrypt
// and skip should be set to 0. For those that do (cens and cbcs), it is
// recommended that encrypt+skip bytes sum to 10 and for cbcs that a 1:9
// encrypt:skip ratio be used. See ISO/IEC DIS 23001-7, section 10.4.2 for
// more information.
struct CdmCencPatternEncryptionDescriptor {
size_t encrypt_blocks; // number of 16 byte blocks to decrypt
size_t skip_blocks; // number of 16 byte blocks to leave in clear
size_t offset_blocks; // offset into the pattern for this call, in blocks
CdmCencPatternEncryptionDescriptor()
: encrypt_blocks(0),
skip_blocks(0),
offset_blocks(0) {}
};
struct CdmDecryptionParameters {
bool is_encrypted;
bool is_secure;
@@ -284,6 +304,7 @@ struct CdmDecryptionParameters {
size_t decrypt_buffer_offset;
uint8_t subsample_flags;
bool is_video;
CdmCencPatternEncryptionDescriptor pattern_descriptor;
CdmDecryptionParameters()
: is_encrypted(true),
is_secure(true),

View File

@@ -412,6 +412,9 @@ CdmResponseType CryptoSession::LoadKeys(
ko->key_control_iv = NULL;
ko->key_control = NULL;
}
ko->cipher_mode = ki->cipher_mode() == kCipherModeCbc
? OEMCrypto_CipherMode_CBC
: OEMCrypto_CipherMode_CTR;
}
uint8_t* pst = NULL;
if (!provider_session_token.empty()) {
@@ -672,6 +675,10 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
&buffer_descriptor, params.subsample_flags);
}
if (params.is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
OEMCrypto_CENCEncryptPatternDesc pattern_descriptor;
pattern_descriptor.encrypt = params.pattern_descriptor.encrypt_blocks;
pattern_descriptor.skip = params.pattern_descriptor.skip_blocks;
pattern_descriptor.offset = params.pattern_descriptor.offset_blocks;
AutoLock auto_lock(crypto_lock_);
// Check if key needs to be selected
if (params.is_encrypted) {
@@ -683,11 +690,10 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
}
}
}
// TODO(rfrias): add encrypt pattern parameter.
sts = OEMCrypto_DecryptCENC(
oec_session_id_, params.encrypt_buffer, params.encrypt_length,
params.is_encrypted, &(*params.iv).front(), params.block_offset,
&buffer_descriptor, NULL, params.subsample_flags);
&buffer_descriptor, &pattern_descriptor, params.subsample_flags);
}
switch (sts) {

View File

@@ -106,6 +106,9 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
key.set_key_control(license.key(i).key_control().key_control_block());
key.set_key_control_iv(license.key(i).key_control().iv());
}
// TODO(rfrias): Set cipher mode when the license protocol provides
// it (b/26190665). Set to default for now.
key.set_cipher_mode(kCipherModeCtr);
key_array.push_back(key);
break;
case License_KeyContainer::KEY_CONTROL:

View File

@@ -25,6 +25,7 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
static bool IsSupported(const std::string& init_data_type);
static bool IsCenc(const std::string& init_data_type);
static bool IsWebm(const std::string& init_data_type);
static bool IsHls(const std::string& init_data_type);
// Session related methods
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,

View File

@@ -38,6 +38,10 @@ bool WvContentDecryptionModule::IsWebm(const std::string& init_data_type) {
return InitializationData(init_data_type).is_webm();
}
bool WvContentDecryptionModule::IsHls(const std::string& init_data_type) {
return InitializationData(init_data_type).is_hls();
}
CdmResponseType WvContentDecryptionModule::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
const std::string& origin, WvCdmEventListener* event_listener,