DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
decryptor_source.cc
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/decryptor_source.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/stl_util.h"
11 
12 namespace edash_packager {
13 namespace media {
14 
15 DecryptorSource::DecryptorSource(KeySource* key_source)
16  : key_source_(key_source) {
17  CHECK(key_source);
18 }
19 DecryptorSource::~DecryptorSource() {
20  STLDeleteValues(&decryptor_map_);
21 }
22 
23 bool DecryptorSource::DecryptSampleBuffer(const DecryptConfig* decrypt_config,
24  uint8_t* buffer,
25  size_t buffer_size) {
26  DCHECK(decrypt_config);
27  DCHECK(buffer);
28 
29  // Get the decryptor object.
30  AesCryptor* decryptor;
31  auto found = decryptor_map_.find(decrypt_config->key_id());
32  if (found == decryptor_map_.end()) {
33  // Create new AesDecryptor based on decryption mode.
34  EncryptionKey key;
35  Status status(key_source_->GetKey(decrypt_config->key_id(), &key));
36  if (!status.ok()) {
37  LOG(ERROR) << "Error retrieving decryption key: " << status;
38  return false;
39  }
40 
41  scoped_ptr<AesCryptor> aes_decryptor;
42  switch (decrypt_config->decryption_mode()) {
43  case kEncryptionModeAesCtr:
44  aes_decryptor.reset(new AesCtrDecryptor);
45  break;
46  case kEncryptionModeAesCbc:
47  aes_decryptor.reset(new AesCbcDecryptor(kNoPadding, kChainAcrossCalls));
48  break;
49  default:
50  LOG(ERROR) << "Unsupported Decryption Mode: "
51  << decrypt_config->decryption_mode();
52  return false;
53  }
54 
55  if (!aes_decryptor->InitializeWithIv(key.key, decrypt_config->iv())) {
56  LOG(ERROR) << "Failed to initialize AesDecryptor for decryption.";
57  return false;
58  }
59  decryptor = aes_decryptor.release();
60  decryptor_map_[decrypt_config->key_id()] = decryptor;
61  } else {
62  decryptor = found->second;
63  }
64  if (!decryptor->SetIv(decrypt_config->iv())) {
65  LOG(ERROR) << "Invalid initialization vector.";
66  return false;
67  }
68 
69  if (decrypt_config->subsamples().empty()) {
70  // Sample not encrypted using subsample encryption. Decrypt whole.
71  if (!decryptor->Crypt(buffer, buffer_size, buffer)) {
72  LOG(ERROR) << "Error during bulk sample decryption.";
73  return false;
74  }
75  return true;
76  }
77 
78  // Subsample decryption.
79  const std::vector<SubsampleEntry>& subsamples = decrypt_config->subsamples();
80  uint8_t* current_ptr = buffer;
81  const uint8_t* const buffer_end = buffer + buffer_size;
82  for (const auto& subsample : subsamples) {
83  if ((current_ptr + subsample.clear_bytes + subsample.cipher_bytes) >
84  buffer_end) {
85  LOG(ERROR) << "Subsamples overflow sample buffer.";
86  return false;
87  }
88  current_ptr += subsample.clear_bytes;
89  if (!decryptor->Crypt(current_ptr, subsample.cipher_bytes, current_ptr)) {
90  LOG(ERROR) << "Error decrypting subsample buffer.";
91  return false;
92  }
93  current_ptr += subsample.cipher_bytes;
94  }
95  return true;
96 }
97 
98 } // namespace media
99 } // namespace edash_packager
virtual Status GetKey(TrackType track_type, EncryptionKey *key)=0