Fix pattern encryption when applying to patterns other than 1:9
We used to skip all the remaining bytes if the size is less than |crypt_byte_block| blocks. This interpretation is incorrect. We should only leave the last partial 16-byte block un-encrypted. Change-Id: I4f09600efa52e2fdf4d0b661dfc418dcb675f9f6
This commit is contained in:
parent
60df64705b
commit
86b10b6316
|
@ -51,14 +51,31 @@ bool AesPatternCryptor::CryptInternal(const uint8_t* text,
|
||||||
|
|
||||||
while (text_size > 0) {
|
while (text_size > 0) {
|
||||||
const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
|
const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
|
||||||
if (NeedEncrypt(text_size, crypt_byte_size)) {
|
|
||||||
if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
|
if (text_size <= crypt_byte_size) {
|
||||||
|
const bool need_encrypt =
|
||||||
|
encryption_mode_ == kSkipIfCryptByteBlockRemaining
|
||||||
|
? (text_size > crypt_byte_size)
|
||||||
|
: (text_size >= AES_BLOCK_SIZE);
|
||||||
|
if (need_encrypt) {
|
||||||
|
// The partial pattern SHALL be followed with the partial 16-byte block
|
||||||
|
// remains unencrypted.
|
||||||
|
const size_t aligned_crypt_byte_size =
|
||||||
|
text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
|
||||||
|
if (!cryptor_->Crypt(text, aligned_crypt_byte_size, crypt_text))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
text += aligned_crypt_byte_size;
|
||||||
// If there is not enough data, just keep it in clear.
|
text_size -= aligned_crypt_byte_size;
|
||||||
|
crypt_text += aligned_crypt_byte_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The remaining bytes are not encrypted.
|
||||||
memcpy(crypt_text, text, text_size);
|
memcpy(crypt_text, text, text_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
|
||||||
|
return false;
|
||||||
text += crypt_byte_size;
|
text += crypt_byte_size;
|
||||||
text_size -= crypt_byte_size;
|
text_size -= crypt_byte_size;
|
||||||
crypt_text += crypt_byte_size;
|
crypt_text += crypt_byte_size;
|
||||||
|
@ -77,12 +94,5 @@ void AesPatternCryptor::SetIvInternal() {
|
||||||
CHECK(cryptor_->SetIv(iv()));
|
CHECK(cryptor_->SetIv(iv()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesPatternCryptor::NeedEncrypt(size_t input_size,
|
|
||||||
size_t target_data_size) {
|
|
||||||
if (encryption_mode_ == kSkipIfCryptByteBlockRemaining)
|
|
||||||
return input_size > target_data_size;
|
|
||||||
return input_size >= target_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -19,18 +19,16 @@ class AesPatternCryptor : public AesCryptor {
|
||||||
/// Enumerator for controling encrytion/decryption mode for the last
|
/// Enumerator for controling encrytion/decryption mode for the last
|
||||||
/// encryption/decrytion block(s).
|
/// encryption/decrytion block(s).
|
||||||
enum PatternEncryptionMode {
|
enum PatternEncryptionMode {
|
||||||
/// Use kEncryptIfCryptByteBlockRemaining if the last blocks is exactly the
|
/// Use kEncryptIfCryptByteBlockRemaining to encrypt all the full 16-byte
|
||||||
/// same as the number of remaining bytes. IOW
|
/// blocks even if the remaining bytes are less than encryption_block_bytes.
|
||||||
/// if (remaining_bytes == encryption_block_bytes)
|
/// IOW:
|
||||||
/// encrypt(remaining_data)
|
/// if (remaining_bytes <= encryption_block_bytes)
|
||||||
|
/// encrypt(block_aligned_remaining_data)
|
||||||
kEncryptIfCryptByteBlockRemaining,
|
kEncryptIfCryptByteBlockRemaining,
|
||||||
/// Use kSkipIfCryptByteBlockRemaining to not encrypt/decrypt the last
|
/// Use kSkipIfCryptByteBlockRemaining to not encrypt/decrypt the remaining
|
||||||
/// clocks if it is exactly the same as the number of remaining bytes.
|
/// bytes if it is less than or equal to encryption_block_bytes.
|
||||||
/// if (remaining_bytes > encryption_block_bytes) {
|
/// if (remaining_bytes > encryption_block_bytes)
|
||||||
/// // Since this is the last blocks, this is effectively the same
|
|
||||||
/// // condition as remaining_bytes != encryption_block_bytes.
|
|
||||||
/// encrypt().
|
/// encrypt().
|
||||||
/// }
|
|
||||||
/// Use this mode for HLS SAMPLE-AES.
|
/// Use this mode for HLS SAMPLE-AES.
|
||||||
kSkipIfCryptByteBlockRemaining,
|
kSkipIfCryptByteBlockRemaining,
|
||||||
};
|
};
|
||||||
|
@ -70,8 +68,6 @@ class AesPatternCryptor : public AesCryptor {
|
||||||
size_t* crypt_text_size) override;
|
size_t* crypt_text_size) override;
|
||||||
void SetIvInternal() override;
|
void SetIvInternal() override;
|
||||||
|
|
||||||
bool NeedEncrypt(size_t input_size, size_t target_data_size);
|
|
||||||
|
|
||||||
uint8_t crypt_byte_block_;
|
uint8_t crypt_byte_block_;
|
||||||
const uint8_t skip_byte_block_;
|
const uint8_t skip_byte_block_;
|
||||||
const PatternEncryptionMode encryption_mode_;
|
const PatternEncryptionMode encryption_mode_;
|
||||||
|
|
|
@ -103,11 +103,15 @@ const PatternTestCase kPatternTestCases[] = {
|
||||||
{"", ""},
|
{"", ""},
|
||||||
// One partial block (not encrypted).
|
// One partial block (not encrypted).
|
||||||
{"010203", "010203"},
|
{"010203", "010203"},
|
||||||
// One block (not encrypted).
|
// One block (encrypted).
|
||||||
{"01020304050607080910111213141516", "01020304050607080910111213141516"},
|
{"01020304050607080910111213141516", "11121314151617181920212223242526"},
|
||||||
// One block + partial block (not encrypted).
|
// One block + partial block.
|
||||||
{"010203040506070809101112131415161718",
|
{// One block encrypted.
|
||||||
"010203040506070809101112131415161718"},
|
"01020304050607080910111213141516"
|
||||||
|
// Partial block unencrypted.
|
||||||
|
"1718",
|
||||||
|
"11121314151617181920212223242526"
|
||||||
|
"1718"},
|
||||||
// Two blocks (encrypted) - the mock encryptor adds every byte by 0x10.
|
// Two blocks (encrypted) - the mock encryptor adds every byte by 0x10.
|
||||||
{"0102030405060708091011121314151617181920212223242526272829303132",
|
{"0102030405060708091011121314151617181920212223242526272829303132",
|
||||||
"1112131415161718192021222324252627282930313233343536373839404142"},
|
"1112131415161718192021222324252627282930313233343536373839404142"},
|
||||||
|
@ -125,13 +129,13 @@ const PatternTestCase kPatternTestCases[] = {
|
||||||
"4950515253545556575859606162636465666768697071727374757677787980"
|
"4950515253545556575859606162636465666768697071727374757677787980"
|
||||||
// kSkipByteBlock (1) block not encrypted.
|
// kSkipByteBlock (1) block not encrypted.
|
||||||
"81828384858687888990919293949596"
|
"81828384858687888990919293949596"
|
||||||
// Less than kCryptByteBlock blocks remaining, so not encrypted.
|
// One full block remaining, encrypted.
|
||||||
"97989900010203040506070809101112",
|
"97989900010203040506070809101112",
|
||||||
"1112131415161718192021222324252627282930313233343536373839404142"
|
"1112131415161718192021222324252627282930313233343536373839404142"
|
||||||
"33343536373839404142434445464748"
|
"33343536373839404142434445464748"
|
||||||
"5960616263646566676869707172737475767778798081828384858687888990"
|
"5960616263646566676869707172737475767778798081828384858687888990"
|
||||||
"81828384858687888990919293949596"
|
"81828384858687888990919293949596"
|
||||||
"97989900010203040506070809101112"},
|
"a7a8a910111213141516171819202122"},
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue