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

Side by Side Diff: media/webm/webm_cluster_parser.cc

Issue 11139008: Change WebM parser to treat IVs from encrypted WebM as raw data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing comments. Created 8 years, 2 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 "media/webm/webm_cluster_parser.h" 5 #include "media/webm/webm_cluster_parser.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/sys_byteorder.h"
11 #include "media/base/data_buffer.h" 10 #include "media/base/data_buffer.h"
12 #include "media/base/decrypt_config.h" 11 #include "media/base/decrypt_config.h"
13 #include "media/webm/webm_constants.h" 12 #include "media/webm/webm_constants.h"
14 13
15 namespace media { 14 namespace media {
16 15
17 // Generates a 16 byte CTR counter block. The CTR counter block format is a 16 // Generates a 16 byte CTR counter block. The CTR counter block format is a
xhwang 2012/10/15 16:39:00 With |iv_size|, update this comment?
fgalligan1 2012/10/15 20:01:07 Done.
18 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV. 17 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV.
19 // Returns a string of kDecryptionKeySize bytes. 18 // Returns a string of kDecryptionKeySize bytes.
20 static std::string GenerateCounterBlock(uint64 iv) { 19 static std::string GenerateCounterBlock(const uint8* iv, size_t iv_size) {
21 std::string counter_block(reinterpret_cast<char*>(&iv), sizeof(iv)); 20 std::string counter_block(reinterpret_cast<const char*>(iv), iv_size);
22 counter_block.append(DecryptConfig::kDecryptionKeySize - sizeof(iv), 0); 21 counter_block.append(DecryptConfig::kDecryptionKeySize - iv_size, 0);
23 return counter_block; 22 return counter_block;
24 } 23 }
25 24
26 WebMClusterParser::WebMClusterParser(int64 timecode_scale, 25 WebMClusterParser::WebMClusterParser(int64 timecode_scale,
27 int audio_track_num, 26 int audio_track_num,
28 int video_track_num, 27 int video_track_num,
29 const std::string& audio_encryption_key_id, 28 const std::string& audio_encryption_key_id,
30 const std::string& video_encryption_key_id) 29 const std::string& video_encryption_key_id)
31 : timecode_multiplier_(timecode_scale / 1000.0), 30 : timecode_multiplier_(timecode_scale / 1000.0),
32 audio_encryption_key_id_(audio_encryption_key_id), 31 audio_encryption_key_id_(audio_encryption_key_id),
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 block_data_.reset(new uint8[size]); 177 block_data_.reset(new uint8[size]);
179 memcpy(block_data_.get(), data, size); 178 memcpy(block_data_.get(), data, size);
180 block_data_size_ = size; 179 block_data_size_ = size;
181 return true; 180 return true;
182 } 181 }
183 182
184 bool WebMClusterParser::OnBlock(int track_num, int timecode, 183 bool WebMClusterParser::OnBlock(int track_num, int timecode,
185 int block_duration, 184 int block_duration,
186 int flags, 185 int flags,
187 const uint8* data, int size) { 186 const uint8* data, int size) {
187 DCHECK_GT(size, -1);
ddorwin 2012/10/15 02:32:49 DCHECK_GE(size, 0); seems better
fgalligan1 2012/10/15 16:20:27 Done.
188 if (cluster_timecode_ == -1) { 188 if (cluster_timecode_ == -1) {
189 DVLOG(1) << "Got a block before cluster timecode."; 189 DVLOG(1) << "Got a block before cluster timecode.";
190 return false; 190 return false;
191 } 191 }
192 192
193 if (timecode < 0) { 193 if (timecode < 0) {
194 DVLOG(1) << "Got a block with negative timecode offset " << timecode; 194 DVLOG(1) << "Got a block with negative timecode offset " << timecode;
195 return false; 195 return false;
196 } 196 }
197 197
(...skipping 23 matching lines...) Expand all
221 // The first bit of the flags is set when the block contains only keyframes. 221 // The first bit of the flags is set when the block contains only keyframes.
222 // http://www.matroska.org/technical/specs/index.html 222 // http://www.matroska.org/technical/specs/index.html
223 bool is_keyframe = (flags & 0x80) != 0; 223 bool is_keyframe = (flags & 0x80) != 0;
224 scoped_refptr<StreamParserBuffer> buffer = 224 scoped_refptr<StreamParserBuffer> buffer =
225 StreamParserBuffer::CopyFrom(data, size, is_keyframe); 225 StreamParserBuffer::CopyFrom(data, size, is_keyframe);
226 226
227 // Every encrypted Block has a signal byte and IV prepended to it. Current 227 // Every encrypted Block has a signal byte and IV prepended to it. Current
228 // encrypted WebM request for comments specification is here 228 // encrypted WebM request for comments specification is here
229 // http://wiki.webmproject.org/encryption/webm-encryption-rfc 229 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
230 if (!encryption_key_id.empty()) { 230 if (!encryption_key_id.empty()) {
231 if (static_cast<size_t>(size) < sizeof(uint8)) {
232 DVLOG(1) << "Got an encrypted block with no data.";
ddorwin 2012/10/15 02:32:49 It's not yet "encrypted", right?
fgalligan1 2012/10/15 16:20:27 No. I changed it too "Got a block from an encrypte
233 return false;
234 }
231 uint8 signal_byte = data[0]; 235 uint8 signal_byte = data[0];
232 int data_offset = sizeof(signal_byte); 236 int data_offset = sizeof(signal_byte);
233 237
234 // Setting the DecryptConfig object of the buffer while leaving the 238 // Setting the DecryptConfig object of the buffer while leaving the
235 // initialization vector empty will tell the decryptor that the frame is 239 // initialization vector empty will tell the decryptor that the frame is
236 // unencrypted. 240 // unencrypted.
237 std::string counter_block; 241 std::string counter_block;
238 242
239 if (signal_byte & kWebMFlagEncryptedFrame) { 243 if (signal_byte & kWebMFlagEncryptedFrame) {
240 uint64 network_iv; 244 if (static_cast<size_t>(size) < sizeof(signal_byte) + kWebMIvSize) {
241 memcpy(&network_iv, data + data_offset, sizeof(network_iv)); 245 DVLOG(1) << "Got an encrypted block with not enough data " << size;
242 data_offset += sizeof(network_iv); 246 return false;
243 counter_block = GenerateCounterBlock(base::NetToHost64(network_iv)); 247 }
248 counter_block = GenerateCounterBlock(data + data_offset, kWebMIvSize);
249 data_offset += kWebMIvSize;
244 } 250 }
245 251
246 // TODO(fgalligan): Revisit if DecryptConfig needs to be set on unencrypted 252 // TODO(fgalligan): Revisit if DecryptConfig needs to be set on unencrypted
247 // frames after the CDM API is finalized. 253 // frames after the CDM API is finalized.
248 // Unencrypted frames of potentially encrypted streams currently set 254 // Unencrypted frames of potentially encrypted streams currently set
249 // DecryptConfig. 255 // DecryptConfig.
250 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( 256 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
251 encryption_key_id, 257 encryption_key_id,
252 counter_block, 258 counter_block,
253 data_offset, 259 data_offset,
(...skipping 28 matching lines...) Expand all
282 288
283 buffers_.push_back(buffer); 289 buffers_.push_back(buffer);
284 return true; 290 return true;
285 } 291 }
286 292
287 void WebMClusterParser::Track::Reset() { 293 void WebMClusterParser::Track::Reset() {
288 buffers_.clear(); 294 buffers_.clear();
289 } 295 }
290 296
291 } // namespace media 297 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698