OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include <string> | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/sys_byteorder.h" | |
9 #include "media/base/decoder_buffer.h" | |
10 #include "media/base/decrypt_config.h" | |
11 #include "media/crypto/hmac_aes_decryptor.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 namespace media { | |
15 | |
16 struct WebmEncryptedData { | |
17 uint8 plain_text[32]; | |
18 int plain_text_size; | |
19 uint8 key_id[32]; | |
20 int key_id_size; | |
21 uint8 key[32]; | |
22 int key_size; | |
23 uint8 encrypted_data[64]; | |
24 int encrypted_data_size; | |
25 }; | |
26 | |
27 const WebmEncryptedData kEncryptedFrames[] = { | |
28 { | |
29 // plaintext | |
30 "Original data.", 14, | |
31 // key_id | |
32 "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" | |
33 "\x10\x11\x12\x13", 20, | |
34 // key | |
35 "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, | |
36 // encrypted_data | |
37 "\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.
| |
38 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
39 "\x64\xf7", 34 | |
40 }, | |
41 { | |
42 // plaintext | |
43 "Changed Original data.", 22, | |
44 // key_id | |
45 "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" | |
46 "\x10\x11\x12\x13", 20, | |
47 // key | |
48 "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, | |
49 // encrypted_data | |
50 "\x43\xe4\x78\x7a\x43\xe1\x49\xbb\x44\x38\xdf\xfc\x0\x0\x0\x0" | |
51 "\x0\x0\x0\x0\xec\x8e\x87\x21\xd3\xb9\x1c\x61\xf6\x5a\x60\xaa" | |
52 "\x7\xe\x96\xd0\x54\x5d\x35\x9a\x4a\xd3", 42 | |
53 }, | |
54 { | |
55 // plaintext | |
56 "Original data.", 14, | |
57 // key_id | |
58 "\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30", 13, | |
59 // key | |
60 "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40", 16, | |
61 // encrypted_data | |
62 "\xd9\x43\x30\xfd\x82\x77\x62\x4\x8\xc2\x48\x89\x0\x0\x0\x0" | |
63 "\x0\x0\x0\x1\x48\x5e\x4a\x41\x2a\x8b\xf4\xc6\x47\x54\x90\x34" | |
64 "\xf4\x8b", 34 | |
65 }, | |
66 }; | |
67 | |
68 static const int kKeySize = 16; | |
69 static const unsigned char kWrongKey[] = "I'm a wrong key."; | |
70 static const unsigned char kFrame0InvalidHmac[] = | |
71 "\xfc\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" | |
72 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
73 "\x64\xf7"; | |
74 static const unsigned char kFrame0InvalidIv[] = | |
75 "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\x0f\xff\xff\xff" | |
76 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
77 "\x64\xf7"; | |
78 static const unsigned char kFrame0InvalidData[] = | |
79 "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" | |
80 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
81 "\x64\xf8"; | |
82 | |
83 class HmacAesDecryptorTest : public testing::Test { | |
84 public: | |
85 HmacAesDecryptorTest() {} | |
86 | |
87 protected: | |
88 scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(const uint8* data, | |
89 int data_size, | |
90 const uint8* key_id, | |
91 int key_id_size) { | |
92 CHECK_GE(data_size, | |
93 DecryptConfig::kWebMIntegrityCheckSize + DecryptConfig::kIvSize); | |
94 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( | |
95 data, data_size); | |
96 CHECK(encrypted_buffer); | |
97 | |
98 // Every encrypted Block has an HMAC and IV prepended to it. Current WebM | |
99 // encrypted request for comments specification is here | |
100 // http://wiki.webmproject.org/encryption/webm-encryption-rfc. | |
101 uint64 network_iv; | |
102 memcpy(&network_iv, | |
103 data + DecryptConfig::kWebMIntegrityCheckSize, | |
104 sizeof(network_iv)); | |
105 const uint64 iv = base::NetToHost64(network_iv); | |
106 encrypted_buffer->SetDecryptConfig( | |
107 scoped_ptr<DecryptConfig>(new DecryptConfig( | |
108 data, DecryptConfig::kWebMIntegrityCheckSize, | |
109 iv, | |
110 key_id, key_id_size))); | |
111 return encrypted_buffer; | |
112 } | |
113 | |
114 void DecryptAndExpectToSucceed(const uint8* data, int data_size, | |
115 const uint8* plain_text, | |
116 int plain_text_size, | |
117 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
| |
118 scoped_refptr<DecoderBuffer> encrypted_data = | |
119 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); | |
120 scoped_refptr<DecoderBuffer> decrypted = | |
121 decryptor_.Decrypt(encrypted_data); | |
122 ASSERT_TRUE(decrypted); | |
123 ASSERT_EQ(plain_text_size, decrypted->GetDataSize()); | |
124 EXPECT_EQ(0, memcmp(plain_text, decrypted->GetData(), plain_text_size)); | |
125 } | |
126 | |
127 void DecryptAndExpectToFail(const uint8* data, int data_size, | |
128 const uint8* plain_text, int plain_text_size, | |
129 const uint8* key_id, int key_id_size) { | |
130 scoped_refptr<DecoderBuffer> encrypted_data = | |
131 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); | |
132 scoped_refptr<DecoderBuffer> decrypted = | |
133 decryptor_.Decrypt(encrypted_data); | |
134 EXPECT_FALSE(decrypted); | |
135 } | |
136 | |
137 HmacAesDecryptor decryptor_; | |
138 }; | |
139 | |
140 TEST_F(HmacAesDecryptorTest, NormalDecryption) { | |
141 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
142 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
143 frame.key, frame.key_size); | |
144 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
145 frame.encrypted_data_size, | |
146 frame.plain_text, | |
147 frame.plain_text_size, | |
148 frame.key_id, | |
149 frame.key_id_size)); | |
150 } | |
151 | |
152 TEST_F(HmacAesDecryptorTest, WrongKey) { | |
153 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
154 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
155 kWrongKey, kKeySize); | |
156 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, | |
157 frame.encrypted_data_size, | |
158 frame.plain_text, | |
159 frame.plain_text_size, | |
160 frame.key_id, | |
161 frame.key_id_size)); | |
162 } | |
163 | |
164 TEST_F(HmacAesDecryptorTest, MultipleKeys) { | |
165 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
166 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
167 frame.key, frame.key_size); | |
168 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; | |
169 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, | |
170 frame2.key, frame2.key_size); | |
171 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
172 frame.encrypted_data_size, | |
173 frame.plain_text, | |
174 frame.plain_text_size, | |
175 frame.key_id, | |
176 frame.key_id_size)); | |
177 } | |
178 | |
179 TEST_F(HmacAesDecryptorTest, KeyReplacement) { | |
180 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
181 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
182 kWrongKey, kKeySize); | |
183 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, | |
184 frame.encrypted_data_size, | |
185 frame.plain_text, | |
186 frame.plain_text_size, | |
187 frame.key_id, | |
188 frame.key_id_size)); | |
189 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
190 frame.key, frame.key_size); | |
191 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
192 frame.encrypted_data_size, | |
193 frame.plain_text, | |
194 frame.plain_text_size, | |
195 frame.key_id, | |
196 frame.key_id_size)); | |
197 } | |
198 | |
199 TEST_F(HmacAesDecryptorTest, MultipleKeysAndFrames) { | |
200 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
201 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
202 frame.key, frame.key_size); | |
203 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; | |
204 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, | |
205 frame2.key, frame2.key_size); | |
206 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
207 frame.encrypted_data_size, | |
208 frame.plain_text, | |
209 frame.plain_text_size, | |
210 frame.key_id, | |
211 frame.key_id_size)); | |
212 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame2.encrypted_data, | |
213 frame2.encrypted_data_size, | |
214 frame2.plain_text, | |
215 frame2.plain_text_size, | |
216 frame2.key_id, | |
217 frame2.key_id_size)); | |
218 } | |
219 | |
220 TEST_F(HmacAesDecryptorTest, HmacCheckFailure) { | |
221 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
222 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
223 frame.key, frame.key_size); | |
224 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidHmac, | |
225 frame.encrypted_data_size, | |
226 frame.plain_text, | |
227 frame.plain_text_size, | |
228 frame.key_id, | |
229 frame.key_id_size)); | |
230 } | |
231 | |
232 TEST_F(HmacAesDecryptorTest, IvCheckFailure) { | |
233 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
234 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
235 frame.key, frame.key_size); | |
236 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidIv, | |
237 frame.encrypted_data_size, | |
238 frame.plain_text, | |
239 frame.plain_text_size, | |
240 frame.key_id, | |
241 frame.key_id_size)); | |
242 } | |
243 | |
244 TEST_F(HmacAesDecryptorTest, DataCheckFailure) { | |
245 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
246 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
247 frame.key, frame.key_size); | |
248 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidData, | |
249 frame.encrypted_data_size, | |
250 frame.plain_text, | |
251 frame.plain_text_size, | |
252 frame.key_id, | |
253 frame.key_id_size)); | |
254 } | |
255 | |
256 } // media | |
OLD | NEW |