From 86b10b63169ad0485310d0750580dbb817dd0e0b Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Tue, 28 Aug 2018 16:28:26 -0700 Subject: [PATCH] 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 --- packager/media/base/aes_pattern_cryptor.cc | 34 ++++++++++++------- packager/media/base/aes_pattern_cryptor.h | 20 +++++------ .../base/aes_pattern_cryptor_unittest.cc | 18 ++++++---- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/packager/media/base/aes_pattern_cryptor.cc b/packager/media/base/aes_pattern_cryptor.cc index 3849d66fb2..b3216069a6 100644 --- a/packager/media/base/aes_pattern_cryptor.cc +++ b/packager/media/base/aes_pattern_cryptor.cc @@ -51,14 +51,31 @@ bool AesPatternCryptor::CryptInternal(const uint8_t* text, while (text_size > 0) { 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)) - return false; - } else { - // If there is not enough data, just keep it in clear. + + 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; + text += aligned_crypt_byte_size; + text_size -= aligned_crypt_byte_size; + crypt_text += aligned_crypt_byte_size; + } + + // The remaining bytes are not encrypted. memcpy(crypt_text, text, text_size); return true; } + + if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text)) + return false; text += crypt_byte_size; text_size -= crypt_byte_size; crypt_text += crypt_byte_size; @@ -77,12 +94,5 @@ void AesPatternCryptor::SetIvInternal() { 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 shaka diff --git a/packager/media/base/aes_pattern_cryptor.h b/packager/media/base/aes_pattern_cryptor.h index f65f71e5c0..7a6b295c1c 100644 --- a/packager/media/base/aes_pattern_cryptor.h +++ b/packager/media/base/aes_pattern_cryptor.h @@ -19,18 +19,16 @@ class AesPatternCryptor : public AesCryptor { /// Enumerator for controling encrytion/decryption mode for the last /// encryption/decrytion block(s). enum PatternEncryptionMode { - /// Use kEncryptIfCryptByteBlockRemaining if the last blocks is exactly the - /// same as the number of remaining bytes. IOW - /// if (remaining_bytes == encryption_block_bytes) - /// encrypt(remaining_data) + /// Use kEncryptIfCryptByteBlockRemaining to encrypt all the full 16-byte + /// blocks even if the remaining bytes are less than encryption_block_bytes. + /// IOW: + /// if (remaining_bytes <= encryption_block_bytes) + /// encrypt(block_aligned_remaining_data) kEncryptIfCryptByteBlockRemaining, - /// Use kSkipIfCryptByteBlockRemaining to not encrypt/decrypt the last - /// clocks if it is exactly the same as the number of remaining 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. + /// Use kSkipIfCryptByteBlockRemaining to not encrypt/decrypt the remaining + /// bytes if it is less than or equal to encryption_block_bytes. + /// if (remaining_bytes > encryption_block_bytes) /// encrypt(). - /// } /// Use this mode for HLS SAMPLE-AES. kSkipIfCryptByteBlockRemaining, }; @@ -70,8 +68,6 @@ class AesPatternCryptor : public AesCryptor { size_t* crypt_text_size) override; void SetIvInternal() override; - bool NeedEncrypt(size_t input_size, size_t target_data_size); - uint8_t crypt_byte_block_; const uint8_t skip_byte_block_; const PatternEncryptionMode encryption_mode_; diff --git a/packager/media/base/aes_pattern_cryptor_unittest.cc b/packager/media/base/aes_pattern_cryptor_unittest.cc index 0ba87e18ec..eb6f582bab 100644 --- a/packager/media/base/aes_pattern_cryptor_unittest.cc +++ b/packager/media/base/aes_pattern_cryptor_unittest.cc @@ -103,11 +103,15 @@ const PatternTestCase kPatternTestCases[] = { {"", ""}, // One partial block (not encrypted). {"010203", "010203"}, - // One block (not encrypted). - {"01020304050607080910111213141516", "01020304050607080910111213141516"}, - // One block + partial block (not encrypted). - {"010203040506070809101112131415161718", - "010203040506070809101112131415161718"}, + // One block (encrypted). + {"01020304050607080910111213141516", "11121314151617181920212223242526"}, + // One block + partial block. + {// One block encrypted. + "01020304050607080910111213141516" + // Partial block unencrypted. + "1718", + "11121314151617181920212223242526" + "1718"}, // Two blocks (encrypted) - the mock encryptor adds every byte by 0x10. {"0102030405060708091011121314151617181920212223242526272829303132", "1112131415161718192021222324252627282930313233343536373839404142"}, @@ -125,13 +129,13 @@ const PatternTestCase kPatternTestCases[] = { "4950515253545556575859606162636465666768697071727374757677787980" // kSkipByteBlock (1) block not encrypted. "81828384858687888990919293949596" - // Less than kCryptByteBlock blocks remaining, so not encrypted. + // One full block remaining, encrypted. "97989900010203040506070809101112", "1112131415161718192021222324252627282930313233343536373839404142" "33343536373839404142434445464748" "5960616263646566676869707172737475767778798081828384858687888990" "81828384858687888990919293949596" - "97989900010203040506070809101112"}, + "a7a8a910111213141516171819202122"}, }; } // namespace