OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/cdm/aes_decryptor.h" | 5 #include "media/cdm/aes_decryptor.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 std::string decrypted_text; | 160 std::string decrypted_text; |
161 base::StringPiece encrypted_text(sample, sample_size); | 161 base::StringPiece encrypted_text(sample, sample_size); |
162 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { | 162 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
163 DVLOG(1) << "Could not decrypt data."; | 163 DVLOG(1) << "Could not decrypt data."; |
164 return NULL; | 164 return NULL; |
165 } | 165 } |
166 | 166 |
167 // TODO(xhwang): Find a way to avoid this data copy. | 167 // TODO(xhwang): Find a way to avoid this data copy. |
168 return DecoderBuffer::CopyFrom( | 168 return DecoderBuffer::CopyFrom( |
169 reinterpret_cast<const uint8*>(decrypted_text.data()), | 169 reinterpret_cast<const uint8*>(decrypted_text.data()), |
170 decrypted_text.size()); | 170 decrypted_text.size(), |
| 171 false); |
171 } | 172 } |
172 | 173 |
173 const std::vector<SubsampleEntry>& subsamples = | 174 const std::vector<SubsampleEntry>& subsamples = |
174 input.decrypt_config()->subsamples(); | 175 input.decrypt_config()->subsamples(); |
175 | 176 |
176 size_t total_clear_size = 0; | 177 size_t total_clear_size = 0; |
177 size_t total_encrypted_size = 0; | 178 size_t total_encrypted_size = 0; |
178 for (size_t i = 0; i < subsamples.size(); i++) { | 179 for (size_t i = 0; i < subsamples.size(); i++) { |
179 total_clear_size += subsamples[i].clear_bytes; | 180 total_clear_size += subsamples[i].clear_bytes; |
180 total_encrypted_size += subsamples[i].cypher_bytes; | 181 total_encrypted_size += subsamples[i].cypher_bytes; |
181 // Check for overflow. This check is valid because *_size is unsigned. | 182 // Check for overflow. This check is valid because *_size is unsigned. |
182 DCHECK(total_clear_size >= subsamples[i].clear_bytes); | 183 DCHECK(total_clear_size >= subsamples[i].clear_bytes); |
183 if (total_encrypted_size < subsamples[i].cypher_bytes) | 184 if (total_encrypted_size < subsamples[i].cypher_bytes) |
184 return NULL; | 185 return NULL; |
185 } | 186 } |
186 size_t total_size = total_clear_size + total_encrypted_size; | 187 size_t total_size = total_clear_size + total_encrypted_size; |
187 if (total_size < total_clear_size || total_size != sample_size) { | 188 if (total_size < total_clear_size || total_size != sample_size) { |
188 DVLOG(1) << "Subsample sizes do not equal input size"; | 189 DVLOG(1) << "Subsample sizes do not equal input size"; |
189 return NULL; | 190 return NULL; |
190 } | 191 } |
191 | 192 |
192 // No need to decrypt if there is no encrypted data. | 193 // No need to decrypt if there is no encrypted data. |
193 if (total_encrypted_size <= 0) { | 194 if (total_encrypted_size <= 0) { |
194 return DecoderBuffer::CopyFrom(reinterpret_cast<const uint8*>(sample), | 195 return DecoderBuffer::CopyFrom(reinterpret_cast<const uint8*>(sample), |
195 sample_size); | 196 sample_size, |
| 197 false); |
196 } | 198 } |
197 | 199 |
198 // The encrypted portions of all subsamples must form a contiguous block, | 200 // The encrypted portions of all subsamples must form a contiguous block, |
199 // such that an encrypted subsample that ends away from a block boundary is | 201 // such that an encrypted subsample that ends away from a block boundary is |
200 // immediately followed by the start of the next encrypted subsample. We | 202 // immediately followed by the start of the next encrypted subsample. We |
201 // copy all encrypted subsamples to a contiguous buffer, decrypt them, then | 203 // copy all encrypted subsamples to a contiguous buffer, decrypt them, then |
202 // copy the decrypted bytes over the encrypted bytes in the output. | 204 // copy the decrypted bytes over the encrypted bytes in the output. |
203 // TODO(strobe): attempt to reduce number of memory copies | 205 // TODO(strobe): attempt to reduce number of memory copies |
204 scoped_ptr<uint8[]> encrypted_bytes(new uint8[total_encrypted_size]); | 206 scoped_ptr<uint8[]> encrypted_bytes(new uint8[total_encrypted_size]); |
205 CopySubsamples(subsamples, kSrcContainsClearBytes, | 207 CopySubsamples(subsamples, kSrcContainsClearBytes, |
206 reinterpret_cast<const uint8*>(sample), encrypted_bytes.get()); | 208 reinterpret_cast<const uint8*>(sample), encrypted_bytes.get()); |
207 | 209 |
208 base::StringPiece encrypted_text( | 210 base::StringPiece encrypted_text( |
209 reinterpret_cast<const char*>(encrypted_bytes.get()), | 211 reinterpret_cast<const char*>(encrypted_bytes.get()), |
210 total_encrypted_size); | 212 total_encrypted_size); |
211 std::string decrypted_text; | 213 std::string decrypted_text; |
212 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { | 214 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
213 DVLOG(1) << "Could not decrypt data."; | 215 DVLOG(1) << "Could not decrypt data."; |
214 return NULL; | 216 return NULL; |
215 } | 217 } |
216 DCHECK_EQ(decrypted_text.size(), encrypted_text.size()); | 218 DCHECK_EQ(decrypted_text.size(), encrypted_text.size()); |
217 | 219 |
218 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( | 220 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( |
219 reinterpret_cast<const uint8*>(sample), sample_size); | 221 reinterpret_cast<const uint8*>(sample), sample_size, false); |
220 CopySubsamples(subsamples, kDstContainsClearBytes, | 222 CopySubsamples(subsamples, kDstContainsClearBytes, |
221 reinterpret_cast<const uint8*>(decrypted_text.data()), | 223 reinterpret_cast<const uint8*>(decrypted_text.data()), |
222 output->writable_data()); | 224 output->writable_data()); |
223 return output; | 225 return output; |
224 } | 226 } |
225 | 227 |
226 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, | 228 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, |
227 const SessionClosedCB& session_closed_cb, | 229 const SessionClosedCB& session_closed_cb, |
228 const SessionKeysChangeCB& session_keys_change_cb) | 230 const SessionKeysChangeCB& session_keys_change_cb) |
229 : session_message_cb_(session_message_cb), | 231 : session_message_cb_(session_message_cb), |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 | 414 |
413 void AesDecryptor::Decrypt(StreamType stream_type, | 415 void AesDecryptor::Decrypt(StreamType stream_type, |
414 const scoped_refptr<DecoderBuffer>& encrypted, | 416 const scoped_refptr<DecoderBuffer>& encrypted, |
415 const DecryptCB& decrypt_cb) { | 417 const DecryptCB& decrypt_cb) { |
416 CHECK(encrypted->decrypt_config()); | 418 CHECK(encrypted->decrypt_config()); |
417 | 419 |
418 scoped_refptr<DecoderBuffer> decrypted; | 420 scoped_refptr<DecoderBuffer> decrypted; |
419 // An empty iv string signals that the frame is unencrypted. | 421 // An empty iv string signals that the frame is unencrypted. |
420 if (encrypted->decrypt_config()->iv().empty()) { | 422 if (encrypted->decrypt_config()->iv().empty()) { |
421 decrypted = DecoderBuffer::CopyFrom(encrypted->data(), | 423 decrypted = DecoderBuffer::CopyFrom(encrypted->data(), |
422 encrypted->data_size()); | 424 encrypted->data_size(), |
| 425 false); |
423 } else { | 426 } else { |
424 const std::string& key_id = encrypted->decrypt_config()->key_id(); | 427 const std::string& key_id = encrypted->decrypt_config()->key_id(); |
425 DecryptionKey* key = GetKey(key_id); | 428 DecryptionKey* key = GetKey(key_id); |
426 if (!key) { | 429 if (!key) { |
427 DVLOG(1) << "Could not find a matching key for the given key ID."; | 430 DVLOG(1) << "Could not find a matching key for the given key ID."; |
428 decrypt_cb.Run(kNoKey, NULL); | 431 decrypt_cb.Run(kNoKey, NULL); |
429 return; | 432 return; |
430 } | 433 } |
431 | 434 |
432 crypto::SymmetricKey* decryption_key = key->decryption_key(); | 435 crypto::SymmetricKey* decryption_key = key->decryption_key(); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 bool AesDecryptor::DecryptionKey::Init() { | 547 bool AesDecryptor::DecryptionKey::Init() { |
545 CHECK(!secret_.empty()); | 548 CHECK(!secret_.empty()); |
546 decryption_key_.reset(crypto::SymmetricKey::Import( | 549 decryption_key_.reset(crypto::SymmetricKey::Import( |
547 crypto::SymmetricKey::AES, secret_)); | 550 crypto::SymmetricKey::AES, secret_)); |
548 if (!decryption_key_) | 551 if (!decryption_key_) |
549 return false; | 552 return false; |
550 return true; | 553 return true; |
551 } | 554 } |
552 | 555 |
553 } // namespace media | 556 } // namespace media |
OLD | NEW |