Chromium Code Reviews| Index: media/crypto/aes_decryptor_unittest.cc |
| diff --git a/media/crypto/aes_decryptor_unittest.cc b/media/crypto/aes_decryptor_unittest.cc |
| index 814bd6c420baa7805f5bf7498026ee85005fa048..5fceb8eb2a6d0c9e58eb307758cb9f41cc012bc7 100644 |
| --- a/media/crypto/aes_decryptor_unittest.cc |
| +++ b/media/crypto/aes_decryptor_unittest.cc |
| @@ -21,16 +21,44 @@ namespace media { |
| static const char kClearKeySystem[] = "org.w3.clearkey"; |
| static const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; |
| -// |kEncryptedData| is encrypted from |kOriginalData| using |kRightKey|. |
| -// Modifying any of these independently would fail the test. |
| static const uint8 kOriginalData[] = { |
| 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, |
| - 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e |
| + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x20, 0x33, |
| + 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, |
| + 0x6f, 0x66, 0x20, 0x69, 0x74, 0x2e |
| }; |
| -static const uint8 kEncryptedData[] = { |
| - 0x82, 0x3A, 0x76, 0x92, 0xEC, 0x7F, 0xF8, 0x85, |
| - 0xEC, 0x23, 0x52, 0xFB, 0x19, 0xB1, 0xB9, 0x09 |
| + |
| +// |kCbcEncryptedData| is |kOriginalData| encrypted with |kRightKey| and the |
| +// default IV embedded in aes_decryptor.cc. |
| +// |
| +// TODO(strobe): CBC is only used for an early draft of WebM encryption. |
| +// Remove when https://chromiumcodereview.appspot.com/10535029 lands. |
| +static const uint8 kCbcEncryptedData[] = { |
| + 0x16, 0xeb, 0x06, 0xf8, 0x99, 0x87, 0xce, 0x09, |
| + 0x0e, 0x91, 0x5a, 0xa3, 0x88, 0xc3, 0x5b, 0xf5, |
| + 0xe9, 0xac, 0x40, 0x53, 0x95, 0x85, 0x5f, 0x09, |
| + 0x3d, 0xa0, 0x4f, 0xbe, 0x66, 0xf5, 0x15, 0xb5 |
| +}; |
| + |
| +// |kCtrEncryptedData| is |kOriginalData| encrypted with |kRightKey|, using |
| +// initial counter |kInitialIv|. |
| +static const uint8 kCtrEncryptedData[] = { |
| + 0x06, 0x53, 0x1d, 0x16, 0x67, 0xd4, 0x2d, 0x5c, |
| + 0xa8, 0xba, 0x3b, 0x82, 0xc4, 0xdc, 0x14, 0x89, |
| + 0xea, 0x2e, 0x8c, 0x64, 0x4c, 0x4b, 0x6b, 0xda, |
| + 0x39, 0xbb, 0xe8, 0xc1, 0x25, 0x35 |
| }; |
| + |
| +// |kCtrSubsampleEncryptedData| is |kOriginalData|, subsampled according to |
| +// |kSubsamples|, with ciphered portions encrypted with |kRightKey|, using |
| +// initial counter |kInitialIv|. |
| +static const uint8 kCtrSubsampleEncryptedData[] = { |
| + 0x4f, 0x72, 0x69, 0x2e, 0x48, 0x1a, 0x10, 0x62, |
| + 0x20, 0xde, 0x2d, 0x44, 0xe9, 0xf0, 0x7a, 0xc5, |
| + 0x95, 0xd2, 0x56, 0xc3, 0xae, 0x6b, 0x9d, 0x3d, |
| + 0x57, 0x48, 0x38, 0x93, 0x74, 0x2e |
| +}; |
| + |
| static const uint8 kRightKey[] = { |
| 0x41, 0x20, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, |
| 0x66, 0x75, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x21 |
| @@ -46,15 +74,51 @@ static const uint8 kKeyId1[] = { |
| static const uint8 kKeyId2[] = { |
| 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44, 0x20, 0x32 |
| }; |
| +static const uint8 kInitialIv[] = { |
| + 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x56, 0x31, |
| + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| +}; |
| +static const SubsampleEntry kSubsamples[] = { |
| + { 3, 5 }, |
| + { 1, 19 }, |
| + { 2, 0 } |
| +}; |
| class AesDecryptorTest : public testing::Test { |
| public: |
| - AesDecryptorTest() : decryptor_(&client_) { |
| - encrypted_data_ = DecoderBuffer::CopyFrom(kEncryptedData, |
| - arraysize(kEncryptedData)); |
| - } |
| + AesDecryptorTest() : decryptor_(&client_) {} |
| protected: |
| + void InitCbc() { |
| + encrypted_data_ = DecoderBuffer::CopyFrom( |
| + kCbcEncryptedData, arraysize(kCbcEncryptedData)); |
| + encrypted_data_->SetDecryptConfig( |
| + scoped_ptr<DecryptConfig>(new DecryptConfig( |
| + kKeyId1, arraysize(kKeyId1)))); |
| + } |
| + |
| + void InitCtr() { |
| + encrypted_data_ = DecoderBuffer::CopyFrom( |
| + kCtrEncryptedData, arraysize(kCtrEncryptedData)); |
| + encrypted_data_->SetDecryptConfig( |
| + scoped_ptr<DecryptConfig>(new DecryptConfig( |
| + kKeyId1, arraysize(kKeyId1), |
| + std::string(kInitialIv, kInitialIv + arraysize(kInitialIv)), |
|
ddorwin
2012/07/17 01:14:21
Why not just size as the second parameter?
strobe_
2012/07/19 02:43:35
Would require typecasting.
ddorwin
2012/07/19 06:11:10
Just curious: to what?
strobe_
2012/07/19 16:55:02
uint8 to int8.
ddorwin
2012/07/24 01:00:09
The first parameter? uint8* to char*?
So, it would
strobe_
2012/07/25 01:05:13
Will get this in next bundle since it touches many
|
| + std::vector<SubsampleEntry>()))); |
| + } |
| + |
| + void InitCtrSubsample() { |
| + encrypted_data_ = DecoderBuffer::CopyFrom( |
| + kCtrSubsampleEncryptedData, arraysize(kCtrSubsampleEncryptedData)); |
| + std::vector<SubsampleEntry> subsamples( |
| + kSubsamples, kSubsamples + arraysize(kSubsamples)); |
| + encrypted_data_->SetDecryptConfig( |
| + scoped_ptr<DecryptConfig>(new DecryptConfig( |
| + kKeyId1, arraysize(kKeyId1), |
| + std::string(kInitialIv, kInitialIv + arraysize(kInitialIv)), |
| + subsamples))); |
| + } |
| + |
| void GenerateKeyRequest() { |
| EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(std::string()), |
| NotNull(), Gt(0), "")) |
| @@ -80,12 +144,6 @@ class AesDecryptorTest : public testing::Test { |
| session_id_string_); |
| } |
| - template <int KeyIdSize> |
| - void SetKeyIdForEncryptedData(const uint8 (&key_id)[KeyIdSize]) { |
| - encrypted_data_->SetDecryptConfig( |
| - scoped_ptr<DecryptConfig>(new DecryptConfig(key_id, KeyIdSize))); |
| - } |
| - |
| void DecryptAndExpectToSucceed() { |
| scoped_refptr<DecoderBuffer> decrypted = |
| decryptor_.Decrypt(encrypted_data_); |
| @@ -95,10 +153,22 @@ class AesDecryptorTest : public testing::Test { |
| EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length)); |
| } |
| + // This function depends on PKCS#5 verification, which is only performed by |
| + // CBC. |
| + // TODO(strobe): Remove along with CBC. |
| void DecryptAndExpectToFail() { |
| scoped_refptr<DecoderBuffer> decrypted = |
| decryptor_.Decrypt(encrypted_data_); |
| - EXPECT_FALSE(decrypted); |
| + ASSERT_FALSE(decrypted); |
| + } |
| + |
| + void DecryptAndExpectIncorrectData() { |
| + scoped_refptr<DecoderBuffer> decrypted = |
| + decryptor_.Decrypt(encrypted_data_); |
| + ASSERT_TRUE(decrypted); |
| + int data_length = sizeof(kOriginalData); |
| + ASSERT_EQ(data_length, decrypted->GetDataSize()); |
| + EXPECT_NE(0, memcmp(kOriginalData, decrypted->GetData(), data_length)); |
| } |
| scoped_refptr<DecoderBuffer> encrypted_data_; |
| @@ -108,37 +178,76 @@ class AesDecryptorTest : public testing::Test { |
| }; |
| TEST_F(AesDecryptorTest, NormalDecryption) { |
| + InitCtr(); |
|
ddorwin
2012/07/17 01:14:21
Skipping. Will review after rebase.
|
| + GenerateKeyRequest(); |
| + AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| + ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); |
| +} |
| + |
| +TEST_F(AesDecryptorTest, NormalCbcDecryption) { |
| + InitCbc(); |
| + GenerateKeyRequest(); |
| + AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| + ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); |
| +} |
| + |
| +TEST_F(AesDecryptorTest, NormalCtrSubsampleDecryption) { |
| + InitCtrSubsample(); |
| GenerateKeyRequest(); |
| AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| - SetKeyIdForEncryptedData(kKeyId1); |
| ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); |
| } |
| +TEST_F(AesDecryptorTest, WrongSubsampleSize) { |
| + InitCtrSubsample(); |
| + const DecryptConfig& config = *encrypted_data_->GetDecryptConfig(); |
| + std::vector<SubsampleEntry> subsamples = config.subsamples(); |
| + subsamples[0].clear_bytes += 2; |
| + encrypted_data_->SetDecryptConfig( |
| + scoped_ptr<DecryptConfig>(new DecryptConfig( |
| + config.key_id(), config.key_id_size(), |
| + config.iv(), subsamples))); |
| + GenerateKeyRequest(); |
| + AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| + ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); |
| +} |
| + |
| TEST_F(AesDecryptorTest, WrongKey) { |
| + InitCtr(); |
| + GenerateKeyRequest(); |
| + AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); |
| + ASSERT_NO_FATAL_FAILURE(DecryptAndExpectIncorrectData()); |
| +} |
| + |
| +// This test relies on CBC verification of PKCS#5 padding, which CTR mode does |
| +// not expect or verify. |
| +// TODO(strobe): Remove along with CBC. |
| +TEST_F(AesDecryptorTest, WrongCbcKey) { |
| + InitCbc(); |
| GenerateKeyRequest(); |
| AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); |
| - SetKeyIdForEncryptedData(kKeyId1); |
| ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); |
| } |
| TEST_F(AesDecryptorTest, MultipleKeys) { |
| + InitCtr(); |
| GenerateKeyRequest(); |
| AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| AddKeyAndExpectToSucceed(kKeyId2, kWrongKey); |
| - SetKeyIdForEncryptedData(kKeyId1); |
| ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); |
| } |
| TEST_F(AesDecryptorTest, KeyReplacement) { |
| + InitCtr(); |
| GenerateKeyRequest(); |
| - SetKeyIdForEncryptedData(kKeyId1); |
| AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); |
| - ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); |
| + ASSERT_NO_FATAL_FAILURE(DecryptAndExpectIncorrectData()); |
| AddKeyAndExpectToSucceed(kKeyId1, kRightKey); |
| ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); |
| } |
| TEST_F(AesDecryptorTest, WrongSizedKey) { |
| + InitCtr(); |
| GenerateKeyRequest(); |
| AddKeyAndExpectToFail(kKeyId1, kWrongSizedKey); |
| } |