Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: media/crypto/aes_decryptor.cc

Issue 17408005: Refactored DecoderBuffer to use unix_hacker_style naming. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@localrefactor
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "crypto/encryptor.h" 12 #include "crypto/encryptor.h"
13 #include "crypto/symmetric_key.h" 13 #include "crypto/symmetric_key.h"
14 #include "media/base/audio_decoder_config.h" 14 #include "media/base/audio_decoder_config.h"
15 #include "media/base/decoder_buffer.h" 15 #include "media/base/decoder_buffer.h"
16 #include "media/base/decrypt_config.h" 16 #include "media/base/decrypt_config.h"
17 #include "media/base/video_decoder_config.h" 17 #include "media/base/video_decoder_config.h"
18 #include "media/base/video_frame.h" 18 #include "media/base/video_frame.h"
19 19
20 namespace media { 20 namespace media {
21 21
22 uint32 AesDecryptor::next_session_id_ = 1; 22 uint32 AesDecryptor::next_session_id_ = 1;
23 23
24 enum ClearBytesBufferSel { 24 enum ClearBytesBufferSel {
25 kSrcContainsClearBytes, 25 kSrcContainsClearBytes,
26 kDstContainsClearBytes 26 kDstContainsClearBytes
27 }; 27 };
28 28
29 static void CopySubsamples(const std::vector<SubsampleEntry>& subsamples, 29 static void CopySubsamples(const std::vector<SubsampleEntry>& subsamples,
30 const ClearBytesBufferSel sel, 30 const ClearBytesBufferSel sel, const uint8* src,
31 const uint8* src,
32 uint8* dst) { 31 uint8* dst) {
33 for (size_t i = 0; i < subsamples.size(); i++) { 32 for (size_t i = 0; i < subsamples.size(); i++) {
34 const SubsampleEntry& subsample = subsamples[i]; 33 const SubsampleEntry& subsample = subsamples[i];
35 if (sel == kSrcContainsClearBytes) { 34 if (sel == kSrcContainsClearBytes) {
36 src += subsample.clear_bytes; 35 src += subsample.clear_bytes;
37 } else { 36 } else {
38 dst += subsample.clear_bytes; 37 dst += subsample.clear_bytes;
39 } 38 }
40 memcpy(dst, src, subsample.cypher_bytes); 39 memcpy(dst, src, subsample.cypher_bytes);
41 src += subsample.cypher_bytes; 40 src += subsample.cypher_bytes;
42 dst += subsample.cypher_bytes; 41 dst += subsample.cypher_bytes;
43 } 42 }
44 } 43 }
45 44
46 // Decrypts |input| using |key|. Returns a DecoderBuffer with the decrypted 45 // Decrypts |input| using |key|. Returns a DecoderBuffer with the decrypted
47 // data if decryption succeeded or NULL if decryption failed. 46 // data if decryption succeeded or NULL if decryption failed.
48 static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, 47 static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input,
49 crypto::SymmetricKey* key) { 48 crypto::SymmetricKey* key) {
50 CHECK(input.GetDataSize()); 49 CHECK(input.get_data_size());
51 CHECK(input.GetDecryptConfig()); 50 CHECK(input.get_decrypt_config());
52 CHECK(key); 51 CHECK(key);
53 52
54 crypto::Encryptor encryptor; 53 crypto::Encryptor encryptor;
55 if (!encryptor.Init(key, crypto::Encryptor::CTR, "")) { 54 if (!encryptor.Init(key, crypto::Encryptor::CTR, "")) {
56 DVLOG(1) << "Could not initialize decryptor."; 55 DVLOG(1) << "Could not initialize decryptor.";
57 return NULL; 56 return NULL;
58 } 57 }
59 58
60 DCHECK_EQ(input.GetDecryptConfig()->iv().size(), 59 DCHECK_EQ(input.get_decrypt_config()->iv().size(),
61 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)); 60 static_cast<size_t>(DecryptConfig::kDecryptionKeySize));
62 if (!encryptor.SetCounter(input.GetDecryptConfig()->iv())) { 61 if (!encryptor.SetCounter(input.get_decrypt_config()->iv())) {
63 DVLOG(1) << "Could not set counter block."; 62 DVLOG(1) << "Could not set counter block.";
64 return NULL; 63 return NULL;
65 } 64 }
66 65
67 const int data_offset = input.GetDecryptConfig()->data_offset(); 66 const int data_offset = input.get_decrypt_config()->data_offset();
68 const char* sample = 67 const char* sample =
69 reinterpret_cast<const char*>(input.GetData() + data_offset); 68 reinterpret_cast<const char*>(input.get_data() + data_offset);
70 int sample_size = input.GetDataSize() - data_offset; 69 int sample_size = input.get_data_size() - data_offset;
71 70
72 if (input.GetDecryptConfig()->subsamples().empty()) { 71 if (input.get_decrypt_config()->subsamples().empty()) {
73 std::string decrypted_text; 72 std::string decrypted_text;
74 base::StringPiece encrypted_text(sample, sample_size); 73 base::StringPiece encrypted_text(sample, sample_size);
75 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { 74 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) {
76 DVLOG(1) << "Could not decrypt data."; 75 DVLOG(1) << "Could not decrypt data.";
77 return NULL; 76 return NULL;
78 } 77 }
79 78
80 // TODO(xhwang): Find a way to avoid this data copy. 79 // TODO(xhwang): Find a way to avoid this data copy.
81 return DecoderBuffer::CopyFrom( 80 return DecoderBuffer::copy_from(
82 reinterpret_cast<const uint8*>(decrypted_text.data()), 81 reinterpret_cast<const uint8*>(decrypted_text.data()),
83 decrypted_text.size()); 82 decrypted_text.size());
84 } 83 }
85 84
86 const std::vector<SubsampleEntry>& subsamples = 85 const std::vector<SubsampleEntry>& subsamples =
87 input.GetDecryptConfig()->subsamples(); 86 input.get_decrypt_config()->subsamples();
88 87
89 int total_clear_size = 0; 88 int total_clear_size = 0;
90 int total_encrypted_size = 0; 89 int total_encrypted_size = 0;
91 for (size_t i = 0; i < subsamples.size(); i++) { 90 for (size_t i = 0; i < subsamples.size(); i++) {
92 total_clear_size += subsamples[i].clear_bytes; 91 total_clear_size += subsamples[i].clear_bytes;
93 total_encrypted_size += subsamples[i].cypher_bytes; 92 total_encrypted_size += subsamples[i].cypher_bytes;
94 } 93 }
95 if (total_clear_size + total_encrypted_size != sample_size) { 94 if (total_clear_size + total_encrypted_size != sample_size) {
96 DVLOG(1) << "Subsample sizes do not equal input size"; 95 DVLOG(1) << "Subsample sizes do not equal input size";
97 return NULL; 96 return NULL;
(...skipping 11 matching lines...) Expand all
109 108
110 base::StringPiece encrypted_text( 109 base::StringPiece encrypted_text(
111 reinterpret_cast<const char*>(encrypted_bytes.get()), 110 reinterpret_cast<const char*>(encrypted_bytes.get()),
112 total_encrypted_size); 111 total_encrypted_size);
113 std::string decrypted_text; 112 std::string decrypted_text;
114 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) { 113 if (!encryptor.Decrypt(encrypted_text, &decrypted_text)) {
115 DVLOG(1) << "Could not decrypt data."; 114 DVLOG(1) << "Could not decrypt data.";
116 return NULL; 115 return NULL;
117 } 116 }
118 117
119 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( 118 scoped_refptr<DecoderBuffer> output = DecoderBuffer::copy_from(
120 reinterpret_cast<const uint8*>(sample), sample_size); 119 reinterpret_cast<const uint8*>(sample), sample_size);
121 CopySubsamples(subsamples, kDstContainsClearBytes, 120 CopySubsamples(subsamples, kDstContainsClearBytes,
122 reinterpret_cast<const uint8*>(decrypted_text.data()), 121 reinterpret_cast<const uint8*>(decrypted_text.data()),
123 output->GetWritableData()); 122 output->get_writable_data());
124 return output; 123 return output;
125 } 124 }
126 125
127 AesDecryptor::AesDecryptor(const KeyAddedCB& key_added_cb, 126 AesDecryptor::AesDecryptor(const KeyAddedCB& key_added_cb,
128 const KeyErrorCB& key_error_cb, 127 const KeyErrorCB& key_error_cb,
129 const KeyMessageCB& key_message_cb, 128 const KeyMessageCB& key_message_cb,
130 const NeedKeyCB& need_key_cb) 129 const NeedKeyCB& need_key_cb)
131 : key_added_cb_(key_added_cb), 130 : key_added_cb_(key_added_cb),
132 key_error_cb_(key_error_cb), 131 key_error_cb_(key_error_cb),
133 key_message_cb_(key_message_cb), 132 key_message_cb_(key_message_cb),
134 need_key_cb_(need_key_cb) { 133 need_key_cb_(need_key_cb) {}
135 }
136 134
137 AesDecryptor::~AesDecryptor() { 135 AesDecryptor::~AesDecryptor() { STLDeleteValues(&key_map_); }
138 STLDeleteValues(&key_map_);
139 }
140 136
141 bool AesDecryptor::GenerateKeyRequest(const std::string& type, 137 bool AesDecryptor::GenerateKeyRequest(const std::string& type,
142 const uint8* init_data, 138 const uint8* init_data,
143 int init_data_length) { 139 int init_data_length) {
144 std::string session_id_string(base::UintToString(next_session_id_++)); 140 std::string session_id_string(base::UintToString(next_session_id_++));
145 141
146 // For now, the AesDecryptor does not care about |type|; 142 // For now, the AesDecryptor does not care about |type|;
147 // just fire the event with the |init_data| as the request. 143 // just fire the event with the |init_data| as the request.
148 std::string message; 144 std::string message;
149 if (init_data && init_data_length) { 145 if (init_data && init_data_length) {
150 message = std::string(reinterpret_cast<const char*>(init_data), 146 message =
151 init_data_length); 147 std::string(reinterpret_cast<const char*>(init_data), init_data_length);
152 } 148 }
153 149
154 key_message_cb_.Run(session_id_string, message, std::string()); 150 key_message_cb_.Run(session_id_string, message, std::string());
155 return true; 151 return true;
156 } 152 }
157 153
158 void AesDecryptor::AddKey(const uint8* key, 154 void AesDecryptor::AddKey(const uint8* key, int key_length,
159 int key_length, 155 const uint8* init_data, int init_data_length,
160 const uint8* init_data,
161 int init_data_length,
162 const std::string& session_id) { 156 const std::string& session_id) {
163 CHECK(key); 157 CHECK(key);
164 CHECK_GT(key_length, 0); 158 CHECK_GT(key_length, 0);
165 159
166 // TODO(xhwang): Add |session_id| check after we figure out how: 160 // TODO(xhwang): Add |session_id| check after we figure out how:
167 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550 161 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550
168 if (key_length != DecryptConfig::kDecryptionKeySize) { 162 if (key_length != DecryptConfig::kDecryptionKeySize) {
169 DVLOG(1) << "Invalid key length: " << key_length; 163 DVLOG(1) << "Invalid key length: " << key_length;
170 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); 164 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0);
171 return; 165 return;
172 } 166 }
173 167
174 // TODO(xhwang): Fix the decryptor to accept no |init_data|. See 168 // TODO(xhwang): Fix the decryptor to accept no |init_data|. See
175 // http://crbug.com/123265. Until then, ensure a non-empty value is passed. 169 // http://crbug.com/123265. Until then, ensure a non-empty value is passed.
176 static const uint8 kDummyInitData[1] = { 0 }; 170 static const uint8 kDummyInitData[1] = {0};
177 if (!init_data) { 171 if (!init_data) {
178 init_data = kDummyInitData; 172 init_data = kDummyInitData;
179 init_data_length = arraysize(kDummyInitData); 173 init_data_length = arraysize(kDummyInitData);
180 } 174 }
181 175
182 // TODO(xhwang): For now, use |init_data| for key ID. Make this more spec 176 // TODO(xhwang): For now, use |init_data| for key ID. Make this more spec
183 // compliant later (http://crbug.com/123262, http://crbug.com/123265). 177 // compliant later (http://crbug.com/123262, http://crbug.com/123265).
184 std::string key_id_string(reinterpret_cast<const char*>(init_data), 178 std::string key_id_string(reinterpret_cast<const char*>(init_data),
185 init_data_length); 179 init_data_length);
186 std::string key_string(reinterpret_cast<const char*>(key) , key_length); 180 std::string key_string(reinterpret_cast<const char*>(key), key_length);
187 scoped_ptr<DecryptionKey> decryption_key(new DecryptionKey(key_string)); 181 scoped_ptr<DecryptionKey> decryption_key(new DecryptionKey(key_string));
188 if (!decryption_key) { 182 if (!decryption_key) {
189 DVLOG(1) << "Could not create key."; 183 DVLOG(1) << "Could not create key.";
190 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); 184 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0);
191 return; 185 return;
192 } 186 }
193 187
194 if (!decryption_key->Init()) { 188 if (!decryption_key->Init()) {
195 DVLOG(1) << "Could not initialize decryption key."; 189 DVLOG(1) << "Could not initialize decryption key.";
196 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); 190 key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0);
197 return; 191 return;
198 } 192 }
199 193
200 SetKey(key_id_string, decryption_key.Pass()); 194 SetKey(key_id_string, decryption_key.Pass());
201 195
202 if (!new_audio_key_cb_.is_null()) 196 if (!new_audio_key_cb_.is_null()) new_audio_key_cb_.Run();
203 new_audio_key_cb_.Run();
204 197
205 if (!new_video_key_cb_.is_null()) 198 if (!new_video_key_cb_.is_null()) new_video_key_cb_.Run();
206 new_video_key_cb_.Run();
207 199
208 key_added_cb_.Run(session_id); 200 key_added_cb_.Run(session_id);
209 } 201 }
210 202
211 void AesDecryptor::CancelKeyRequest(const std::string& session_id) { 203 void AesDecryptor::CancelKeyRequest(const std::string& session_id) {}
212 }
213 204
214 Decryptor* AesDecryptor::GetDecryptor() { 205 Decryptor* AesDecryptor::GetDecryptor() { return this; }
215 return this;
216 }
217 206
218 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, 207 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type,
219 const NewKeyCB& new_key_cb) { 208 const NewKeyCB& new_key_cb) {
220 switch (stream_type) { 209 switch (stream_type) {
221 case kAudio: 210 case kAudio:
222 new_audio_key_cb_ = new_key_cb; 211 new_audio_key_cb_ = new_key_cb;
223 break; 212 break;
224 case kVideo: 213 case kVideo:
225 new_video_key_cb_ = new_key_cb; 214 new_video_key_cb_ = new_key_cb;
226 break; 215 break;
227 default: 216 default:
228 NOTREACHED(); 217 NOTREACHED();
229 } 218 }
230 } 219 }
231 220
232 void AesDecryptor::Decrypt(StreamType stream_type, 221 void AesDecryptor::Decrypt(StreamType stream_type,
233 const scoped_refptr<DecoderBuffer>& encrypted, 222 const scoped_refptr<DecoderBuffer>& encrypted,
234 const DecryptCB& decrypt_cb) { 223 const DecryptCB& decrypt_cb) {
235 CHECK(encrypted->GetDecryptConfig()); 224 CHECK(encrypted->get_decrypt_config());
236 225
237 scoped_refptr<DecoderBuffer> decrypted; 226 scoped_refptr<DecoderBuffer> decrypted;
238 // An empty iv string signals that the frame is unencrypted. 227 // An empty iv string signals that the frame is unencrypted.
239 if (encrypted->GetDecryptConfig()->iv().empty()) { 228 if (encrypted->get_decrypt_config()->iv().empty()) {
240 int data_offset = encrypted->GetDecryptConfig()->data_offset(); 229 int data_offset = encrypted->get_decrypt_config()->data_offset();
241 decrypted = DecoderBuffer::CopyFrom(encrypted->GetData() + data_offset, 230 decrypted =
242 encrypted->GetDataSize() - data_offset); 231 DecoderBuffer::copy_from(encrypted->get_data() + data_offset,
232 encrypted->get_data_size() - data_offset);
243 } else { 233 } else {
244 const std::string& key_id = encrypted->GetDecryptConfig()->key_id(); 234 const std::string& key_id = encrypted->get_decrypt_config()->key_id();
245 DecryptionKey* key = GetKey(key_id); 235 DecryptionKey* key = GetKey(key_id);
246 if (!key) { 236 if (!key) {
247 DVLOG(1) << "Could not find a matching key for the given key ID."; 237 DVLOG(1) << "Could not find a matching key for the given key ID.";
248 decrypt_cb.Run(kNoKey, NULL); 238 decrypt_cb.Run(kNoKey, NULL);
249 return; 239 return;
250 } 240 }
251 241
252 crypto::SymmetricKey* decryption_key = key->decryption_key(); 242 crypto::SymmetricKey* decryption_key = key->decryption_key();
253 decrypted = DecryptData(*encrypted.get(), decryption_key); 243 decrypted = DecryptData(*encrypted.get(), decryption_key);
254 if (!decrypted.get()) { 244 if (!decrypted.get()) {
255 DVLOG(1) << "Decryption failed."; 245 DVLOG(1) << "Decryption failed.";
256 decrypt_cb.Run(kError, NULL); 246 decrypt_cb.Run(kError, NULL);
257 return; 247 return;
258 } 248 }
259 } 249 }
260 250
261 decrypted->SetTimestamp(encrypted->GetTimestamp()); 251 decrypted->set_timestamp(encrypted->get_timestamp());
262 decrypted->SetDuration(encrypted->GetDuration()); 252 decrypted->set_duration(encrypted->get_duration());
263 decrypt_cb.Run(kSuccess, decrypted); 253 decrypt_cb.Run(kSuccess, decrypted);
264 } 254 }
265 255
266 void AesDecryptor::CancelDecrypt(StreamType stream_type) { 256 void AesDecryptor::CancelDecrypt(StreamType stream_type) {
267 // Decrypt() calls the DecryptCB synchronously so there's nothing to cancel. 257 // Decrypt() calls the DecryptCB synchronously so there's nothing to cancel.
268 } 258 }
269 259
270 void AesDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config, 260 void AesDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config,
271 const DecoderInitCB& init_cb) { 261 const DecoderInitCB& init_cb) {
272 // AesDecryptor does not support audio decoding. 262 // AesDecryptor does not support audio decoding.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 delete found->second; 297 delete found->second;
308 key_map_.erase(found); 298 key_map_.erase(found);
309 } 299 }
310 key_map_[key_id] = decryption_key.release(); 300 key_map_[key_id] = decryption_key.release();
311 } 301 }
312 302
313 AesDecryptor::DecryptionKey* AesDecryptor::GetKey( 303 AesDecryptor::DecryptionKey* AesDecryptor::GetKey(
314 const std::string& key_id) const { 304 const std::string& key_id) const {
315 base::AutoLock auto_lock(key_map_lock_); 305 base::AutoLock auto_lock(key_map_lock_);
316 KeyMap::const_iterator found = key_map_.find(key_id); 306 KeyMap::const_iterator found = key_map_.find(key_id);
317 if (found == key_map_.end()) 307 if (found == key_map_.end()) return NULL;
318 return NULL;
319 308
320 return found->second; 309 return found->second;
321 } 310 }
322 311
323 AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret) 312 AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret)
324 : secret_(secret) { 313 : secret_(secret) {}
325 }
326 314
327 AesDecryptor::DecryptionKey::~DecryptionKey() {} 315 AesDecryptor::DecryptionKey::~DecryptionKey() {}
328 316
329 bool AesDecryptor::DecryptionKey::Init() { 317 bool AesDecryptor::DecryptionKey::Init() {
330 CHECK(!secret_.empty()); 318 CHECK(!secret_.empty());
331 decryption_key_.reset(crypto::SymmetricKey::Import( 319 decryption_key_.reset(
332 crypto::SymmetricKey::AES, secret_)); 320 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, secret_));
333 if (!decryption_key_) 321 if (!decryption_key_) return false;
334 return false;
335 return true; 322 return true;
336 } 323 }
337 324
338 } // namespace media 325 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698