| 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
|
|
|