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