Chromium Code Reviews| Index: media/crypto/aes_decryptor.cc |
| diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc |
| index 129bc330131585c2a77a66dc7ab8b96fb96c76e6..963f23f00c6662e962129d5477be45877bc260f7 100644 |
| --- a/media/crypto/aes_decryptor.cc |
| +++ b/media/crypto/aes_decryptor.cc |
| @@ -16,9 +16,6 @@ |
| namespace media { |
| -// TODO(xhwang): Get real IV from frames. |
| -static const char kInitialCounter[] = "0000000000000000"; |
| - |
| uint32 AesDecryptor::next_session_id_ = 1; |
| // Decrypt |input| using |key|. |
| @@ -29,27 +26,88 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, |
| CHECK(input.GetDataSize()); |
| CHECK(key); |
|
fgalligan1
2012/06/27 00:28:36
Maybe add a TODO to support a key change?
strobe_
2012/06/27 02:01:21
Not sure what a key change means in this context.
|
| + base::StringPiece iv( |
| + reinterpret_cast<const char*>(input.GetDecryptConfig()->iv()), |
| + input.GetDecryptConfig()->iv_size()); |
| + |
| // Initialize encryption data. |
| // The IV must be exactly as long as the cipher block size. |
| crypto::Encryptor encryptor; |
| - if (!encryptor.Init(key, crypto::Encryptor::CBC, kInitialCounter)) { |
| - DVLOG(1) << "Could not initialize encryptor."; |
| - return NULL; |
| + if (input.GetDecryptConfig()->use_cbc()) { |
| + if (!encryptor.Init(key, crypto::Encryptor::CBC, iv)) { |
| + DVLOG(1) << "Could not initialize encryptor."; |
| + return NULL; |
| + } |
| + } else { |
| + if (!(encryptor.Init(key, crypto::Encryptor::CTR, base::StringPiece()) && |
|
ddorwin
2012/06/26 06:09:19
Suggest: !foo || !bar
strobe_
2012/06/27 02:01:21
Done.
|
| + encryptor.SetCounter(iv))) { |
| + DVLOG(1) << "Could not initialize encryptor."; |
| + return NULL; |
| + } |
| } |
| - std::string decrypted_text; |
| - base::StringPiece encrypted_text( |
| - reinterpret_cast<const char*>(input.GetData()), |
| - input.GetDataSize()); |
| - if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
| - DVLOG(1) << "Could not decrypt data."; |
| - return NULL; |
| - } |
| + if (input.GetDecryptConfig()->subsample_count()) { |
|
ddorwin
2012/06/26 06:09:19
Extract function for this case please. Then test i
strobe_
2012/06/27 02:01:21
Will do in next patch set.
|
| + int size = 0; |
|
ddorwin
2012/06/26 06:09:19
maybe total_subsample_size
strobe_
2012/06/27 02:01:21
Done.
|
| + for (int i = 0; i < input.GetDecryptConfig()->subsample_count(); i++) |
|
ddorwin
2012/06/26 06:09:19
This would be easier to read if you had aliases fo
strobe_
2012/06/27 02:01:21
Done.
|
| + size += input.GetDecryptConfig()->subsamples()[i].cypher_bytes; |
| + if (size > input.GetDataSize()) { |
|
ddorwin
2012/06/26 06:09:19
The input only contains encrypted bytes? Shouldn't
strobe_
2012/06/27 02:01:21
Input contains both encrypted and unencrypted byte
ddorwin
2012/07/03 21:03:46
It's still >, but I'm not sure you meant to/can ch
strobe_
2012/07/13 00:47:07
Yes, you're correct, the comment got out of sync w
|
| + DVLOG(1) << "Subsample encrypted size larger than input size"; |
| + return NULL; |
| + } |
| - // TODO(xhwang): Find a way to avoid this data copy. |
| - return DecoderBuffer::CopyFrom( |
| - reinterpret_cast<const uint8*>(decrypted_text.data()), |
| - decrypted_text.size()); |
| + scoped_array<uint8> encrypted_bytes(new uint8[size]); |
|
ddorwin
2012/06/26 06:09:19
Please explain what this code does. Copies encrypt
strobe_
2012/06/27 02:01:21
Precisely. Comment added.
|
| + int in_pos = 0, out_pos = 0; |
| + for (int i = 0; i < input.GetDecryptConfig()->subsample_count(); i++) { |
| + SubsampleEntry subsample = input.GetDecryptConfig()->subsamples()[i]; |
| + in_pos += subsample.clear_bytes; |
| + if (in_pos + subsample.cypher_bytes > input.GetDataSize()) { |
| + DVLOG(1) << "Subsample total size larger than input size"; |
| + return NULL; |
| + } |
| + memcpy(encrypted_bytes.get() + out_pos, input.GetData() + in_pos, |
| + subsample.cypher_bytes); |
| + in_pos += subsample.cypher_bytes; |
| + out_pos += subsample.cypher_bytes; |
| + } |
| + |
| + std::string decrypted_text; |
| + base::StringPiece encrypted_text( |
| + reinterpret_cast<const char*>(encrypted_bytes.get()), size); |
| + if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
| + DVLOG(1) << "Could not decrypt data."; |
| + return NULL; |
| + } |
| + encrypted_bytes.reset(); |
|
ddorwin
2012/06/26 06:09:19
Why explicitly here? And while encrypted_text is s
strobe_
2012/06/27 02:01:21
Removed. (Original reason was to minimize number o
|
| + |
| + scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( |
|
ddorwin
2012/06/26 06:09:19
We've copied at least twice now. Are there any oth
strobe_
2012/06/27 02:01:21
I didn't find any good ways without modifying Encr
|
| + input.GetData(), input.GetDataSize()); |
| + in_pos = 0; |
| + out_pos = 0; |
| + for (int i = 0; i < input.GetDecryptConfig()->subsample_count(); i++) { |
| + SubsampleEntry subsample = input.GetDecryptConfig()->subsamples()[i]; |
| + out_pos += subsample.clear_bytes; |
| + memcpy(output->GetWritableData() + out_pos, |
| + reinterpret_cast<const uint8*>(decrypted_text.data()) + in_pos, |
| + subsample.cypher_bytes); |
| + in_pos += subsample.cypher_bytes; |
| + out_pos += subsample.cypher_bytes; |
| + } |
| + return output; |
| + } else { |
| + std::string decrypted_text; |
| + base::StringPiece encrypted_text( |
| + reinterpret_cast<const char*>(input.GetData()), |
| + input.GetDataSize()); |
| + if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { |
| + DVLOG(1) << "Could not decrypt data."; |
| + return NULL; |
| + } |
| + |
| + // TODO(xhwang): Find a way to avoid this data copy. |
| + return DecoderBuffer::CopyFrom( |
| + reinterpret_cast<const uint8*>(decrypted_text.data()), |
| + decrypted_text.size()); |
| + } |
| } |
| AesDecryptor::AesDecryptor(DecryptorClient* client) |