| 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 |