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 |