OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/crypto/aes_decryptor.h" | 5 #include "media/crypto/aes_decryptor.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/string_piece.h" | 10 #include "base/string_piece.h" |
11 #include "crypto/encryptor.h" | 11 #include "crypto/encryptor.h" |
12 #include "crypto/symmetric_key.h" | 12 #include "crypto/symmetric_key.h" |
13 #include "media/base/decoder_buffer.h" | 13 #include "media/base/decoder_buffer.h" |
14 #include "media/base/decrypt_config.h" | 14 #include "media/base/decrypt_config.h" |
15 #include "media/base/decryptor_client.h" | 15 #include "media/base/decryptor_client.h" |
16 | 16 |
17 namespace media { | 17 namespace media { |
18 | 18 |
19 // TODO(xhwang): Get real IV from frames. | |
20 static const char kInitialCounter[] = "0000000000000000"; | |
21 | |
22 uint32 AesDecryptor::next_session_id_ = 1; | 19 uint32 AesDecryptor::next_session_id_ = 1; |
23 | 20 |
24 // Decrypt |input| using |key|. | 21 // Decrypt |input| using |key|. |
25 // Return a DecoderBuffer with the decrypted data if decryption succeeded. | 22 // Return a DecoderBuffer with the decrypted data if decryption succeeded. |
26 // Return NULL if decryption failed. | 23 // Return NULL if decryption failed. |
27 static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, | 24 static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, |
28 crypto::SymmetricKey* key) { | 25 crypto::SymmetricKey* key) { |
29 CHECK(input.GetDataSize()); | 26 CHECK(input.GetDataSize()); |
30 CHECK(key); | 27 CHECK(key); |
31 | 28 |
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.
| |
29 base::StringPiece iv( | |
30 reinterpret_cast<const char*>(input.GetDecryptConfig()->iv()), | |
31 input.GetDecryptConfig()->iv_size()); | |
32 | |
32 // Initialize encryption data. | 33 // Initialize encryption data. |
33 // The IV must be exactly as long as the cipher block size. | 34 // The IV must be exactly as long as the cipher block size. |
34 crypto::Encryptor encryptor; | 35 crypto::Encryptor encryptor; |
35 if (!encryptor.Init(key, crypto::Encryptor::CBC, kInitialCounter)) { | 36 if (input.GetDecryptConfig()->use_cbc()) { |
36 DVLOG(1) << "Could not initialize encryptor."; | 37 if (!encryptor.Init(key, crypto::Encryptor::CBC, iv)) { |
37 return NULL; | 38 DVLOG(1) << "Could not initialize encryptor."; |
39 return NULL; | |
40 } | |
41 } else { | |
42 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.
| |
43 encryptor.SetCounter(iv))) { | |
44 DVLOG(1) << "Could not initialize encryptor."; | |
45 return NULL; | |
46 } | |
38 } | 47 } |
39 | 48 |
40 std::string decrypted_text; | 49 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.
| |
41 base::StringPiece encrypted_text( | 50 int size = 0; |
ddorwin
2012/06/26 06:09:19
maybe total_subsample_size
strobe_
2012/06/27 02:01:21
Done.
| |
42 reinterpret_cast<const char*>(input.GetData()), | 51 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.
| |
43 input.GetDataSize()); | 52 size += input.GetDecryptConfig()->subsamples()[i].cypher_bytes; |
44 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { | 53 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
| |
45 DVLOG(1) << "Could not decrypt data."; | 54 DVLOG(1) << "Subsample encrypted size larger than input size"; |
46 return NULL; | 55 return NULL; |
56 } | |
57 | |
58 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.
| |
59 int in_pos = 0, out_pos = 0; | |
60 for (int i = 0; i < input.GetDecryptConfig()->subsample_count(); i++) { | |
61 SubsampleEntry subsample = input.GetDecryptConfig()->subsamples()[i]; | |
62 in_pos += subsample.clear_bytes; | |
63 if (in_pos + subsample.cypher_bytes > input.GetDataSize()) { | |
64 DVLOG(1) << "Subsample total size larger than input size"; | |
65 return NULL; | |
66 } | |
67 memcpy(encrypted_bytes.get() + out_pos, input.GetData() + in_pos, | |
68 subsample.cypher_bytes); | |
69 in_pos += subsample.cypher_bytes; | |
70 out_pos += subsample.cypher_bytes; | |
71 } | |
72 | |
73 std::string decrypted_text; | |
74 base::StringPiece encrypted_text( | |
75 reinterpret_cast<const char*>(encrypted_bytes.get()), size); | |
76 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { | |
77 DVLOG(1) << "Could not decrypt data."; | |
78 return NULL; | |
79 } | |
80 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
| |
81 | |
82 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
| |
83 input.GetData(), input.GetDataSize()); | |
84 in_pos = 0; | |
85 out_pos = 0; | |
86 for (int i = 0; i < input.GetDecryptConfig()->subsample_count(); i++) { | |
87 SubsampleEntry subsample = input.GetDecryptConfig()->subsamples()[i]; | |
88 out_pos += subsample.clear_bytes; | |
89 memcpy(output->GetWritableData() + out_pos, | |
90 reinterpret_cast<const uint8*>(decrypted_text.data()) + in_pos, | |
91 subsample.cypher_bytes); | |
92 in_pos += subsample.cypher_bytes; | |
93 out_pos += subsample.cypher_bytes; | |
94 } | |
95 return output; | |
96 } else { | |
97 std::string decrypted_text; | |
98 base::StringPiece encrypted_text( | |
99 reinterpret_cast<const char*>(input.GetData()), | |
100 input.GetDataSize()); | |
101 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { | |
102 DVLOG(1) << "Could not decrypt data."; | |
103 return NULL; | |
104 } | |
105 | |
106 // TODO(xhwang): Find a way to avoid this data copy. | |
107 return DecoderBuffer::CopyFrom( | |
108 reinterpret_cast<const uint8*>(decrypted_text.data()), | |
109 decrypted_text.size()); | |
47 } | 110 } |
48 | |
49 // TODO(xhwang): Find a way to avoid this data copy. | |
50 return DecoderBuffer::CopyFrom( | |
51 reinterpret_cast<const uint8*>(decrypted_text.data()), | |
52 decrypted_text.size()); | |
53 } | 111 } |
54 | 112 |
55 AesDecryptor::AesDecryptor(DecryptorClient* client) | 113 AesDecryptor::AesDecryptor(DecryptorClient* client) |
56 : client_(client) { | 114 : client_(client) { |
57 } | 115 } |
58 | 116 |
59 AesDecryptor::~AesDecryptor() { | 117 AesDecryptor::~AesDecryptor() { |
60 STLDeleteValues(&key_map_); | 118 STLDeleteValues(&key_map_); |
61 } | 119 } |
62 | 120 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 | 213 |
156 if (decrypted) { | 214 if (decrypted) { |
157 decrypted->SetTimestamp(encrypted->GetTimestamp()); | 215 decrypted->SetTimestamp(encrypted->GetTimestamp()); |
158 decrypted->SetDuration(encrypted->GetDuration()); | 216 decrypted->SetDuration(encrypted->GetDuration()); |
159 } | 217 } |
160 | 218 |
161 return decrypted; | 219 return decrypted; |
162 } | 220 } |
163 | 221 |
164 } // namespace media | 222 } // namespace media |
OLD | NEW |