Index: media/crypto/hmac_aes_decryptor_unittest.cc |
diff --git a/media/crypto/hmac_aes_decryptor_unittest.cc b/media/crypto/hmac_aes_decryptor_unittest.cc |
new file mode 100755 |
index 0000000000000000000000000000000000000000..b32c9b9a3aed1598dfecd0e508728278b0a64ab9 |
--- /dev/null |
+++ b/media/crypto/hmac_aes_decryptor_unittest.cc |
@@ -0,0 +1,256 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <string> |
+ |
+#include "base/logging.h" |
+#include "base/sys_byteorder.h" |
+#include "media/base/decoder_buffer.h" |
+#include "media/base/decrypt_config.h" |
+#include "media/crypto/hmac_aes_decryptor.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace media { |
+ |
+struct WebmEncryptedData { |
+ uint8 plain_text[32]; |
+ int plain_text_size; |
+ uint8 key_id[32]; |
+ int key_id_size; |
+ uint8 key[32]; |
+ int key_size; |
+ uint8 encrypted_data[64]; |
+ int encrypted_data_size; |
+}; |
+ |
+const WebmEncryptedData kEncryptedFrames[] = { |
+ { |
+ // plaintext |
+ "Original data.", 14, |
+ // key_id |
+ "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" |
+ "\x10\x11\x12\x13", 20, |
+ // key |
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, |
+ // encrypted_data |
+ "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" |
+ "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" |
+ "\x64\xf7", 34 |
+ }, |
+ { |
+ // plaintext |
+ "Changed Original data.", 22, |
+ // key_id |
+ "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" |
+ "\x10\x11\x12\x13", 20, |
+ // key |
+ "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, |
+ // encrypted_data |
+ "\x43\xe4\x78\x7a\x43\xe1\x49\xbb\x44\x38\xdf\xfc\x0\x0\x0\x0" |
+ "\x0\x0\x0\x0\xec\x8e\x87\x21\xd3\xb9\x1c\x61\xf6\x5a\x60\xaa" |
+ "\x7\xe\x96\xd0\x54\x5d\x35\x9a\x4a\xd3", 42 |
+ }, |
+ { |
+ // plaintext |
+ "Original data.", 14, |
+ // key_id |
+ "\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30", 13, |
+ // key |
+ "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40", 16, |
+ // encrypted_data |
+ "\xd9\x43\x30\xfd\x82\x77\x62\x4\x8\xc2\x48\x89\x0\x0\x0\x0" |
+ "\x0\x0\x0\x1\x48\x5e\x4a\x41\x2a\x8b\xf4\xc6\x47\x54\x90\x34" |
+ "\xf4\x8b", 34 |
+ }, |
+}; |
+ |
+static const int kKeySize = 16; |
+static const unsigned char kWrongKey[] = "I'm a wrong key."; |
+static const unsigned char kFrame0InvalidHmac[] = |
+ "\xfc\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" |
+ "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" |
+ "\x64\xf7"; |
+static const unsigned char kFrame0InvalidIv[] = |
+ "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\x0f\xff\xff\xff" |
+ "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" |
+ "\x64\xf7"; |
+static const unsigned char kFrame0InvalidData[] = |
+ "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" |
+ "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" |
+ "\x64\xf8"; |
+ |
+class HmacAesDecryptorTest : public testing::Test { |
+ public: |
+ HmacAesDecryptorTest() {} |
+ |
+ protected: |
+ scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(const uint8* data, |
+ int data_size, |
+ const uint8* key_id, |
+ int key_id_size) { |
+ CHECK_GE(data_size, |
+ DecryptConfig::kWebMIntegrityCheckSize + DecryptConfig::kIvSize); |
+ scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( |
+ data, data_size); |
+ CHECK(encrypted_buffer); |
+ |
+ // Every encrypted Block has an HMAC and IV prepended to it. Current WebM |
+ // encrypted request for comments specification is here |
+ // http://wiki.webmproject.org/encryption/webm-encryption-rfc. |
+ uint64 network_iv; |
+ memcpy(&network_iv, |
+ data + DecryptConfig::kWebMIntegrityCheckSize, |
+ sizeof(network_iv)); |
+ const uint64 iv = base::NetToHost64(network_iv); |
+ encrypted_buffer->SetDecryptConfig( |
+ scoped_ptr<DecryptConfig>(new DecryptConfig( |
+ data, DecryptConfig::kWebMIntegrityCheckSize, |
+ iv, |
+ key_id, key_id_size))); |
+ return encrypted_buffer; |
+ } |
+ |
+ void DecryptAndExpectToSucceed(const uint8* data, int data_size, |
+ const uint8* plain_text, |
+ int plain_text_size, |
+ const uint8* key_id, int key_id_size) { |
+ scoped_refptr<DecoderBuffer> encrypted_data = |
+ CreateEncryptedBuffer(data, data_size, key_id, key_id_size); |
+ scoped_refptr<DecoderBuffer> decrypted = |
+ decryptor_.Decrypt(encrypted_data); |
+ ASSERT_TRUE(decrypted); |
+ ASSERT_EQ(plain_text_size, decrypted->GetDataSize()); |
+ EXPECT_EQ(0, memcmp(plain_text, decrypted->GetData(), plain_text_size)); |
+ } |
+ |
+ void DecryptAndExpectToFail(const uint8* data, int data_size, |
+ const uint8* plain_text, int plain_text_size, |
+ const uint8* key_id, int key_id_size) { |
+ scoped_refptr<DecoderBuffer> encrypted_data = |
+ CreateEncryptedBuffer(data, data_size, key_id, key_id_size); |
+ scoped_refptr<DecoderBuffer> decrypted = |
+ decryptor_.Decrypt(encrypted_data); |
+ EXPECT_FALSE(decrypted); |
+ } |
+ |
+ HmacAesDecryptor decryptor_; |
+}; |
+ |
+TEST_F(HmacAesDecryptorTest, NormalDecryption) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, WrongKey) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ kWrongKey, kKeySize); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, MultipleKeys) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ const WebmEncryptedData& frame2 = kEncryptedFrames[2]; |
+ decryptor_.AddKey(frame2.key_id, frame2.key_id_size, |
+ frame2.key, frame2.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, KeyReplacement) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ kWrongKey, kKeySize); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, MultipleKeysAndFrames) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ const WebmEncryptedData& frame2 = kEncryptedFrames[2]; |
+ decryptor_.AddKey(frame2.key_id, frame2.key_id_size, |
+ frame2.key, frame2.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame2.encrypted_data, |
+ frame2.encrypted_data_size, |
+ frame2.plain_text, |
+ frame2.plain_text_size, |
+ frame2.key_id, |
+ frame2.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, HmacCheckFailure) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidHmac, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, IvCheckFailure) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidIv, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+TEST_F(HmacAesDecryptorTest, DataCheckFailure) { |
+ const WebmEncryptedData& frame = kEncryptedFrames[0]; |
+ decryptor_.AddKey(frame.key_id, frame.key_id_size, |
+ frame.key, frame.key_size); |
+ ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidData, |
+ frame.encrypted_data_size, |
+ frame.plain_text, |
+ frame.plain_text_size, |
+ frame.key_id, |
+ frame.key_id_size)); |
+} |
+ |
+} // media |