Chromium Code Reviews| 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" |
|
xhwang
2012/06/14 19:42:27
FYI, I am switching to {0x00, 0x11, ...} style for
fgalligan1
2012/07/03 22:00:15
Done.
|
| + "\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) { |
|
xhwang
2012/06/14 19:42:27
Since data, plain_text and key_id are all arrays a
fgalligan1
2012/07/03 22:00:15
I can't use the template function here because it
|
| + 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 |