Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: media/crypto/aes_decryptor_unittest.cc

Issue 10651006: Add Common Encryption support to BMFF, including subsample decryption. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix another case issue Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "media/base/decoder_buffer.h" 8 #include "media/base/decoder_buffer.h"
9 #include "media/base/decrypt_config.h" 9 #include "media/base/decrypt_config.h"
10 #include "media/base/mock_filters.h" 10 #include "media/base/mock_filters.h"
11 #include "media/crypto/aes_decryptor.h" 11 #include "media/crypto/aes_decryptor.h"
12 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
13 13
14 using ::testing::_; 14 using ::testing::_;
15 using ::testing::Gt; 15 using ::testing::Gt;
16 using ::testing::NotNull; 16 using ::testing::NotNull;
17 using ::testing::SaveArg; 17 using ::testing::SaveArg;
18 using ::testing::StrNe; 18 using ::testing::StrNe;
19 19
20 namespace media { 20 namespace media {
21 21
22 static const char kClearKeySystem[] = "org.w3.clearkey"; 22 static const char kClearKeySystem[] = "org.w3.clearkey";
23 static const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; 23 static const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 };
24 // |kEncryptedData| is encrypted from |kOriginalData| using |kRightKey|.
25 // Modifying any of these independently would fail the test.
26 static const uint8 kOriginalData[] = { 24 static const uint8 kOriginalData[] = {
27 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 25 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
28 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e 26 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x20, 0x33,
27 0x30, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20,
28 0x6f, 0x66, 0x20, 0x69, 0x74, 0x2e
29 }; 29 };
30 static const uint8 kEncryptedData[] = { 30
31 0x82, 0x3A, 0x76, 0x92, 0xEC, 0x7F, 0xF8, 0x85, 31 // |kCbcEncryptedData| is |kOriginalData| encrypted with |kRightKey| and the
32 0xEC, 0x23, 0x52, 0xFB, 0x19, 0xB1, 0xB9, 0x09 32 // default IV embedded in aes_decryptor.cc.
33 //
34 // TODO(strobe): CBC is only used for an early draft of WebM encryption.
35 // Remove when https://chromiumcodereview.appspot.com/10535029 lands.
36 static const uint8 kCbcEncryptedData[] = {
37 0x16, 0xeb, 0x06, 0xf8, 0x99, 0x87, 0xce, 0x09,
38 0x0e, 0x91, 0x5a, 0xa3, 0x88, 0xc3, 0x5b, 0xf5,
39 0xe9, 0xac, 0x40, 0x53, 0x95, 0x85, 0x5f, 0x09,
40 0x3d, 0xa0, 0x4f, 0xbe, 0x66, 0xf5, 0x15, 0xb5
33 }; 41 };
42
43 // |kCtrEncryptedData| is |kOriginalData| encrypted with |kRightKey|, using
44 // initial counter |kInitialIv|.
45 static const uint8 kCtrEncryptedData[] = {
46 0x06, 0x53, 0x1d, 0x16, 0x67, 0xd4, 0x2d, 0x5c,
47 0xa8, 0xba, 0x3b, 0x82, 0xc4, 0xdc, 0x14, 0x89,
48 0xea, 0x2e, 0x8c, 0x64, 0x4c, 0x4b, 0x6b, 0xda,
49 0x39, 0xbb, 0xe8, 0xc1, 0x25, 0x35
50 };
51
52 // |kCtrSubsampleEncryptedData| is |kOriginalData|, subsampled according to
53 // |kSubsamples|, with ciphered portions encrypted with |kRightKey|, using
54 // initial counter |kInitialIv|.
55 static const uint8 kCtrSubsampleEncryptedData[] = {
56 0x4f, 0x72, 0x69, 0x2e, 0x48, 0x1a, 0x10, 0x62,
57 0x20, 0xde, 0x2d, 0x44, 0xe9, 0xf0, 0x7a, 0xc5,
58 0x95, 0xd2, 0x56, 0xc3, 0xae, 0x6b, 0x9d, 0x3d,
59 0x57, 0x48, 0x38, 0x93, 0x74, 0x2e
60 };
61
34 static const uint8 kRightKey[] = { 62 static const uint8 kRightKey[] = {
35 0x41, 0x20, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 63 0x41, 0x20, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72,
36 0x66, 0x75, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x21 64 0x66, 0x75, 0x6c, 0x20, 0x6b, 0x65, 0x79, 0x21
37 }; 65 };
38 static const uint8 kWrongKey[] = { 66 static const uint8 kWrongKey[] = {
39 0x49, 0x27, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x72, 67 0x49, 0x27, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x72,
40 0x6f, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x2e 68 0x6f, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x2e
41 }; 69 };
42 static const uint8 kWrongSizedKey[] = { 0x20, 0x20 }; 70 static const uint8 kWrongSizedKey[] = { 0x20, 0x20 };
43 static const uint8 kKeyId1[] = { 71 static const uint8 kKeyId1[] = {
44 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44, 0x20, 0x31 72 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44, 0x20, 0x31
45 }; 73 };
46 static const uint8 kKeyId2[] = { 74 static const uint8 kKeyId2[] = {
47 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44, 0x20, 0x32 75 0x4b, 0x65, 0x79, 0x20, 0x49, 0x44, 0x20, 0x32
48 }; 76 };
77 static const uint8 kInitialIv[] = {
78 0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x56, 0x31,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
80 };
81 static const SubsampleEntry kSubsamples[] = {
82 { 3, 5 },
83 { 1, 19 },
84 { 2, 0 }
85 };
49 86
50 class AesDecryptorTest : public testing::Test { 87 class AesDecryptorTest : public testing::Test {
51 public: 88 public:
52 AesDecryptorTest() : decryptor_(&client_) { 89 AesDecryptorTest() : decryptor_(&client_) {}
53 encrypted_data_ = DecoderBuffer::CopyFrom(kEncryptedData, 90
54 arraysize(kEncryptedData)); 91 protected:
92 void InitCBC() {
xhwang 2012/06/27 22:38:35 Change to InitCbc(), to be consistent with kCbcEnc
strobe_ 2012/07/13 00:47:07 Done.
93 encrypted_data_ = DecoderBuffer::CopyFrom(
94 kCbcEncryptedData, arraysize(kCbcEncryptedData));
95 encrypted_data_->SetDecryptConfig(
96 scoped_ptr<DecryptConfig>(new DecryptConfig(
97 kKeyId1, arraysize(kKeyId1))));
55 } 98 }
56 99
57 protected: 100 void InitCTR() {
101 encrypted_data_ = DecoderBuffer::CopyFrom(
102 kCtrEncryptedData, arraysize(kCtrEncryptedData));
103 encrypted_data_->SetDecryptConfig(
104 scoped_ptr<DecryptConfig>(new DecryptConfig(
105 kKeyId1, arraysize(kKeyId1),
106 kInitialIv, arraysize(kInitialIv),
107 NULL, 0)));
108 }
109
110 void InitCTRSubsample() {
111 encrypted_data_ = DecoderBuffer::CopyFrom(
112 kCtrSubsampleEncryptedData, arraysize(kCtrSubsampleEncryptedData));
113 encrypted_data_->SetDecryptConfig(
114 scoped_ptr<DecryptConfig>(new DecryptConfig(
115 kKeyId1, arraysize(kKeyId1),
116 kInitialIv, arraysize(kInitialIv),
117 kSubsamples, arraysize(kSubsamples))));
118 }
119
58 void GenerateKeyRequest() { 120 void GenerateKeyRequest() {
59 EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(std::string()), 121 EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(std::string()),
60 NotNull(), Gt(0), "")) 122 NotNull(), Gt(0), ""))
61 .WillOnce(SaveArg<1>(&session_id_string_)); 123 .WillOnce(SaveArg<1>(&session_id_string_));
62 decryptor_.GenerateKeyRequest(kClearKeySystem, 124 decryptor_.GenerateKeyRequest(kClearKeySystem,
63 kInitData, arraysize(kInitData)); 125 kInitData, arraysize(kInitData));
64 } 126 }
65 127
66 template <int KeyIdSize, int KeySize> 128 template <int KeyIdSize, int KeySize>
67 void AddKeyAndExpectToSucceed(const uint8 (&key_id)[KeyIdSize], 129 void AddKeyAndExpectToSucceed(const uint8 (&key_id)[KeyIdSize],
68 const uint8 (&key)[KeySize]) { 130 const uint8 (&key)[KeySize]) {
69 EXPECT_CALL(client_, KeyAdded(kClearKeySystem, session_id_string_)); 131 EXPECT_CALL(client_, KeyAdded(kClearKeySystem, session_id_string_));
70 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize, 132 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize,
71 session_id_string_); 133 session_id_string_);
72 } 134 }
73 135
74 template <int KeyIdSize, int KeySize> 136 template <int KeyIdSize, int KeySize>
75 void AddKeyAndExpectToFail(const uint8 (&key_id)[KeyIdSize], 137 void AddKeyAndExpectToFail(const uint8 (&key_id)[KeyIdSize],
76 const uint8 (&key)[KeySize]) { 138 const uint8 (&key)[KeySize]) {
77 EXPECT_CALL(client_, KeyError(kClearKeySystem, session_id_string_, 139 EXPECT_CALL(client_, KeyError(kClearKeySystem, session_id_string_,
78 Decryptor::kUnknownError, 0)); 140 Decryptor::kUnknownError, 0));
79 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize, 141 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize,
80 session_id_string_); 142 session_id_string_);
81 } 143 }
82 144
83 template <int KeyIdSize>
84 void SetKeyIdForEncryptedData(const uint8 (&key_id)[KeyIdSize]) {
85 encrypted_data_->SetDecryptConfig(
86 scoped_ptr<DecryptConfig>(new DecryptConfig(key_id, KeyIdSize)));
87 }
88
89 void DecryptAndExpectToSucceed() { 145 void DecryptAndExpectToSucceed() {
90 scoped_refptr<DecoderBuffer> decrypted = 146 scoped_refptr<DecoderBuffer> decrypted =
91 decryptor_.Decrypt(encrypted_data_); 147 decryptor_.Decrypt(encrypted_data_);
92 ASSERT_TRUE(decrypted); 148 ASSERT_TRUE(decrypted);
93 int data_length = sizeof(kOriginalData); 149 int data_length = sizeof(kOriginalData);
94 ASSERT_EQ(data_length, decrypted->GetDataSize()); 150 ASSERT_EQ(data_length, decrypted->GetDataSize());
95 EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length)); 151 EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length));
96 } 152 }
97 153
154 // This function depends on PKCS#5 verification, which is only performed by
155 // CBC. Remove along with CBC.
ddorwin 2012/07/03 21:03:47 \nTODO: Remove..
strobe_ 2012/07/13 00:47:07 Done.
98 void DecryptAndExpectToFail() { 156 void DecryptAndExpectToFail() {
99 scoped_refptr<DecoderBuffer> decrypted = 157 scoped_refptr<DecoderBuffer> decrypted =
100 decryptor_.Decrypt(encrypted_data_); 158 decryptor_.Decrypt(encrypted_data_);
101 EXPECT_FALSE(decrypted); 159 ASSERT_FALSE(decrypted);
160 }
161
162 void DecryptAndExpectIncorrectData() {
163 scoped_refptr<DecoderBuffer> decrypted =
164 decryptor_.Decrypt(encrypted_data_);
165 ASSERT_TRUE(decrypted);
166 int data_length = sizeof(kOriginalData);
167 ASSERT_EQ(data_length, decrypted->GetDataSize());
168 EXPECT_NE(0, memcmp(kOriginalData, decrypted->GetData(), data_length));
102 } 169 }
103 170
104 scoped_refptr<DecoderBuffer> encrypted_data_; 171 scoped_refptr<DecoderBuffer> encrypted_data_;
105 MockDecryptorClient client_; 172 MockDecryptorClient client_;
106 AesDecryptor decryptor_; 173 AesDecryptor decryptor_;
107 std::string session_id_string_; 174 std::string session_id_string_;
108 }; 175 };
109 176
110 TEST_F(AesDecryptorTest, NormalDecryption) { 177 TEST_F(AesDecryptorTest, NormalDecryption) {
178 InitCTR();
111 GenerateKeyRequest(); 179 GenerateKeyRequest();
112 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 180 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
113 SetKeyIdForEncryptedData(kKeyId1);
114 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 181 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
115 } 182 }
116 183
184 TEST_F(AesDecryptorTest, NormalCBCDecryption) {
185 InitCBC();
186 GenerateKeyRequest();
187 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
188 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
189 }
190
191 TEST_F(AesDecryptorTest, NormalCTRSubsampleDecryption) {
192 InitCTRSubsample();
193 GenerateKeyRequest();
194 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
195 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
196 }
197
198 // This test relies on CBC verification of PKCS#5 padding, which CTR mode does
199 // not expect or verify. It should be removed along with support for CBC.
ddorwin 2012/07/03 21:03:47 If you want to remove this one, there should be a
strobe_ 2012/07/13 00:47:07 Done.
117 TEST_F(AesDecryptorTest, WrongKey) { 200 TEST_F(AesDecryptorTest, WrongKey) {
201 InitCBC();
118 GenerateKeyRequest(); 202 GenerateKeyRequest();
119 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); 203 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey);
120 SetKeyIdForEncryptedData(kKeyId1);
121 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); 204 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail());
122 } 205 }
123 206
124 TEST_F(AesDecryptorTest, MultipleKeys) { 207 TEST_F(AesDecryptorTest, MultipleKeys) {
208 InitCTR();
125 GenerateKeyRequest(); 209 GenerateKeyRequest();
126 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 210 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
127 AddKeyAndExpectToSucceed(kKeyId2, kWrongKey); 211 AddKeyAndExpectToSucceed(kKeyId2, kWrongKey);
128 SetKeyIdForEncryptedData(kKeyId1);
129 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 212 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
130 } 213 }
131 214
132 TEST_F(AesDecryptorTest, KeyReplacement) { 215 TEST_F(AesDecryptorTest, KeyReplacement) {
216 InitCTR();
133 GenerateKeyRequest(); 217 GenerateKeyRequest();
134 SetKeyIdForEncryptedData(kKeyId1);
135 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); 218 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey);
136 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); 219 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectIncorrectData());
137 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 220 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
138 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 221 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
139 } 222 }
140 223
141 TEST_F(AesDecryptorTest, WrongSizedKey) { 224 TEST_F(AesDecryptorTest, WrongSizedKey) {
225 InitCTR();
142 GenerateKeyRequest(); 226 GenerateKeyRequest();
143 AddKeyAndExpectToFail(kKeyId1, kWrongSizedKey); 227 AddKeyAndExpectToFail(kKeyId1, kWrongSizedKey);
144 } 228 }
145 229
146 } // media 230 } // media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698