[MediaRouter] Update MR-2-Extension's PostMessage to return boolean.
[chromium-blink-merge.git] / chromecast / media / cma / pipeline / decrypt_util.cc
blobabd466148a40ee463043d4df6928b58eb8388de7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/media/cma/pipeline/decrypt_util.h"
7 #include <openssl/aes.h>
8 #include <string>
10 #include "base/logging.h"
11 #include "chromecast/media/cma/base/decoder_buffer_base.h"
12 #include "crypto/symmetric_key.h"
13 #include "media/base/decrypt_config.h"
15 namespace chromecast {
16 namespace media {
18 namespace {
20 class DecoderBufferClear : public DecoderBufferBase {
21 public:
22 explicit DecoderBufferClear(const scoped_refptr<DecoderBufferBase>& buffer);
24 // DecoderBufferBase implementation.
25 StreamId stream_id() const override;
26 base::TimeDelta timestamp() const override;
27 void set_timestamp(const base::TimeDelta& timestamp) override;
28 const uint8* data() const override;
29 uint8* writable_data() const override;
30 size_t data_size() const override;
31 const ::media::DecryptConfig* decrypt_config() const override;
32 bool end_of_stream() const override;
34 private:
35 ~DecoderBufferClear() override;
37 scoped_refptr<DecoderBufferBase> const buffer_;
39 DISALLOW_COPY_AND_ASSIGN(DecoderBufferClear);
42 DecoderBufferClear::DecoderBufferClear(
43 const scoped_refptr<DecoderBufferBase>& buffer)
44 : buffer_(buffer) {
47 DecoderBufferClear::~DecoderBufferClear() {
50 StreamId DecoderBufferClear::stream_id() const {
51 return buffer_->stream_id();
54 base::TimeDelta DecoderBufferClear::timestamp() const {
55 return buffer_->timestamp();
58 void DecoderBufferClear::set_timestamp(const base::TimeDelta& timestamp) {
59 buffer_->set_timestamp(timestamp);
62 const uint8* DecoderBufferClear::data() const {
63 return buffer_->data();
66 uint8* DecoderBufferClear::writable_data() const {
67 return buffer_->writable_data();
70 size_t DecoderBufferClear::data_size() const {
71 return buffer_->data_size();
74 const ::media::DecryptConfig* DecoderBufferClear::decrypt_config() const {
75 // Buffer is clear so no decryption info.
76 return NULL;
79 bool DecoderBufferClear::end_of_stream() const {
80 return buffer_->end_of_stream();
83 } // namespace
85 scoped_refptr<DecoderBufferBase> DecryptDecoderBuffer(
86 const scoped_refptr<DecoderBufferBase>& buffer,
87 crypto::SymmetricKey* key) {
88 if (buffer->end_of_stream())
89 return buffer;
91 const ::media::DecryptConfig* decrypt_config = buffer->decrypt_config();
92 if (!decrypt_config || decrypt_config->iv().size() == 0)
93 return buffer;
95 // Get the key.
96 std::string raw_key;
97 if (!key->GetRawKey(&raw_key)) {
98 LOG(ERROR) << "Failed to get the underlying AES key";
99 return buffer;
101 DCHECK_EQ(static_cast<int>(raw_key.length()), AES_BLOCK_SIZE);
102 const uint8* key_u8 = reinterpret_cast<const uint8*>(raw_key.data());
103 AES_KEY aes_key;
104 if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) {
105 LOG(ERROR) << "Failed to set the AES key";
106 return buffer;
109 // Get the IV.
110 uint8 aes_iv[AES_BLOCK_SIZE];
111 DCHECK_EQ(static_cast<int>(decrypt_config->iv().length()),
112 AES_BLOCK_SIZE);
113 memcpy(aes_iv, decrypt_config->iv().data(), AES_BLOCK_SIZE);
115 // Decryption state.
116 unsigned int encrypted_byte_offset = 0;
117 uint8 ecount_buf[AES_BLOCK_SIZE];
119 // Perform the decryption.
120 const std::vector< ::media::SubsampleEntry>& subsamples =
121 decrypt_config->subsamples();
122 uint8* data = buffer->writable_data();
123 uint32 offset = 0;
124 for (size_t k = 0; k < subsamples.size(); k++) {
125 offset += subsamples[k].clear_bytes;
126 uint32 cypher_bytes = subsamples[k].cypher_bytes;
127 CHECK_LE(static_cast<size_t>(offset + cypher_bytes), buffer->data_size());
128 AES_ctr128_encrypt(
129 data + offset, data + offset, cypher_bytes, &aes_key,
130 aes_iv, ecount_buf, &encrypted_byte_offset);
131 offset += cypher_bytes;
134 return scoped_refptr<DecoderBufferBase>(new DecoderBufferClear(buffer));
137 } // namespace media
138 } // namespace chromecast