DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
key_source.cc
1 // Copyright 2014 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/key_source.h"
8 
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/media/base/aes_encryptor.h"
11 #include "packager/media/base/buffer_writer.h"
12 
13 namespace edash_packager {
14 namespace media {
15 
16 EncryptionKey::EncryptionKey() {}
17 EncryptionKey::~EncryptionKey() {}
18 
19 KeySource::~KeySource() {}
20 
21 Status KeySource::FetchKeys(const std::vector<uint8_t>& content_id,
22  const std::string& policy) {
23  // Do nothing for fixed key encryption/decryption.
24  return Status::OK;
25 }
26 
27 Status KeySource::FetchKeys(const std::vector<uint8_t>& pssh_box) {
28  // Do nothing for fixed key encryption/decryption.
29  return Status::OK;
30 }
31 
32 Status KeySource::FetchKeys(const std::vector<std::vector<uint8_t>>& key_ids) {
33  // Do nothing for fixed key encryption/decryption.
34  return Status::OK;
35 }
36 
37 Status KeySource::FetchKeys(uint32_t asset_id) {
38  // Do nothing for fixed key encryption/decryption.
39  return Status::OK;
40 }
41 
42 Status KeySource::GetKey(TrackType track_type, EncryptionKey* key) {
43  DCHECK(key);
44  DCHECK(encryption_key_);
45  *key = *encryption_key_;
46  return Status::OK;
47 }
48 
49 Status KeySource::GetKey(const std::vector<uint8_t>& key_id,
50  EncryptionKey* key) {
51  DCHECK(key);
52  DCHECK(encryption_key_);
53  if (key_id != encryption_key_->key_id) {
54  return Status(error::NOT_FOUND, std::string("Key for key ID ") +
55  base::HexEncode(&key_id[0], key_id.size()) +
56  " was not found.");
57  }
58  *key = *encryption_key_;
59  return Status::OK;
60 }
61 
62 Status KeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
63  TrackType track_type,
64  EncryptionKey* key) {
65  *key = *encryption_key_;
66  // A naive key rotation algorithm is implemented here by left rotating the
67  // key, key_id and pssh. Note that this implementation is only intended for
68  // testing purpose. The actual key rotation algorithm can be much more
69  // complicated.
70  LOG(WARNING)
71  << "This naive key rotation algorithm should not be used in production.";
72  std::rotate(key->key_id.begin(),
73  key->key_id.begin() + (crypto_period_index % key->key_id.size()),
74  key->key_id.end());
75  std::rotate(key->key.begin(),
76  key->key.begin() + (crypto_period_index % key->key.size()),
77  key->key.end());
78 
79  std::vector<uint8_t> pssh_data(
80  key->key_system_info[0].pssh_data().begin(),
81  key->key_system_info[0].pssh_data().end());
82  std::rotate(pssh_data.begin(),
83  pssh_data.begin() + (crypto_period_index % pssh_data.size()),
84  pssh_data.end());
85 
86  // Since this should only be used for testing, use the Widevine system id.
87  // TODO(modmaker): Change to FixedKeySource
89  info.add_key_id(key->key_id);
90  info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId));
91  info.set_pssh_box_version(0);
92  info.set_pssh_data(pssh_data);
93 
94  key->key_system_info.clear();
95  key->key_system_info.push_back(info);
96 
97  return Status::OK;
98 }
99 
100 scoped_ptr<KeySource> KeySource::CreateFromHexStrings(
101  const std::string& key_id_hex,
102  const std::string& key_hex,
103  const std::string& pssh_data_hex,
104  const std::string& iv_hex) {
105  scoped_ptr<EncryptionKey> encryption_key(new EncryptionKey());
106 
107  if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) {
108  LOG(ERROR) << "Cannot parse key_id_hex " << key_id_hex;
109  return scoped_ptr<KeySource>();
110  }
111 
112  if (!base::HexStringToBytes(key_hex, &encryption_key->key)) {
113  LOG(ERROR) << "Cannot parse key_hex " << key_hex;
114  return scoped_ptr<KeySource>();
115  }
116 
117  std::vector<uint8_t> pssh_data;
118  if (!pssh_data_hex.empty() &&
119  !base::HexStringToBytes(pssh_data_hex, &pssh_data)) {
120  LOG(ERROR) << "Cannot parse pssh_hex " << pssh_data_hex;
121  return scoped_ptr<KeySource>();
122  }
123 
124  if (!iv_hex.empty()) {
125  if (!base::HexStringToBytes(iv_hex, &encryption_key->iv)) {
126  LOG(ERROR) << "Cannot parse iv_hex " << iv_hex;
127  return scoped_ptr<KeySource>();
128  }
129  }
130 
131  // TODO(modmaker): Change to FixedKeySource
133  info.add_key_id(encryption_key->key_id);
134  info.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId));
135  info.set_pssh_box_version(0);
136  info.set_pssh_data(pssh_data);
137 
138  encryption_key->key_system_info.push_back(info);
139  return scoped_ptr<KeySource>(new KeySource(encryption_key.Pass()));
140 }
141 
143  const std::string& track_type_string) {
144  if (track_type_string == "SD")
145  return TRACK_TYPE_SD;
146  if (track_type_string == "HD")
147  return TRACK_TYPE_HD;
148  if (track_type_string == "AUDIO")
149  return TRACK_TYPE_AUDIO;
150  if (track_type_string == "UNSPECIFIED")
151  return TRACK_TYPE_UNSPECIFIED;
152  LOG(WARNING) << "Unexpected track type: " << track_type_string;
153  return TRACK_TYPE_UNKNOWN;
154 }
155 
156 std::string KeySource::TrackTypeToString(TrackType track_type) {
157  switch (track_type) {
158  case TRACK_TYPE_SD:
159  return "SD";
160  case TRACK_TYPE_HD:
161  return "HD";
162  case TRACK_TYPE_AUDIO:
163  return "AUDIO";
164  default:
165  NOTIMPLEMENTED() << "Unknown track type: " << track_type;
166  return "UNKNOWN";
167  }
168 }
169 
170 KeySource::KeySource() {}
171 KeySource::KeySource(scoped_ptr<EncryptionKey> encryption_key)
172  : encryption_key_(encryption_key.Pass()) {
173  DCHECK(encryption_key_);
174 }
175 
176 } // namespace media
177 } // namespace edash_packager
virtual Status GetKey(TrackType track_type, EncryptionKey *key)
Definition: key_source.cc:42
virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index, TrackType track_type, EncryptionKey *key)
Definition: key_source.cc:62
virtual Status FetchKeys(const std::vector< uint8_t > &content_id, const std::string &policy)
Definition: key_source.cc:21
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:35
static scoped_ptr< KeySource > CreateFromHexStrings(const std::string &key_id_hex, const std::string &key_hex, const std::string &pssh_data_hex, const std::string &iv_hex)
Definition: key_source.cc:100
static TrackType GetTrackTypeFromString(const std::string &track_type_string)
Convert string representation of track type to enum representation.
Definition: key_source.cc:142
static std::string TrackTypeToString(TrackType track_type)
Convert TrackType to string.
Definition: key_source.cc:156