summaryrefslogtreecommitdiffstats
path: root/media/webm/webm_cluster_parser.cc
diff options
context:
space:
mode:
authorfgalligan@chromium.org <fgalligan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 14:54:10 +0000
committerfgalligan@chromium.org <fgalligan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-20 14:54:10 +0000
commitd55917908e06bf543c941bf0f6e0f2648eeeece8 (patch)
tree0d236b71de8ddc0d0b33a66e83aadcd5f4e1dae3 /media/webm/webm_cluster_parser.cc
parenta858c9222754f3eb210d6e7e8a31c657be653b54 (diff)
downloadchromium_src-d55917908e06bf543c941bf0f6e0f2648eeeece8.zip
chromium_src-d55917908e06bf543c941bf0f6e0f2648eeeece8.tar.gz
chromium_src-d55917908e06bf543c941bf0f6e0f2648eeeece8.tar.bz2
Add support for encrypted WebM files as defined in the RFC.
The WebM parser now reads the HMAC and IV from every encrypted Block and stores that information in the DecryptorConfig object. Added two new elements ContentEncAESSettings and AESSettingsCipherMode used by encrypted WebM files. This is a new code review of https://chromiumcodereview.appspot.com/10535029/ patch set 17 after patch set 16 was reverted. BUG=119845 TEST=media_unittests Review URL: https://chromiumcodereview.appspot.com/10810026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147654 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/webm/webm_cluster_parser.cc')
-rw-r--r--media/webm/webm_cluster_parser.cc43
1 files changed, 40 insertions, 3 deletions
diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc
index c5a2fdc..20d131e 100644
--- a/media/webm/webm_cluster_parser.cc
+++ b/media/webm/webm_cluster_parser.cc
@@ -5,12 +5,31 @@
#include "media/webm/webm_cluster_parser.h"
#include "base/logging.h"
+#include "base/sys_byteorder.h"
#include "media/base/data_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/webm/webm_constants.h"
namespace media {
+// Generates a 16 byte CTR counter block. The CTR counter block format is a
+// CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV.
+// Always returns a valid pointer to a buffer of kDecryptionKeySize bytes.
+static scoped_array<uint8> GenerateCounterBlock(uint64 iv) {
+ scoped_array<uint8> counter_block_data(
+ new uint8[DecryptConfig::kDecryptionKeySize]);
+
+ // Set the IV.
+ memcpy(counter_block_data.get(), &iv, sizeof(iv));
+
+ // Set block counter to all 0's.
+ memset(counter_block_data.get() + sizeof(iv),
+ 0,
+ DecryptConfig::kDecryptionKeySize - sizeof(iv));
+
+ return counter_block_data.Pass();
+}
+
WebMClusterParser::WebMClusterParser(int64 timecode_scale,
int audio_track_num,
int video_track_num,
@@ -193,15 +212,33 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode,
base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
(cluster_timecode_ + timecode) * timecode_multiplier_);
+ // Every encrypted Block has an HMAC and IV prepended to it. Current encrypted
+ // WebM request for comments specification is here
+ // http://wiki.webmproject.org/encryption/webm-encryption-rfc
+ bool encrypted = track_num == video_.track_num() &&
+ video_encryption_key_id_.get();
+ // If encrypted skip past the HMAC. Encrypted buffers must include the IV and
+ // the encrypted frame because the decryptor will verify this data before
+ // decryption. The HMAC and IV will be copied into DecryptConfig.
+ int offset = (encrypted) ? kWebMHmacSize : 0;
+
// The first bit of the flags is set when the block contains only keyframes.
// http://www.matroska.org/technical/specs/index.html
bool is_keyframe = (flags & 0x80) != 0;
scoped_refptr<StreamParserBuffer> buffer =
- StreamParserBuffer::CopyFrom(data, size, is_keyframe);
+ StreamParserBuffer::CopyFrom(data + offset, size - offset, is_keyframe);
+
+ if (encrypted) {
+ uint64 network_iv;
+ memcpy(&network_iv, data + kWebMHmacSize, sizeof(network_iv));
+ const uint64 iv = base::NetToHost64(network_iv);
- if (track_num == video_.track_num() && video_encryption_key_id_.get()) {
+ scoped_array<uint8> counter_block(GenerateCounterBlock(iv));
buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
- video_encryption_key_id_.get(), video_encryption_key_id_size_)));
+ video_encryption_key_id_.get(), video_encryption_key_id_size_,
+ counter_block.get(), DecryptConfig::kDecryptionKeySize,
+ data, kWebMHmacSize,
+ sizeof(iv))));
}
buffer->SetTimestamp(timestamp);