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

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: Remove references to non-public encrypted files in tests 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[] = {
fgalligan1 2012/06/27 00:28:36 s/kCBCEncryptedData/kCbcEncryptedData
strobe_ 2012/06/27 02:01:21 Done.
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 |kInitialCtr|.
45 static const uint8 kCTREncryptedData[] = {
fgalligan1 2012/06/27 00:28:36 s/kCTREncryptedData/kCtrEncryptedData/
strobe_ 2012/06/27 02:01:21 Done.
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 // |kCTREncryptedData| is |kOriginalData|, subsampled according to
fgalligan1 2012/06/27 00:28:36 kCtrSubsampleEncryptedData
strobe_ 2012/06/27 02:01:21 Done.
53 // |kSubsamples|, with ciphered portions encrypted with |kRightKey|, using
54 // initial counter |kInitialCtr|.
55 static const uint8 kCTRSubsampleEncryptedData[] = {
fgalligan1 2012/06/27 00:28:36 s/kCTRSubsampleEncryptedData/kCtrSubsampleEncrypte
strobe_ 2012/06/27 02:01:21 Done.
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 kInitialCtr[] = {
ddorwin 2012/06/26 06:09:19 Why not call this IV?
strobe_ 2012/06/27 02:01:21 Done. (The underlying libraries tend to treat init
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 InitCTR();
ddorwin 2012/06/26 06:09:19 I think this is unexpected. Please call it in each
strobe_ 2012/06/27 02:01:21 Done.
54 arraysize(kEncryptedData)); 91 };
92
93 protected:
94 void InitCBC() {
95 encrypted_data_ = DecoderBuffer::CopyFrom(
96 kCBCEncryptedData, arraysize(kCBCEncryptedData));
97 encrypted_data_->SetDecryptConfig(
98 scoped_ptr<DecryptConfig>(new DecryptConfig(
99 kKeyId1, arraysize(kKeyId1))));
55 } 100 }
56 101
57 protected: 102 void InitCTR() {
103 encrypted_data_ = DecoderBuffer::CopyFrom(
104 kCTREncryptedData, arraysize(kCTREncryptedData));
105 encrypted_data_->SetDecryptConfig(
106 scoped_ptr<DecryptConfig>(new DecryptConfig(
107 kKeyId1, arraysize(kKeyId1),
108 kInitialCtr, arraysize(kInitialCtr))));
109 }
110
111 void InitCTRSubsample() {
112 encrypted_data_ = DecoderBuffer::CopyFrom(
113 kCTRSubsampleEncryptedData, arraysize(kCTRSubsampleEncryptedData));
114 encrypted_data_->SetDecryptConfig(
115 scoped_ptr<DecryptConfig>(new DecryptConfig(
116 kKeyId1, arraysize(kKeyId1),
117 kInitialCtr, arraysize(kInitialCtr),
118 kSubsamples, arraysize(kSubsamples))));
119 }
120
58 void GenerateKeyRequest() { 121 void GenerateKeyRequest() {
59 EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(std::string()), 122 EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(std::string()),
60 NotNull(), Gt(0), "")) 123 NotNull(), Gt(0), ""))
61 .WillOnce(SaveArg<1>(&session_id_string_)); 124 .WillOnce(SaveArg<1>(&session_id_string_));
62 decryptor_.GenerateKeyRequest(kClearKeySystem, 125 decryptor_.GenerateKeyRequest(kClearKeySystem,
63 kInitData, arraysize(kInitData)); 126 kInitData, arraysize(kInitData));
64 } 127 }
65 128
66 template <int KeyIdSize, int KeySize> 129 template <int KeyIdSize, int KeySize>
67 void AddKeyAndExpectToSucceed(const uint8 (&key_id)[KeyIdSize], 130 void AddKeyAndExpectToSucceed(const uint8 (&key_id)[KeyIdSize],
68 const uint8 (&key)[KeySize]) { 131 const uint8 (&key)[KeySize]) {
69 EXPECT_CALL(client_, KeyAdded(kClearKeySystem, session_id_string_)); 132 EXPECT_CALL(client_, KeyAdded(kClearKeySystem, session_id_string_));
70 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize, 133 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize,
71 session_id_string_); 134 session_id_string_);
72 } 135 }
73 136
74 template <int KeyIdSize, int KeySize> 137 template <int KeyIdSize, int KeySize>
75 void AddKeyAndExpectToFail(const uint8 (&key_id)[KeyIdSize], 138 void AddKeyAndExpectToFail(const uint8 (&key_id)[KeyIdSize],
76 const uint8 (&key)[KeySize]) { 139 const uint8 (&key)[KeySize]) {
77 EXPECT_CALL(client_, KeyError(kClearKeySystem, session_id_string_, 140 EXPECT_CALL(client_, KeyError(kClearKeySystem, session_id_string_,
78 Decryptor::kUnknownError, 0)); 141 Decryptor::kUnknownError, 0));
79 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize, 142 decryptor_.AddKey(kClearKeySystem, key, KeySize, key_id, KeyIdSize,
80 session_id_string_); 143 session_id_string_);
81 } 144 }
82 145
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() { 146 void DecryptAndExpectToSucceed() {
90 scoped_refptr<DecoderBuffer> decrypted = 147 scoped_refptr<DecoderBuffer> decrypted =
91 decryptor_.Decrypt(encrypted_data_); 148 decryptor_.Decrypt(encrypted_data_);
92 ASSERT_TRUE(decrypted); 149 ASSERT_TRUE(decrypted);
93 int data_length = sizeof(kOriginalData); 150 int data_length = sizeof(kOriginalData);
94 ASSERT_EQ(data_length, decrypted->GetDataSize()); 151 ASSERT_EQ(data_length, decrypted->GetDataSize());
95 EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length)); 152 EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length));
96 } 153 }
97 154
98 void DecryptAndExpectToFail() { 155 void DecryptAndExpectIncorrectData() {
99 scoped_refptr<DecoderBuffer> decrypted = 156 scoped_refptr<DecoderBuffer> decrypted =
100 decryptor_.Decrypt(encrypted_data_); 157 decryptor_.Decrypt(encrypted_data_);
101 EXPECT_FALSE(decrypted); 158 ASSERT_TRUE(decrypted);
ddorwin 2012/06/26 06:09:19 Does this pass because you fixed up the padding or
strobe_ 2012/06/27 02:01:21 The latter. Our CBC decoder expects PKCS#5 padding
159 int data_length = sizeof(kOriginalData);
160 ASSERT_EQ(data_length, decrypted->GetDataSize());
161 EXPECT_NE(0, memcmp(kOriginalData, decrypted->GetData(), data_length));
102 } 162 }
103 163
104 scoped_refptr<DecoderBuffer> encrypted_data_; 164 scoped_refptr<DecoderBuffer> encrypted_data_;
105 MockDecryptorClient client_; 165 MockDecryptorClient client_;
106 AesDecryptor decryptor_; 166 AesDecryptor decryptor_;
107 std::string session_id_string_; 167 std::string session_id_string_;
108 }; 168 };
109 169
110 TEST_F(AesDecryptorTest, NormalDecryption) { 170 TEST_F(AesDecryptorTest, NormalDecryption) {
111 GenerateKeyRequest(); 171 GenerateKeyRequest();
112 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 172 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
113 SetKeyIdForEncryptedData(kKeyId1);
114 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 173 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
115 } 174 }
116 175
117 TEST_F(AesDecryptorTest, WrongKey) { 176 TEST_F(AesDecryptorTest, NormalCBCDecryption) {
177 InitCBC();
178 GenerateKeyRequest();
179 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
180 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
181 }
182
183 TEST_F(AesDecryptorTest, NormalCTRSubsampleDecryption) {
184 InitCTRSubsample();
185 GenerateKeyRequest();
186 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
187 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
188 }
189
190 TEST_F(AesDecryptorTest, WrongCBCKey) {
ddorwin 2012/06/26 06:09:19 add InitCTRSubsample(); I think you also need a Wr
strobe_ 2012/06/27 02:01:21 Not sure where this should go.
118 GenerateKeyRequest(); 191 GenerateKeyRequest();
119 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); 192 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey);
120 SetKeyIdForEncryptedData(kKeyId1); 193 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectIncorrectData());
121 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail());
122 } 194 }
123 195
124 TEST_F(AesDecryptorTest, MultipleKeys) { 196 TEST_F(AesDecryptorTest, MultipleKeys) {
125 GenerateKeyRequest(); 197 GenerateKeyRequest();
126 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 198 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
127 AddKeyAndExpectToSucceed(kKeyId2, kWrongKey); 199 AddKeyAndExpectToSucceed(kKeyId2, kWrongKey);
128 SetKeyIdForEncryptedData(kKeyId1);
129 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 200 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
130 } 201 }
131 202
132 TEST_F(AesDecryptorTest, KeyReplacement) { 203 TEST_F(AesDecryptorTest, KeyReplacement) {
133 GenerateKeyRequest(); 204 GenerateKeyRequest();
134 SetKeyIdForEncryptedData(kKeyId1);
135 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey); 205 AddKeyAndExpectToSucceed(kKeyId1, kWrongKey);
136 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); 206 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectIncorrectData());
137 AddKeyAndExpectToSucceed(kKeyId1, kRightKey); 207 AddKeyAndExpectToSucceed(kKeyId1, kRightKey);
138 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); 208 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed());
139 } 209 }
140 210
141 TEST_F(AesDecryptorTest, WrongSizedKey) { 211 TEST_F(AesDecryptorTest, WrongSizedKey) {
142 GenerateKeyRequest(); 212 GenerateKeyRequest();
143 AddKeyAndExpectToFail(kKeyId1, kWrongSizedKey); 213 AddKeyAndExpectToFail(kKeyId1, kWrongSizedKey);
144 } 214 }
145 215
146 } // media 216 } // media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698