Chromium Code Reviews| Index: media/crypto/aes_decryptor.cc |
| diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc |
| index e69f4062a8afb3f00ee9d609a19785da40269efe..8cbd58db84da6354c52163e87155b1ea4781f24a 100644 |
| --- a/media/crypto/aes_decryptor.cc |
| +++ b/media/crypto/aes_decryptor.cc |
| @@ -83,53 +83,84 @@ static bool CheckData(const DecoderBuffer& input, |
| return true; |
| } |
| -// Decrypts |input| using |key|. |encrypted_data_offset| is the number of bytes |
| -// into |input| that the encrypted data starts. |
| -// Returns a DecoderBuffer with the decrypted data if decryption succeeded or |
| -// NULL if decryption failed. |
| -static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, |
| - crypto::SymmetricKey* key, |
| - int encrypted_data_offset) { |
| - CHECK(input.GetDataSize()); |
| - CHECK(input.GetDecryptConfig()); |
| - CHECK(key); |
| +// Decrypts |encrypted_data| using |key|. |
| +// Returns true and fill |decrypted_text| if if decryption succeeded. |
|
fgalligan1
2012/07/25 19:33:50
s/fill/fills/
s/if if/if/
xhwang
2012/07/26 23:36:47
Done.
|
| +// Returns false and leave |decrypted_text| as is if decryption failed. |
|
fgalligan1
2012/07/25 19:33:50
s/leave/leaves/
ddorwin
2012/07/26 21:24:07
I think this is pretty common practice and thus do
xhwang
2012/07/26 23:36:47
Done.
|
| +static bool DecryptData( |
| + const uint8* encrypted_data, int encrypted_data_size, |
| + const uint8* iv, int iv_size, |
| + crypto::SymmetricKey* key, |
| + std::string* decrypted_text) { |
|
ddorwin
2012/07/26 21:24:07
nit: Odd that the output is a different type from
xhwang
2012/07/26 23:36:47
Done.
|
| + DCHECK(decrypted_text->empty()); |
|
fgalligan1
2012/07/25 19:33:50
Why does decrypted_text need to be empty()?
xhwang
2012/07/26 23:36:47
Done.
|
| // Initialize decryptor. |
| crypto::Encryptor encryptor; |
| if (!encryptor.Init(key, crypto::Encryptor::CTR, "")) { |
| DVLOG(1) << "Could not initialize decryptor."; |
| - return NULL; |
| + return false; |
| } |
| - DCHECK_EQ(input.GetDecryptConfig()->iv_size(), |
| - DecryptConfig::kDecryptionKeySize); |
| + DCHECK_EQ(iv_size, DecryptConfig::kDecryptionKeySize); |
| // Set the counter block. |
| - base::StringPiece counter_block( |
| - reinterpret_cast<const char*>(input.GetDecryptConfig()->iv()), |
| - input.GetDecryptConfig()->iv_size()); |
| + base::StringPiece counter_block(reinterpret_cast<const char*>(iv),iv_size); |
|
ddorwin
2012/07/26 21:24:07
space after ,
xhwang
2012/07/26 23:36:47
Done.
|
| if (counter_block.empty()) { |
| DVLOG(1) << "Could not generate counter block."; |
| - return NULL; |
| + return false; |
| } |
| if (!encryptor.SetCounter(counter_block)) { |
| DVLOG(1) << "Could not set counter block."; |
| - return NULL; |
| + return false; |
| } |
| - std::string decrypted_text; |
| - const char* frame = |
| - reinterpret_cast<const char*>(input.GetData() + encrypted_data_offset); |
| - int frame_size = input.GetDataSize() - encrypted_data_offset; |
| - base::StringPiece encrypted_text(frame, frame_size); |
| - if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
| + base::StringPiece encrypted_text( |
| + reinterpret_cast<const char*>(encrypted_data), encrypted_data_size); |
| + if (!encryptor.Decrypt(encrypted_text, decrypted_text)) { |
| DVLOG(1) << "Could not decrypt data."; |
| - return NULL; |
| + DCHECK(decrypted_text->empty()); |
|
fgalligan1
2012/07/25 19:33:50
I don't think you need this check here if you remo
xhwang
2012/07/26 23:36:47
Done.
|
| + return false; |
| + } |
| + |
| + DCHECK(!decrypted_text->empty()); |
| + return true; |
| +} |
| + |
| +// Decrypts |encrypted_buffer| using |key|. |
| +// Fires the |decrypt_cb| with kSuccess and the decrypted buffer if decryption |
| +// succeeded. |
| +// Fires the |decrypt_cb| with kError and NULL if decryption failed. |
|
ddorwin
2012/07/26 21:24:07
Otherwise fires ... NULL.
xhwang
2012/07/26 23:36:47
Done.
|
| +static void DecryptBuffer(const Decryptor::DecryptCB& decrypt_cb, |
| + const scoped_refptr<DecoderBuffer>& encrypted_buffer, |
| + crypto::SymmetricKey* key) { |
| + CHECK(encrypted_buffer->GetDataSize()); |
| + CHECK(encrypted_buffer->GetDecryptConfig()); |
| + CHECK(key); |
| + |
| + std::string decrypted_text; |
| + int encrypted_data_offset = |
| + encrypted_buffer->GetDecryptConfig()->encrypted_frame_offset(); |
| + |
| + bool succeed = DecryptData( |
| + encrypted_buffer->GetData() + encrypted_data_offset, |
| + encrypted_buffer->GetDataSize() - encrypted_data_offset, |
| + encrypted_buffer->GetDecryptConfig()->iv(), |
| + encrypted_buffer->GetDecryptConfig()->iv_size(), |
| + key, |
| + &decrypted_text); |
| + |
| + if (!succeed) { |
| + DVLOG(1) << "Decryption failed."; |
| + decrypt_cb.Run(Decryptor::kError, NULL); |
| + return; |
| } |
| // TODO(xhwang): Find a way to avoid this data copy. |
| - return DecoderBuffer::CopyFrom( |
| + scoped_refptr<DecoderBuffer> decrypted_buffer = DecoderBuffer::CopyFrom( |
| reinterpret_cast<const uint8*>(decrypted_text.data()), |
| decrypted_text.size()); |
| + |
| + decrypted_buffer->SetTimestamp(encrypted_buffer->GetTimestamp()); |
| + decrypted_buffer->SetDuration(encrypted_buffer->GetDuration()); |
| + decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer); |
| } |
| AesDecryptor::AesDecryptor(DecryptorClient* client) |
| @@ -199,16 +230,7 @@ void AesDecryptor::AddKey(const std::string& key_system, |
| return; |
| } |
| - { |
| - base::AutoLock auto_lock(key_map_lock_); |
| - KeyMap::iterator found = key_map_.find(key_id_string); |
| - if (found != key_map_.end()) { |
| - delete found->second; |
| - key_map_.erase(found); |
| - } |
| - key_map_[key_id_string] = decryption_key.release(); |
| - } |
| - |
| + SetKey(key_id_string, decryption_key.Pass()); |
| client_->KeyAdded(key_system, session_id); |
| } |
| @@ -224,18 +246,10 @@ void AesDecryptor::Decrypt(const scoped_refptr<DecoderBuffer>& encrypted, |
| // TODO(xhwang): Avoid always constructing a string with StringPiece? |
| std::string key_id_string(reinterpret_cast<const char*>(key_id), key_id_size); |
| - |
| - DecryptionKey* key = NULL; |
| - { |
| - base::AutoLock auto_lock(key_map_lock_); |
| - KeyMap::const_iterator found = key_map_.find(key_id_string); |
| - if (found != key_map_.end()) |
| - key = found->second; |
| - } |
| + DecryptionKey* key = GetKey(key_id_string); |
| if (!key) { |
| - // TODO(fgalligan): Fire a need_key event here and add a test. |
| - DVLOG(1) << "Could not find a matching key for given key ID."; |
| + DVLOG(1) << "Could not find a matching key for the given key ID."; |
|
ddorwin
2012/07/26 21:24:07
This is still temporary, right? So there should st
xhwang
2012/07/26 23:36:47
Done.
|
| decrypt_cb.Run(kError, NULL); |
| return; |
| } |
| @@ -252,23 +266,30 @@ void AesDecryptor::Decrypt(const scoped_refptr<DecoderBuffer>& encrypted, |
| return; |
| } |
| - scoped_refptr<DecoderBuffer> decrypted = |
| - DecryptData(*encrypted, |
| - key->decryption_key(), |
| - encrypted->GetDecryptConfig()->encrypted_frame_offset()); |
| - if (!decrypted) { |
| - DVLOG(1) << "Decryption failed."; |
| - decrypt_cb.Run(kError, NULL); |
| - return; |
| + DecryptBuffer(decrypt_cb, encrypted, key->decryption_key()); |
| +} |
| + |
| +void AesDecryptor::SetKey(const std::string& key_id, |
| + scoped_ptr<DecryptionKey> decryption_key) { |
|
ddorwin
2012/07/26 21:24:07
Why not just a raw pointer with a note in .h that
xhwang
2012/07/26 23:36:47
Passing in scoped_ptr<> enforces that the AesDecry
|
| + base::AutoLock auto_lock(key_map_lock_); |
| + KeyMap::iterator found = key_map_.find(key_id); |
| + if (found != key_map_.end()) { |
| + delete found->second; |
| + key_map_.erase(found); |
| } |
| + key_map_[key_id] = decryption_key.release(); |
| +} |
| - decrypted->SetTimestamp(encrypted->GetTimestamp()); |
| - decrypted->SetDuration(encrypted->GetDuration()); |
| - decrypt_cb.Run(kSuccess, decrypted); |
| +AesDecryptor::DecryptionKey* AesDecryptor::GetKey( |
| + const std::string& key_id) const { |
| + base::AutoLock auto_lock(key_map_lock_); |
| + KeyMap::const_iterator found = key_map_.find(key_id); |
| + if (found != key_map_.end()) |
|
ddorwin
2012/07/26 21:24:07
I'd swap such that the success case is at the end
xhwang
2012/07/26 23:36:47
Done.
|
| + return found->second; |
| + return NULL; |
| } |
| -AesDecryptor::DecryptionKey::DecryptionKey( |
| - const std::string& secret) |
| +AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret) |
| : secret_(secret) { |
| } |