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

Unified Diff: media/crypto/aes_decryptor.cc

Issue 10651006: Add Common Encryption support to BMFF, including subsample decryption. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add wrong subsample size test Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: media/crypto/aes_decryptor.cc
diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc
index 129bc330131585c2a77a66dc7ab8b96fb96c76e6..8910d278945e5bd8d149c7003705e450428c5ff1 100644
--- a/media/crypto/aes_decryptor.cc
+++ b/media/crypto/aes_decryptor.cc
@@ -16,11 +16,24 @@
namespace media {
-// TODO(xhwang): Get real IV from frames.
-static const char kInitialCounter[] = "0000000000000000";
-
uint32 AesDecryptor::next_session_id_ = 1;
+static void CopySubsamples(const std::vector<SubsampleEntry>& subsamples,
+ const bool src_contains_clear_bytes,
ddorwin 2012/07/17 01:14:21 Consider an enum since it's not clear that false m
strobe_ 2012/07/19 02:43:35 Done.
+ const uint8* src, uint8* dst) {
ddorwin 2012/07/17 01:14:21 same line only for call sites, not defn/decl.
strobe_ 2012/07/19 02:43:35 Done.
+ for (size_t i = 0; i < subsamples.size(); i++) {
+ const SubsampleEntry& subsample = subsamples[i];
+ if (src_contains_clear_bytes) {
+ src += subsample.clear_bytes;
+ } else {
+ dst += subsample.clear_bytes;
+ }
+ memcpy(dst, src, subsample.cypher_bytes);
ddorwin 2012/07/17 01:14:21 Should we verify we don't exceed either buffer siz
strobe_ 2012/07/19 02:43:35 Since this is a static internal helper function, i
+ src += subsample.cypher_bytes;
+ dst += subsample.cypher_bytes;
+ }
+}
+
// Decrypt |input| using |key|.
// Return a DecoderBuffer with the decrypted data if decryption succeeded.
// Return NULL if decryption failed.
@@ -31,10 +44,61 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input,
// Initialize encryption data.
// The IV must be exactly as long as the cipher block size.
+ const std::string& iv = input.GetDecryptConfig()->iv();
crypto::Encryptor encryptor;
- if (!encryptor.Init(key, crypto::Encryptor::CBC, kInitialCounter)) {
- DVLOG(1) << "Could not initialize encryptor.";
- return NULL;
+ if (input.GetDecryptConfig()->use_cbc()) {
+ if (!encryptor.Init(key, crypto::Encryptor::CBC, iv)) {
+ DVLOG(1) << "Could not initialize encryptor.";
+ return NULL;
+ }
+ } else {
+ if (!encryptor.Init(key, crypto::Encryptor::CTR, base::StringPiece()) ||
+ !encryptor.SetCounter(iv)) {
+ DVLOG(1) << "Could not initialize encryptor.";
+ return NULL;
+ }
+ }
+
+ if (!input.GetDecryptConfig()->subsamples().empty()) {
ddorwin 2012/07/17 01:14:21 Prefer positive logic (unless there's a good reaso
strobe_ 2012/07/19 02:43:35 Done.
+ const std::vector<SubsampleEntry>& subsamples =
+ input.GetDecryptConfig()->subsamples();
+
+ int total_clear_size = 0;
+ int total_encrypted_size = 0;
+ for (size_t i = 0; i < subsamples.size(); i++) {
+ total_clear_size += subsamples[i].clear_bytes;
+ total_encrypted_size += subsamples[i].cypher_bytes;
+ }
+ if (total_clear_size + total_encrypted_size != input.GetDataSize()) {
+ DVLOG(1) << "Subsample sizes do not equal input size";
+ return NULL;
+ }
+
+ // The encrypted portions of all subsamples must form a contiguous block,
+ // such that an encrypted subsample that ends away from a block boundary is
+ // immediately followed by the start of the next encrypted subsample. We
+ // copy all encrypted subsamples to a contiguous buffer, decrypt them, then
+ // copy the decrypted bytes over the encrypted bytes in the output.
+ // TODO(strobe): attempt to reduce number of memory copies
+ scoped_array<uint8> encrypted_bytes(
+ new uint8[total_encrypted_size]);
+ CopySubsamples(subsamples, true, input.GetData(), encrypted_bytes.get());
+
+ std::string decrypted_text;
+ base::StringPiece encrypted_text(
+ reinterpret_cast<const char*>(encrypted_bytes.get()),
+ total_encrypted_size);
+ if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) {
+ DVLOG(1) << "Could not decrypt data.";
+ return NULL;
+ }
+
+ scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom(
+ input.GetData(), input.GetDataSize());
+ CopySubsamples(subsamples, false,
+ reinterpret_cast<const uint8*>(decrypted_text.data()),
+ output->GetWritableData());
+ return output;
}
std::string decrypted_text;

Powered by Google App Engine
This is Rietveld 408576698