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

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

Issue 10823110: Add support for v0.3 of the encrypted WebM specification. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing comments from Patch Set 3. Created 8 years, 4 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 | Annotate | Revision Log
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 #include <vector> 6 #include <vector>
7 7
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/sys_byteorder.h" 10 #include "base/sys_byteorder.h"
(...skipping 23 matching lines...) Expand all
34 int key_id_size; 34 int key_id_size;
35 uint8 key[32]; 35 uint8 key[32];
36 int key_size; 36 int key_size;
37 uint8 encrypted_data[64]; 37 uint8 encrypted_data[64];
38 int encrypted_data_size; 38 int encrypted_data_size;
39 }; 39 };
40 40
41 static const char kClearKeySystem[] = "org.w3.clearkey"; 41 static const char kClearKeySystem[] = "org.w3.clearkey";
42 42
43 // Frames 0 & 1 are encrypted with the same key. Frame 2 is encrypted with a 43 // Frames 0 & 1 are encrypted with the same key. Frame 2 is encrypted with a
44 // different key. 44 // different key. Frame 3 has the same HMAC key as frame 2, but frame 3 is
45 // unencrypted.
45 const WebmEncryptedData kWebmEncryptedFrames[] = { 46 const WebmEncryptedData kWebmEncryptedFrames[] = {
46 { 47 {
47 // plaintext 48 // plaintext
48 "Original data.", 14, 49 "Original data.", 14,
49 // key_id 50 // key_id
50 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 51 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
51 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 52 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
52 0x10, 0x11, 0x12, 0x13 53 0x10, 0x11, 0x12, 0x13
53 }, 20, 54 }, 20,
54 // key 55 // key
55 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 56 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
56 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 57 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
57 }, 16, 58 }, 16,
58 // encrypted_data 59 // encrypted_data
59 { 0xfb, 0xe7, 0x1d, 0xbb, 0x4c, 0x23, 0xce, 0xba, 60 { 0x3c, 0x4e, 0xb8, 0xd9, 0x5c, 0x20, 0x48, 0x18,
60 0xcc, 0xf8, 0xda, 0xc0, 0xff, 0xff, 0xff, 0xff, 61 0x4f, 0x03, 0x74, 0xa1, 0x01, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff, 0xb7, 62 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff,
62 0x74, 0x02, 0x4e, 0x1c, 0x75, 0x3d, 0xee, 0xcb, 63 0xb7, 0x74, 0x02, 0x4e, 0x1c, 0x75, 0x3d, 0xee,
63 0x64, 0xf7 64 0xcb, 0x64, 0xf7
64 }, 34 65 }, 35
65 }, 66 },
66 { 67 {
67 // plaintext 68 // plaintext
68 "Changed Original data.", 22, 69 "Changed Original data.", 22,
69 // key_id 70 // key_id
70 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 71 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
71 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 72 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
72 0x10, 0x11, 0x12, 0x13 73 0x10, 0x11, 0x12, 0x13
73 }, 20, 74 }, 20,
74 // key 75 // key
75 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 76 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
76 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23 77 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23
77 }, 16, 78 }, 16,
78 // encrypted_data 79 // encrypted_data
79 { 0x43, 0xe4, 0x78, 0x7a, 0x43, 0xe1, 0x49, 0xbb, 80 { 0xe8, 0x4c, 0x51, 0x33, 0x14, 0x0d, 0xc7, 0x17,
80 0x44, 0x38, 0xdf, 0xfc, 0x00, 0x00, 0x00, 0x00, 81 0x32, 0x60, 0xc9, 0xd0, 0x01, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0xec, 0x8e, 0x87, 0x21, 82 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x8e, 0x87,
82 0xd3, 0xb9, 0x1c, 0x61, 0xf6, 0x5a, 0x60, 0xaa, 83 0x21, 0xd3, 0xb9, 0x1c, 0x61, 0xf6, 0x5a, 0x60,
83 0x07, 0x0e, 0x96, 0xd0, 0x54, 0x5d, 0x35, 0x9a, 84 0xaa, 0x07, 0x0e, 0x96, 0xd0, 0x54, 0x5d, 0x35,
84 0x4a, 0xd3 85 0x9a, 0x4a, 0xd3
85 }, 42 86 }, 43
86 }, 87 },
87 { 88 {
88 // plaintext 89 // plaintext
89 "Original data.", 14, 90 "Original data.", 14,
90 // key_id 91 // key_id
91 { 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 92 { 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
92 0x2c, 0x2d, 0x2e, 0x2f, 0x30 93 0x2c, 0x2d, 0x2e, 0x2f, 0x30
93 }, 13, 94 }, 13,
94 // key 95 // key
95 { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 96 { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
96 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40 97 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40
97 }, 16, 98 }, 16,
98 // encrypted_data 99 // encrypted_data
99 { 0xd9, 0x43, 0x30, 0xfd, 0x82, 0x77, 0x62, 0x04, 100 { 0x46, 0x93, 0x8c, 0x93, 0x48, 0xf9, 0xeb, 0x30,
100 0x08, 0xc2, 0x48, 0x89, 0x00, 0x00, 0x00, 0x00, 101 0x74, 0x55, 0x6b, 0xf2, 0x01, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x01, 0x48, 0x5e, 0x4a, 0x41, 102 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x5e, 0x4a,
102 0x2a, 0x8b, 0xf4, 0xc6, 0x47, 0x54, 0x90, 0x34, 103 0x41, 0x2a, 0x8b, 0xf4, 0xc6, 0x47, 0x54, 0x90,
103 0xf4, 0x8b 104 0x34, 0xf4, 0x8b
104 }, 34 105 }, 35
106 },
107 {
108 // plaintext
109 "Changed Original data.", 22,
110 // key_id
111 { 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
112 0x2c, 0x2d, 0x2e, 0x2f, 0x30
113 }, 13,
114 // key
115 { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
116 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40
117 }, 16,
118 // encrypted_data
119 { 0xee, 0xd6, 0xf5, 0x64, 0x5f, 0xe0, 0x6a, 0xa2,
120 0x9e, 0xd6, 0xce, 0x34, 0x00, 0x43, 0x68, 0x61,
121 0x6e, 0x67, 0x65, 0x64, 0x20, 0x4f, 0x72, 0x69,
122 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x64, 0x61,
123 0x74, 0x61, 0x2e
124 }, 35
105 } 125 }
106 }; 126 };
107 127
108 static const uint8 kWebmWrongKey[] = { 128 static const uint8 kWebmWrongKey[] = {
109 0x49, 0x27, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x72, 129 0x49, 0x27, 0x6d, 0x20, 0x61, 0x20, 0x77, 0x72,
110 0x6f, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x2e 130 0x6f, 0x6e, 0x67, 0x20, 0x6b, 0x65, 0x79, 0x2e
111 }; 131 };
112 static const uint8 kWebmWrongSizedKey[] = { 0x20, 0x20 }; 132 static const uint8 kWebmWrongSizedKey[] = { 0x20, 0x20 };
113 133
114 // This is the encrypted data from frame 0 of |kWebmEncryptedFrames| except 134 // This is the encrypted data from frame 0 of |kWebmEncryptedFrames| except
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 219
200 // Set block counter to all 0's. 220 // Set block counter to all 0's.
201 memset(counter_block_data + iv_size, 0, kDecryptionKeySize - iv_size); 221 memset(counter_block_data + iv_size, 0, kDecryptionKeySize - iv_size);
202 222
203 return std::string(counter_block_data, kDecryptionKeySize); 223 return std::string(counter_block_data, kDecryptionKeySize);
204 } 224 }
205 225
206 // Creates a WebM encrypted buffer that the demuxer would pass to the 226 // Creates a WebM encrypted buffer that the demuxer would pass to the
207 // decryptor. |data| is the payload of a WebM encrypted Block. |key_id| is 227 // decryptor. |data| is the payload of a WebM encrypted Block. |key_id| is
208 // initialization data from the WebM file. Every encrypted Block has 228 // initialization data from the WebM file. Every encrypted Block has
209 // an HMAC and IV prepended to an encrypted frame. Current encrypted WebM 229 // an HMAC and a signal byte prepended to a frame. If the frame is encrypted
210 // request for comments specification is here 230 // then an IV is prepended to the Block. Current encrypted WebM request for
231 // comments specification is here
211 // http://wiki.webmproject.org/encryption/webm-encryption-rfc 232 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
212 static scoped_refptr<DecoderBuffer> CreateWebMEncryptedBuffer( 233 static scoped_refptr<DecoderBuffer> CreateWebMEncryptedBuffer(
213 const uint8* data, int data_size, 234 const uint8* data, int data_size,
214 const uint8* key_id, int key_id_size) { 235 const uint8* key_id, int key_id_size) {
215 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( 236 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom(
216 data + kWebMHmacSize, data_size - kWebMHmacSize); 237 data + kWebMHmacSize, data_size - kWebMHmacSize);
217 CHECK(encrypted_buffer); 238 CHECK(encrypted_buffer);
218 239
219 uint64 network_iv; 240 int data_offset = 1;
220 memcpy(&network_iv, data + kWebMHmacSize, sizeof(network_iv)); 241 uint8 signal_byte = data[kWebMHmacSize];
xhwang 2012/08/01 04:38:23 Move definition of "data_offset" here: int data_of
fgalligan1 2012/08/01 15:07:38 Done.
221 const uint64 iv = base::NetToHost64(network_iv); 242
222 std::string webm_iv = 243 // Setting the DecryptConfig object of the buffer while leaving the
223 GenerateCounterBlock(reinterpret_cast<const uint8*>(&iv), sizeof(iv)); 244 // initialization vector empty will tell the decryptor that the frame is
245 // unencrypted but integrity should still be checked.
246 std::string counter_block_str;
247
248 if (signal_byte & kWebMFlagEncryptedFrame) {
249 uint64 network_iv;
250 memcpy(&network_iv, data + kWebMHmacSize + data_offset, sizeof(network_iv));
251 const uint64 iv = base::NetToHost64(network_iv);
252 counter_block_str =
253 GenerateCounterBlock(reinterpret_cast<const uint8*>(&iv), sizeof(iv));
254 data_offset += sizeof(iv);
255 }
256
224 encrypted_buffer->SetDecryptConfig( 257 encrypted_buffer->SetDecryptConfig(
225 scoped_ptr<DecryptConfig>(new DecryptConfig( 258 scoped_ptr<DecryptConfig>(new DecryptConfig(
226 std::string(reinterpret_cast<const char*>(key_id), key_id_size), 259 std::string(reinterpret_cast<const char*>(key_id), key_id_size),
227 webm_iv, 260 counter_block_str,
228 std::string(reinterpret_cast<const char*>(data), kWebMHmacSize), 261 std::string(reinterpret_cast<const char*>(data), kWebMHmacSize),
229 sizeof(iv), 262 data_offset,
230 std::vector<SubsampleEntry>()))); 263 std::vector<SubsampleEntry>())));
231 return encrypted_buffer; 264 return encrypted_buffer;
232 } 265 }
233 266
234 static scoped_refptr<DecoderBuffer> CreateSubsampleEncryptedBuffer( 267 static scoped_refptr<DecoderBuffer> CreateSubsampleEncryptedBuffer(
235 const uint8* data, int data_size, 268 const uint8* data, int data_size,
236 const uint8* key_id, int key_id_size, 269 const uint8* key_id, int key_id_size,
237 const uint8* iv, int iv_size, 270 const uint8* iv, int iv_size,
238 int data_offset, 271 int data_offset,
239 const std::vector<SubsampleEntry>& subsample_entries) { 272 const std::vector<SubsampleEntry>& subsample_entries) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 frame.key, frame.key_size); 350 frame.key, frame.key_size);
318 scoped_refptr<DecoderBuffer> encrypted_data = 351 scoped_refptr<DecoderBuffer> encrypted_data =
319 CreateWebMEncryptedBuffer(frame.encrypted_data, 352 CreateWebMEncryptedBuffer(frame.encrypted_data,
320 frame.encrypted_data_size, 353 frame.encrypted_data_size,
321 frame.key_id, frame.key_id_size); 354 frame.key_id, frame.key_id_size);
322 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data, 355 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data,
323 frame.plain_text, 356 frame.plain_text,
324 frame.plain_text_size)); 357 frame.plain_text_size));
325 } 358 }
326 359
360 TEST_F(AesDecryptorTest, UnencryptedFrameWebMDecryption) {
361 const WebmEncryptedData& frame = kWebmEncryptedFrames[3];
362 GenerateKeyRequest(frame.key_id, frame.key_id_size);
363 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size,
364 frame.key, frame.key_size);
365 scoped_refptr<DecoderBuffer> encrypted_data =
366 CreateWebMEncryptedBuffer(frame.encrypted_data,
367 frame.encrypted_data_size,
368 frame.key_id, frame.key_id_size);
369 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data,
370 frame.plain_text,
371 frame.plain_text_size));
372 }
373
327 TEST_F(AesDecryptorTest, WrongKey) { 374 TEST_F(AesDecryptorTest, WrongKey) {
328 const WebmEncryptedData& frame = kWebmEncryptedFrames[0]; 375 const WebmEncryptedData& frame = kWebmEncryptedFrames[0];
329 GenerateKeyRequest(frame.key_id, frame.key_id_size); 376 GenerateKeyRequest(frame.key_id, frame.key_id_size);
330 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size, 377 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size,
331 kWebmWrongKey, arraysize(kWebmWrongKey)); 378 kWebmWrongKey, arraysize(kWebmWrongKey));
332 scoped_refptr<DecoderBuffer> encrypted_data = 379 scoped_refptr<DecoderBuffer> encrypted_data =
333 CreateWebMEncryptedBuffer(frame.encrypted_data, 380 CreateWebMEncryptedBuffer(frame.encrypted_data,
334 frame.encrypted_data_size, 381 frame.encrypted_data_size,
335 frame.key_id, frame.key_id_size); 382 frame.key_id, frame.key_id_size);
336 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data)); 383 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data));
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 scoped_refptr<DecoderBuffer> encrypted_data = CreateSubsampleEncryptedBuffer( 535 scoped_refptr<DecoderBuffer> encrypted_data = CreateSubsampleEncryptedBuffer(
489 kSubsampleData, arraysize(kSubsampleData), 536 kSubsampleData, arraysize(kSubsampleData),
490 kSubsampleKeyId, arraysize(kSubsampleKeyId), 537 kSubsampleKeyId, arraysize(kSubsampleKeyId),
491 kSubsampleIv, arraysize(kSubsampleIv), 538 kSubsampleIv, arraysize(kSubsampleIv),
492 0, 539 0,
493 entries); 540 entries);
494 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data)); 541 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data));
495 } 542 }
496 543
497 } // namespace media 544 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698