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

Unified Diff: chromecast/media/cma/pipeline/decrypt_util.cc

Issue 741863002: Chromecast: adds a media pipeline feeding data to CMA device backends. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cma-cdm
Patch Set: address nits, merge Pause/Flush Created 6 years, 1 month 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
« no previous file with comments | « chromecast/media/cma/pipeline/decrypt_util.h ('k') | chromecast/media/cma/pipeline/load_type.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromecast/media/cma/pipeline/decrypt_util.cc
diff --git a/chromecast/media/cma/pipeline/decrypt_util.cc b/chromecast/media/cma/pipeline/decrypt_util.cc
new file mode 100644
index 0000000000000000000000000000000000000000..04d5a472a2fae4102260565111936ca8730e73be
--- /dev/null
+++ b/chromecast/media/cma/pipeline/decrypt_util.cc
@@ -0,0 +1,128 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/pipeline/decrypt_util.h"
+
+#include <openssl/aes.h>
+#include <string>
+
+#include "base/logging.h"
+#include "chromecast/media/cma/base/decoder_buffer_base.h"
+#include "crypto/symmetric_key.h"
+#include "media/base/decrypt_config.h"
+
+namespace chromecast {
+namespace media {
+
+namespace {
+
+class DecoderBufferClear : public DecoderBufferBase {
+ public:
+ explicit DecoderBufferClear(const scoped_refptr<DecoderBufferBase>& buffer);
+
+ // DecoderBufferBase implementation.
+ base::TimeDelta timestamp() const override;
+ const uint8* data() const override;
+ uint8* writable_data() const override;
+ int data_size() const override;
+ const ::media::DecryptConfig* decrypt_config() const override;
+ bool end_of_stream() const override;
+
+ private:
+ virtual ~DecoderBufferClear();
+
+ scoped_refptr<DecoderBufferBase> const buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(DecoderBufferClear);
+};
+
+DecoderBufferClear::DecoderBufferClear(
+ const scoped_refptr<DecoderBufferBase>& buffer)
+ : buffer_(buffer) {
+}
+
+DecoderBufferClear::~DecoderBufferClear() {
+}
+
+base::TimeDelta DecoderBufferClear::timestamp() const {
+ return buffer_->timestamp();
+}
+
+const uint8* DecoderBufferClear::data() const {
+ return buffer_->data();
+}
+
+uint8* DecoderBufferClear::writable_data() const {
+ return buffer_->writable_data();
+}
+
+int DecoderBufferClear::data_size() const {
+ return buffer_->data_size();
+}
+
+const ::media::DecryptConfig* DecoderBufferClear::decrypt_config() const {
+ // Buffer is clear so no decryption info.
+ return NULL;
+}
+
+bool DecoderBufferClear::end_of_stream() const {
+ return buffer_->end_of_stream();
+}
+
+} // namespace
+
+scoped_refptr<DecoderBufferBase> DecryptDecoderBuffer(
+ const scoped_refptr<DecoderBufferBase>& buffer,
+ crypto::SymmetricKey* key) {
+ if (buffer->end_of_stream())
+ return buffer;
+
+ const ::media::DecryptConfig* decrypt_config = buffer->decrypt_config();
+ if (!decrypt_config || decrypt_config->iv().size() == 0)
+ return buffer;
+
+ // Get the key.
+ std::string raw_key;
+ if (!key->GetRawKey(&raw_key)) {
+ LOG(ERROR) << "Failed to get the underlying AES key";
+ return buffer;
+ }
+ DCHECK_EQ(static_cast<int>(raw_key.length()), AES_BLOCK_SIZE);
+ const uint8* key_u8 = reinterpret_cast<const uint8*>(raw_key.data());
+ AES_KEY aes_key;
+ if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) {
+ LOG(ERROR) << "Failed to set the AES key";
+ return buffer;
+ }
+
+ // Get the IV.
+ uint8 aes_iv[AES_BLOCK_SIZE];
+ DCHECK_EQ(static_cast<int>(decrypt_config->iv().length()),
+ AES_BLOCK_SIZE);
+ memcpy(aes_iv, decrypt_config->iv().data(), AES_BLOCK_SIZE);
+
+ // Decryption state.
+ unsigned int encrypted_byte_offset = 0;
+ uint8 ecount_buf[AES_BLOCK_SIZE];
+
+ // Perform the decryption.
+ const std::vector< ::media::SubsampleEntry>& subsamples =
+ decrypt_config->subsamples();
+ uint8* data = buffer->writable_data();
+ uint32 offset = 0;
+ for (size_t k = 0; k < subsamples.size(); k++) {
+ offset += subsamples[k].clear_bytes;
+ uint32 cypher_bytes = subsamples[k].cypher_bytes;
+ CHECK_LE(offset + cypher_bytes, buffer->data_size());
+ AES_ctr128_encrypt(
+ data + offset, data + offset, cypher_bytes, &aes_key,
+ aes_iv, ecount_buf, &encrypted_byte_offset);
+ offset += cypher_bytes;
+ }
+
+ return scoped_refptr<DecoderBufferBase>(new DecoderBufferClear(buffer));
+}
+
+} // namespace media
+} // namespace chromecast
« no previous file with comments | « chromecast/media/cma/pipeline/decrypt_util.h ('k') | chromecast/media/cma/pipeline/load_type.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698