| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromecast/media/cma/pipeline/decrypt_util.h" | 5 #include "chromecast/media/cma/pipeline/decrypt_util.h" |
| 6 | 6 |
| 7 #include <openssl/aes.h> | 7 #include <openssl/aes.h> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "chromecast/media/cma/base/decoder_buffer_base.h" | 11 #include "chromecast/media/cma/base/decoder_buffer_base.h" |
| 12 #include "chromecast/public/media/cast_decrypt_config.h" |
| 12 #include "crypto/symmetric_key.h" | 13 #include "crypto/symmetric_key.h" |
| 13 #include "media/base/decrypt_config.h" | |
| 14 | 14 |
| 15 namespace chromecast { | 15 namespace chromecast { |
| 16 namespace media { | 16 namespace media { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 class DecoderBufferClear : public DecoderBufferBase { | 20 class DecoderBufferClear : public DecoderBufferBase { |
| 21 public: | 21 public: |
| 22 explicit DecoderBufferClear(const scoped_refptr<DecoderBufferBase>& buffer); | 22 explicit DecoderBufferClear(const scoped_refptr<DecoderBufferBase>& buffer); |
| 23 | 23 |
| 24 // DecoderBufferBase implementation. | 24 // DecoderBufferBase implementation. |
| 25 StreamId stream_id() const override; | 25 StreamId stream_id() const override; |
| 26 base::TimeDelta timestamp() const override; | 26 base::TimeDelta timestamp() const override; |
| 27 void set_timestamp(const base::TimeDelta& timestamp) override; | 27 void set_timestamp(base::TimeDelta timestamp) override; |
| 28 const uint8* data() const override; | 28 const uint8* data() const override; |
| 29 uint8* writable_data() const override; | 29 uint8* writable_data() const override; |
| 30 size_t data_size() const override; | 30 size_t data_size() const override; |
| 31 const ::media::DecryptConfig* decrypt_config() const override; | 31 const CastDecryptConfig* decrypt_config() const override; |
| 32 bool end_of_stream() const override; | 32 bool end_of_stream() const override; |
| 33 | 33 |
| 34 private: | 34 private: |
| 35 ~DecoderBufferClear() override; | 35 ~DecoderBufferClear() override; |
| 36 | 36 |
| 37 scoped_refptr<DecoderBufferBase> const buffer_; | 37 scoped_refptr<DecoderBufferBase> const buffer_; |
| 38 | 38 |
| 39 DISALLOW_COPY_AND_ASSIGN(DecoderBufferClear); | 39 DISALLOW_COPY_AND_ASSIGN(DecoderBufferClear); |
| 40 }; | 40 }; |
| 41 | 41 |
| 42 DecoderBufferClear::DecoderBufferClear( | 42 DecoderBufferClear::DecoderBufferClear( |
| 43 const scoped_refptr<DecoderBufferBase>& buffer) | 43 const scoped_refptr<DecoderBufferBase>& buffer) |
| 44 : buffer_(buffer) { | 44 : buffer_(buffer) { |
| 45 } | 45 } |
| 46 | 46 |
| 47 DecoderBufferClear::~DecoderBufferClear() { | 47 DecoderBufferClear::~DecoderBufferClear() { |
| 48 } | 48 } |
| 49 | 49 |
| 50 StreamId DecoderBufferClear::stream_id() const { | 50 StreamId DecoderBufferClear::stream_id() const { |
| 51 return buffer_->stream_id(); | 51 return buffer_->stream_id(); |
| 52 } | 52 } |
| 53 | 53 |
| 54 base::TimeDelta DecoderBufferClear::timestamp() const { | 54 base::TimeDelta DecoderBufferClear::timestamp() const { |
| 55 return buffer_->timestamp(); | 55 return buffer_->timestamp(); |
| 56 } | 56 } |
| 57 | 57 |
| 58 void DecoderBufferClear::set_timestamp(const base::TimeDelta& timestamp) { | 58 void DecoderBufferClear::set_timestamp(base::TimeDelta timestamp) { |
| 59 buffer_->set_timestamp(timestamp); | 59 buffer_->set_timestamp(timestamp); |
| 60 } | 60 } |
| 61 | 61 |
| 62 const uint8* DecoderBufferClear::data() const { | 62 const uint8* DecoderBufferClear::data() const { |
| 63 return buffer_->data(); | 63 return buffer_->data(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 uint8* DecoderBufferClear::writable_data() const { | 66 uint8* DecoderBufferClear::writable_data() const { |
| 67 return buffer_->writable_data(); | 67 return buffer_->writable_data(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 size_t DecoderBufferClear::data_size() const { | 70 size_t DecoderBufferClear::data_size() const { |
| 71 return buffer_->data_size(); | 71 return buffer_->data_size(); |
| 72 } | 72 } |
| 73 | 73 |
| 74 const ::media::DecryptConfig* DecoderBufferClear::decrypt_config() const { | 74 const CastDecryptConfig* DecoderBufferClear::decrypt_config() const { |
| 75 // Buffer is clear so no decryption info. | 75 // Buffer is clear so no decryption info. |
| 76 return NULL; | 76 return NULL; |
| 77 } | 77 } |
| 78 | 78 |
| 79 bool DecoderBufferClear::end_of_stream() const { | 79 bool DecoderBufferClear::end_of_stream() const { |
| 80 return buffer_->end_of_stream(); | 80 return buffer_->end_of_stream(); |
| 81 } | 81 } |
| 82 | 82 |
| 83 } // namespace | 83 } // namespace |
| 84 | 84 |
| 85 scoped_refptr<DecoderBufferBase> DecryptDecoderBuffer( | 85 scoped_refptr<DecoderBufferBase> DecryptDecoderBuffer( |
| 86 const scoped_refptr<DecoderBufferBase>& buffer, | 86 const scoped_refptr<DecoderBufferBase>& buffer, |
| 87 crypto::SymmetricKey* key) { | 87 crypto::SymmetricKey* key) { |
| 88 if (buffer->end_of_stream()) | 88 if (buffer->end_of_stream()) |
| 89 return buffer; | 89 return buffer; |
| 90 | 90 |
| 91 const ::media::DecryptConfig* decrypt_config = buffer->decrypt_config(); | 91 const CastDecryptConfig* decrypt_config = buffer->decrypt_config(); |
| 92 if (!decrypt_config || decrypt_config->iv().size() == 0) | 92 if (!decrypt_config || decrypt_config->iv().size() == 0) |
| 93 return buffer; | 93 return buffer; |
| 94 | 94 |
| 95 // Get the key. | 95 // Get the key. |
| 96 std::string raw_key; | 96 std::string raw_key; |
| 97 if (!key->GetRawKey(&raw_key)) { | 97 if (!key->GetRawKey(&raw_key)) { |
| 98 LOG(ERROR) << "Failed to get the underlying AES key"; | 98 LOG(ERROR) << "Failed to get the underlying AES key"; |
| 99 return buffer; | 99 return buffer; |
| 100 } | 100 } |
| 101 DCHECK_EQ(static_cast<int>(raw_key.length()), AES_BLOCK_SIZE); | 101 DCHECK_EQ(static_cast<int>(raw_key.length()), AES_BLOCK_SIZE); |
| 102 const uint8* key_u8 = reinterpret_cast<const uint8*>(raw_key.data()); | 102 const uint8* key_u8 = reinterpret_cast<const uint8*>(raw_key.data()); |
| 103 AES_KEY aes_key; | 103 AES_KEY aes_key; |
| 104 if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) { | 104 if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) { |
| 105 LOG(ERROR) << "Failed to set the AES key"; | 105 LOG(ERROR) << "Failed to set the AES key"; |
| 106 return buffer; | 106 return buffer; |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Get the IV. | 109 // Get the IV. |
| 110 uint8 aes_iv[AES_BLOCK_SIZE]; | 110 uint8 aes_iv[AES_BLOCK_SIZE]; |
| 111 DCHECK_EQ(static_cast<int>(decrypt_config->iv().length()), | 111 DCHECK_EQ(static_cast<int>(decrypt_config->iv().length()), |
| 112 AES_BLOCK_SIZE); | 112 AES_BLOCK_SIZE); |
| 113 memcpy(aes_iv, decrypt_config->iv().data(), AES_BLOCK_SIZE); | 113 memcpy(aes_iv, decrypt_config->iv().data(), AES_BLOCK_SIZE); |
| 114 | 114 |
| 115 // Decryption state. | 115 // Decryption state. |
| 116 unsigned int encrypted_byte_offset = 0; | 116 unsigned int encrypted_byte_offset = 0; |
| 117 uint8 ecount_buf[AES_BLOCK_SIZE]; | 117 uint8 ecount_buf[AES_BLOCK_SIZE]; |
| 118 | 118 |
| 119 // Perform the decryption. | 119 // Perform the decryption. |
| 120 const std::vector< ::media::SubsampleEntry>& subsamples = | 120 const std::vector<SubsampleEntry>& subsamples = decrypt_config->subsamples(); |
| 121 decrypt_config->subsamples(); | |
| 122 uint8* data = buffer->writable_data(); | 121 uint8* data = buffer->writable_data(); |
| 123 uint32 offset = 0; | 122 uint32 offset = 0; |
| 124 for (size_t k = 0; k < subsamples.size(); k++) { | 123 for (size_t k = 0; k < subsamples.size(); k++) { |
| 125 offset += subsamples[k].clear_bytes; | 124 offset += subsamples[k].clear_bytes; |
| 126 uint32 cypher_bytes = subsamples[k].cypher_bytes; | 125 uint32 cypher_bytes = subsamples[k].cypher_bytes; |
| 127 CHECK_LE(static_cast<size_t>(offset + cypher_bytes), buffer->data_size()); | 126 CHECK_LE(static_cast<size_t>(offset + cypher_bytes), buffer->data_size()); |
| 128 AES_ctr128_encrypt( | 127 AES_ctr128_encrypt( |
| 129 data + offset, data + offset, cypher_bytes, &aes_key, | 128 data + offset, data + offset, cypher_bytes, &aes_key, |
| 130 aes_iv, ecount_buf, &encrypted_byte_offset); | 129 aes_iv, ecount_buf, &encrypted_byte_offset); |
| 131 offset += cypher_bytes; | 130 offset += cypher_bytes; |
| 132 } | 131 } |
| 133 | 132 |
| 134 return scoped_refptr<DecoderBufferBase>(new DecoderBufferClear(buffer)); | 133 return scoped_refptr<DecoderBufferBase>(new DecoderBufferClear(buffer)); |
| 135 } | 134 } |
| 136 | 135 |
| 137 } // namespace media | 136 } // namespace media |
| 138 } // namespace chromecast | 137 } // namespace chromecast |
| OLD | NEW |