diff options
author | fgalligan@chromium.org <fgalligan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-01 18:29:39 +0000 |
---|---|---|
committer | fgalligan@chromium.org <fgalligan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-01 18:29:39 +0000 |
commit | c80cc522094a835d11cc6975a72dfc96eb113293 (patch) | |
tree | be8e99f563f44eac8bb078f66346acd82c9af410 /media/webm | |
parent | 7436acd304fa1d500756562f54299b2601240f41 (diff) | |
download | chromium_src-c80cc522094a835d11cc6975a72dfc96eb113293.zip chromium_src-c80cc522094a835d11cc6975a72dfc96eb113293.tar.gz chromium_src-c80cc522094a835d11cc6975a72dfc96eb113293.tar.bz2 |
Add support for v0.3 of the encrypted WebM specification.
- Added code to handle the signal_byte contained within WebM
encrypted Blocks.
- Added a unittest to aes_decryptor to hanlde an encrypted WebM
Block with an unencrypted frame.
BUG=139876
TEST=Run media_unittests --gtest_filter=AesDecryptor* and all
tests must pass.
Review URL: https://chromiumcodereview.appspot.com/10823110
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149449 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/webm')
-rw-r--r-- | media/webm/webm_cluster_parser.cc | 61 | ||||
-rw-r--r-- | media/webm/webm_constants.h | 1 |
2 files changed, 33 insertions, 29 deletions
diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc index e9ef93e..7878fa8 100644 --- a/media/webm/webm_cluster_parser.cc +++ b/media/webm/webm_cluster_parser.cc @@ -14,20 +14,11 @@ 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(); +// Returns a string of kDecryptionKeySize bytes. +static std::string GenerateCounterBlock(uint64 iv) { + std::string counter_block(reinterpret_cast<char*>(&iv), sizeof(iv)); + counter_block.append(DecryptConfig::kDecryptionKeySize - sizeof(iv), 0); + return counter_block; } WebMClusterParser::WebMClusterParser(int64 timecode_scale, @@ -220,12 +211,14 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, // 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; + bool is_track_encrypted = track_num == video_.track_num() && + video_encryption_key_id_.get(); + + // If stream is encrypted skip past the HMAC. Encrypted buffers must include + // the signal byte, the IV (if frame is encrypted) and + // the frame because the decryptor will verify this data before decryption. + // The HMAC and IV will be copied into DecryptConfig. + int offset = (is_track_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 @@ -233,21 +226,31 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, scoped_refptr<StreamParserBuffer> buffer = 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 (is_track_encrypted) { + uint8 signal_byte = data[kWebMHmacSize]; + int data_offset = sizeof(signal_byte); + + // Setting the DecryptConfig object of the buffer while leaving the + // initialization vector empty will tell the decryptor that the frame is + // unencrypted but integrity should still be checked. + std::string counter_block; + + if (signal_byte & kWebMFlagEncryptedFrame) { + uint64 network_iv; + memcpy(&network_iv, data + kWebMHmacSize + data_offset, + sizeof(network_iv)); + const uint64 iv = base::NetToHost64(network_iv); + counter_block = GenerateCounterBlock(iv); + data_offset += sizeof(iv); + } - scoped_array<uint8> counter_block(GenerateCounterBlock(iv)); buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( std::string( reinterpret_cast<const char*>(video_encryption_key_id_.get()), video_encryption_key_id_size_), - std::string( - reinterpret_cast<const char*>(counter_block.get()), - DecryptConfig::kDecryptionKeySize), + counter_block, std::string(reinterpret_cast<const char*>(data), kWebMHmacSize), - sizeof(iv), + data_offset, std::vector<SubsampleEntry>()))); } diff --git a/media/webm/webm_constants.h b/media/webm/webm_constants.h index 93041b2..7d6f3ed 100644 --- a/media/webm/webm_constants.h +++ b/media/webm/webm_constants.h @@ -202,6 +202,7 @@ const uint8 kWebMFlagKeyframe = 0x80; // The size is from the WebM encrypted specification. Current encrypted WebM // request for comments specification is here // http://wiki.webmproject.org/encryption/webm-encryption-rfc +const uint8 kWebMFlagEncryptedFrame = 0x1; const int kWebMHmacSize = 12; } // namespace media |