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

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 4. 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
« no previous file with comments | « media/crypto/aes_decryptor.cc ('k') | media/webm/webm_cluster_parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 { 1, 0 } 205 { 1, 0 }
186 }; 206 };
187 207
188 // Returns a 16 byte CTR counter block. The CTR counter block format is a 208 // Returns a 16 byte CTR counter block. The CTR counter block format is a
189 // CTR IV appended with a CTR block counter. |iv| is a CTR IV. |iv_size| is 209 // CTR IV appended with a CTR block counter. |iv| is a CTR IV. |iv_size| is
190 // the size of |iv| in bytes. 210 // the size of |iv| in bytes.
191 static std::string GenerateCounterBlock(const uint8* iv, int iv_size) { 211 static std::string GenerateCounterBlock(const uint8* iv, int iv_size) {
192 const int kDecryptionKeySize = 16; 212 const int kDecryptionKeySize = 16;
193 CHECK_GT(iv_size, 0); 213 CHECK_GT(iv_size, 0);
194 CHECK_LE(iv_size, kDecryptionKeySize); 214 CHECK_LE(iv_size, kDecryptionKeySize);
195 char counter_block_data[kDecryptionKeySize];
196 215
197 // Set the IV. 216 std::string counter_block(reinterpret_cast<const char*>(iv), iv_size);
198 memcpy(counter_block_data, iv, iv_size); 217 counter_block.append(kDecryptionKeySize - iv_size, 0);
199 218 return counter_block;
200 // Set block counter to all 0's.
201 memset(counter_block_data + iv_size, 0, kDecryptionKeySize - iv_size);
202
203 return std::string(counter_block_data, kDecryptionKeySize);
204 } 219 }
205 220
206 // Creates a WebM encrypted buffer that the demuxer would pass to the 221 // 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 222 // decryptor. |data| is the payload of a WebM encrypted Block. |key_id| is
208 // initialization data from the WebM file. Every encrypted Block has 223 // initialization data from the WebM file. Every encrypted Block has
209 // an HMAC and IV prepended to an encrypted frame. Current encrypted WebM 224 // an HMAC and a signal byte prepended to a frame. If the frame is encrypted
210 // request for comments specification is here 225 // then an IV is prepended to the Block. Current encrypted WebM request for
226 // comments specification is here
211 // http://wiki.webmproject.org/encryption/webm-encryption-rfc 227 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
212 static scoped_refptr<DecoderBuffer> CreateWebMEncryptedBuffer( 228 static scoped_refptr<DecoderBuffer> CreateWebMEncryptedBuffer(
213 const uint8* data, int data_size, 229 const uint8* data, int data_size,
214 const uint8* key_id, int key_id_size) { 230 const uint8* key_id, int key_id_size) {
215 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( 231 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom(
216 data + kWebMHmacSize, data_size - kWebMHmacSize); 232 data + kWebMHmacSize, data_size - kWebMHmacSize);
217 CHECK(encrypted_buffer); 233 CHECK(encrypted_buffer);
218 234
219 uint64 network_iv; 235 uint8 signal_byte = data[kWebMHmacSize];
220 memcpy(&network_iv, data + kWebMHmacSize, sizeof(network_iv)); 236 int data_offset = sizeof(signal_byte);
221 const uint64 iv = base::NetToHost64(network_iv); 237
222 std::string webm_iv = 238 // Setting the DecryptConfig object of the buffer while leaving the
223 GenerateCounterBlock(reinterpret_cast<const uint8*>(&iv), sizeof(iv)); 239 // initialization vector empty will tell the decryptor that the frame is
240 // unencrypted but integrity should still be checked.
241 std::string counter_block_str;
242
243 if (signal_byte & kWebMFlagEncryptedFrame) {
244 uint64 network_iv;
245 memcpy(&network_iv, data + kWebMHmacSize + data_offset, sizeof(network_iv));
246 const uint64 iv = base::NetToHost64(network_iv);
247 counter_block_str =
248 GenerateCounterBlock(reinterpret_cast<const uint8*>(&iv), sizeof(iv));
249 data_offset += sizeof(iv);
250 }
251
224 encrypted_buffer->SetDecryptConfig( 252 encrypted_buffer->SetDecryptConfig(
225 scoped_ptr<DecryptConfig>(new DecryptConfig( 253 scoped_ptr<DecryptConfig>(new DecryptConfig(
226 std::string(reinterpret_cast<const char*>(key_id), key_id_size), 254 std::string(reinterpret_cast<const char*>(key_id), key_id_size),
227 webm_iv, 255 counter_block_str,
228 std::string(reinterpret_cast<const char*>(data), kWebMHmacSize), 256 std::string(reinterpret_cast<const char*>(data), kWebMHmacSize),
229 sizeof(iv), 257 data_offset,
230 std::vector<SubsampleEntry>()))); 258 std::vector<SubsampleEntry>())));
231 return encrypted_buffer; 259 return encrypted_buffer;
232 } 260 }
233 261
234 static scoped_refptr<DecoderBuffer> CreateSubsampleEncryptedBuffer( 262 static scoped_refptr<DecoderBuffer> CreateSubsampleEncryptedBuffer(
235 const uint8* data, int data_size, 263 const uint8* data, int data_size,
236 const uint8* key_id, int key_id_size, 264 const uint8* key_id, int key_id_size,
237 const uint8* iv, int iv_size, 265 const uint8* iv, int iv_size,
238 int data_offset, 266 int data_offset,
239 const std::vector<SubsampleEntry>& subsample_entries) { 267 const std::vector<SubsampleEntry>& subsample_entries) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 frame.key, frame.key_size); 345 frame.key, frame.key_size);
318 scoped_refptr<DecoderBuffer> encrypted_data = 346 scoped_refptr<DecoderBuffer> encrypted_data =
319 CreateWebMEncryptedBuffer(frame.encrypted_data, 347 CreateWebMEncryptedBuffer(frame.encrypted_data,
320 frame.encrypted_data_size, 348 frame.encrypted_data_size,
321 frame.key_id, frame.key_id_size); 349 frame.key_id, frame.key_id_size);
322 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data, 350 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data,
323 frame.plain_text, 351 frame.plain_text,
324 frame.plain_text_size)); 352 frame.plain_text_size));
325 } 353 }
326 354
355 TEST_F(AesDecryptorTest, UnencryptedFrameWebMDecryption) {
356 const WebmEncryptedData& frame = kWebmEncryptedFrames[3];
357 GenerateKeyRequest(frame.key_id, frame.key_id_size);
358 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size,
359 frame.key, frame.key_size);
360 scoped_refptr<DecoderBuffer> encrypted_data =
361 CreateWebMEncryptedBuffer(frame.encrypted_data,
362 frame.encrypted_data_size,
363 frame.key_id, frame.key_id_size);
364 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(encrypted_data,
365 frame.plain_text,
366 frame.plain_text_size));
367 }
368
327 TEST_F(AesDecryptorTest, WrongKey) { 369 TEST_F(AesDecryptorTest, WrongKey) {
328 const WebmEncryptedData& frame = kWebmEncryptedFrames[0]; 370 const WebmEncryptedData& frame = kWebmEncryptedFrames[0];
329 GenerateKeyRequest(frame.key_id, frame.key_id_size); 371 GenerateKeyRequest(frame.key_id, frame.key_id_size);
330 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size, 372 AddKeyAndExpectToSucceed(frame.key_id, frame.key_id_size,
331 kWebmWrongKey, arraysize(kWebmWrongKey)); 373 kWebmWrongKey, arraysize(kWebmWrongKey));
332 scoped_refptr<DecoderBuffer> encrypted_data = 374 scoped_refptr<DecoderBuffer> encrypted_data =
333 CreateWebMEncryptedBuffer(frame.encrypted_data, 375 CreateWebMEncryptedBuffer(frame.encrypted_data,
334 frame.encrypted_data_size, 376 frame.encrypted_data_size,
335 frame.key_id, frame.key_id_size); 377 frame.key_id, frame.key_id_size);
336 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data)); 378 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( 530 scoped_refptr<DecoderBuffer> encrypted_data = CreateSubsampleEncryptedBuffer(
489 kSubsampleData, arraysize(kSubsampleData), 531 kSubsampleData, arraysize(kSubsampleData),
490 kSubsampleKeyId, arraysize(kSubsampleKeyId), 532 kSubsampleKeyId, arraysize(kSubsampleKeyId),
491 kSubsampleIv, arraysize(kSubsampleIv), 533 kSubsampleIv, arraysize(kSubsampleIv),
492 0, 534 0,
493 entries); 535 entries);
494 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data)); 536 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(encrypted_data));
495 } 537 }
496 538
497 } // namespace media 539 } // namespace media
OLDNEW
« no previous file with comments | « media/crypto/aes_decryptor.cc ('k') | media/webm/webm_cluster_parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698