Improve support for decryption of full sample encrypted cbcs
1. Allow encryption pattern of 0:0, which is treated as 1:0; 2. Remove the special handling of pattern 1:0 in pattern cryptor which may not always be correct; 3. Allow senc/saio/saiz boxes to be absent. Change-Id: I372e61182ec577107e39cb601c3aed80616b036d
This commit is contained in:
parent
e7393fcc22
commit
4c6e5f4fa6
|
@ -23,11 +23,9 @@ AesPatternCryptor::AesPatternCryptor(uint8_t crypt_byte_block,
|
|||
skip_byte_block_(skip_byte_block),
|
||||
encryption_mode_(encryption_mode),
|
||||
cryptor_(std::move(cryptor)) {
|
||||
// |crypt_byte_block_| should never be 0. |skip_byte_block_| can be 0 to allow
|
||||
// a special pattern of 1:0, which is the pattern for the case of pattern
|
||||
// encryption when applied to non video tracks.
|
||||
DCHECK_NE(crypt_byte_block_, 0u);
|
||||
DCHECK(skip_byte_block_ != 0 || crypt_byte_block_ == 1);
|
||||
// Treat pattern 0:0 as 1:0.
|
||||
if (crypt_byte_block_ == 0 && skip_byte_block_ == 0)
|
||||
crypt_byte_block_ = 1;
|
||||
DCHECK(cryptor_);
|
||||
DCHECK(!cryptor_->use_constant_iv());
|
||||
}
|
||||
|
@ -51,17 +49,6 @@ bool AesPatternCryptor::CryptInternal(const uint8_t* text,
|
|||
}
|
||||
*crypt_text_size = text_size;
|
||||
|
||||
// Handle the special pattern 1:0.
|
||||
if (skip_byte_block_ == 0) {
|
||||
DCHECK_EQ(crypt_byte_block_, 1u);
|
||||
const size_t crypt_byte_size = text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
|
||||
if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
|
||||
return false;
|
||||
memcpy(crypt_text + crypt_byte_size, text + crypt_byte_size,
|
||||
text_size - crypt_byte_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
while (text_size > 0) {
|
||||
const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
|
||||
if (NeedEncrypt(text_size, crypt_byte_size)) {
|
||||
|
|
|
@ -72,7 +72,7 @@ class AesPatternCryptor : public AesCryptor {
|
|||
|
||||
bool NeedEncrypt(size_t input_size, size_t target_data_size);
|
||||
|
||||
const uint8_t crypt_byte_block_;
|
||||
uint8_t crypt_byte_block_;
|
||||
const uint8_t skip_byte_block_;
|
||||
const PatternEncryptionMode encryption_mode_;
|
||||
std::unique_ptr<AesCryptor> cryptor_;
|
||||
|
|
|
@ -219,35 +219,5 @@ TEST(SampleAesPatternCryptor, MoreThan16Bytes) {
|
|||
ASSERT_TRUE(pattern_cryptor.Crypt("0123456789abcdef012", &crypt_text));
|
||||
}
|
||||
|
||||
TEST(FullSampleSpecialPatternTest, Test) {
|
||||
MockAesCryptor* mock_cryptor = new MockAesCryptor();
|
||||
EXPECT_CALL(*mock_cryptor, CryptInternal(_, 96u, _, _))
|
||||
.WillOnce(Invoke([](const uint8_t* text, size_t text_size,
|
||||
uint8_t* crypt_text, size_t* crypt_text_size) {
|
||||
*crypt_text_size = text_size;
|
||||
for (size_t i = 0; i < text_size; ++i)
|
||||
*crypt_text++ = 'e';
|
||||
return true;
|
||||
}));
|
||||
|
||||
const uint8_t kFulLSampleCryptBlock = 1;
|
||||
const uint8_t kFullSampleSkipBlock = 0;
|
||||
AesPatternCryptor pattern_cryptor(
|
||||
kFulLSampleCryptBlock, kFullSampleSkipBlock,
|
||||
AesPatternCryptor::kSkipIfCryptByteBlockRemaining,
|
||||
AesPatternCryptor::kUseConstantIv,
|
||||
std::unique_ptr<MockAesCryptor>(mock_cryptor));
|
||||
|
||||
std::vector<uint8_t> iv(8, 'i');
|
||||
// SetIv will be called only once by AesPatternCryptor::SetIv.
|
||||
EXPECT_TRUE(pattern_cryptor.SetIv(iv));
|
||||
|
||||
std::string input_text(100, 'c');
|
||||
std::string crypt_text;
|
||||
// More than 16 bytes so mock's CryptInternal should be called.
|
||||
ASSERT_TRUE(pattern_cryptor.Crypt(input_text, &crypt_text));
|
||||
EXPECT_EQ(std::string(96, 'e') + std::string(4, 'c'), crypt_text);
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
} // namespace shaka
|
||||
|
|
|
@ -589,24 +589,30 @@ const TrackEncryption& TrackRunIterator::track_encryption() const {
|
|||
}
|
||||
|
||||
std::unique_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
|
||||
size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
|
||||
DCHECK_LT(sample_idx, run_itr_->sample_encryption_entries.size());
|
||||
const SampleEncryptionEntry& sample_encryption_entry =
|
||||
run_itr_->sample_encryption_entries[sample_idx];
|
||||
DCHECK(is_encrypted());
|
||||
DCHECK(!AuxInfoNeedsToBeCached());
|
||||
std::vector<uint8_t> iv;
|
||||
std::vector<SubsampleEntry> subsamples;
|
||||
|
||||
const size_t total_size_of_subsamples =
|
||||
sample_encryption_entry.GetTotalSizeOfSubsamples();
|
||||
if (total_size_of_subsamples != 0 &&
|
||||
total_size_of_subsamples != static_cast<size_t>(sample_size())) {
|
||||
LOG(ERROR) << "Incorrect CENC subsample size.";
|
||||
return std::unique_ptr<DecryptConfig>();
|
||||
size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
|
||||
if (sample_idx < run_itr_->sample_encryption_entries.size()) {
|
||||
const SampleEncryptionEntry& sample_encryption_entry =
|
||||
run_itr_->sample_encryption_entries[sample_idx];
|
||||
DCHECK(is_encrypted());
|
||||
DCHECK(!AuxInfoNeedsToBeCached());
|
||||
|
||||
const size_t total_size_of_subsamples =
|
||||
sample_encryption_entry.GetTotalSizeOfSubsamples();
|
||||
if (total_size_of_subsamples != 0 &&
|
||||
total_size_of_subsamples != static_cast<size_t>(sample_size())) {
|
||||
LOG(ERROR) << "Incorrect CENC subsample size.";
|
||||
return std::unique_ptr<DecryptConfig>();
|
||||
}
|
||||
|
||||
iv = sample_encryption_entry.initialization_vector;
|
||||
subsamples = sample_encryption_entry.subsamples;
|
||||
}
|
||||
|
||||
FourCC protection_scheme = is_audio() ? audio_description().sinf.type.type
|
||||
: video_description().sinf.type.type;
|
||||
std::vector<uint8_t> iv = sample_encryption_entry.initialization_vector;
|
||||
if (iv.empty()) {
|
||||
if (protection_scheme != FOURCC_cbcs) {
|
||||
LOG(WARNING)
|
||||
|
@ -619,8 +625,8 @@ std::unique_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
|
|||
}
|
||||
}
|
||||
return std::unique_ptr<DecryptConfig>(new DecryptConfig(
|
||||
track_encryption().default_kid, iv, sample_encryption_entry.subsamples,
|
||||
protection_scheme, track_encryption().default_crypt_byte_block,
|
||||
track_encryption().default_kid, iv, subsamples, protection_scheme,
|
||||
track_encryption().default_crypt_byte_block,
|
||||
track_encryption().default_skip_byte_block));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue