ClearKeyDecryptionManager.cpp (10018B)
1 /* 2 * Copyright 2015, Mozilla Foundation and contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "ClearKeyDecryptionManager.h" 18 19 #include <assert.h> 20 #include <string.h> 21 22 #include <algorithm> 23 #include <vector> 24 25 #include "mozilla/CheckedInt.h" 26 #include "mozilla/Span.h" 27 #include "psshparser/PsshParser.h" 28 29 using namespace cdm; 30 31 bool AllZero(const std::vector<uint32_t>& aBytes) { 32 return std::all_of(aBytes.begin(), aBytes.end(), 33 [](uint32_t b) { return b == 0; }); 34 } 35 36 class ClearKeyDecryptor : public RefCounted { 37 public: 38 ClearKeyDecryptor(); 39 40 void InitKey(const Key& aKey); 41 bool HasKey() const { return !mKey.empty(); } 42 43 Status Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, 44 const CryptoMetaData& aMetadata); 45 46 const Key& DecryptionKey() const { return mKey; } 47 48 private: 49 ~ClearKeyDecryptor(); 50 51 Key mKey; 52 }; 53 54 /* static */ 55 ClearKeyDecryptionManager* ClearKeyDecryptionManager::sInstance = nullptr; 56 57 /* static */ 58 ClearKeyDecryptionManager* ClearKeyDecryptionManager::Get() { 59 if (!sInstance) { 60 sInstance = new ClearKeyDecryptionManager(); 61 } 62 return sInstance; 63 } 64 65 ClearKeyDecryptionManager::ClearKeyDecryptionManager() { 66 CK_LOGD("ClearKeyDecryptionManager::ClearKeyDecryptionManager"); 67 } 68 69 ClearKeyDecryptionManager::~ClearKeyDecryptionManager() { 70 CK_LOGD("ClearKeyDecryptionManager::~ClearKeyDecryptionManager"); 71 72 sInstance = nullptr; 73 74 for (auto it = mDecryptors.begin(); it != mDecryptors.end(); it++) { 75 it->second->Release(); 76 } 77 mDecryptors.clear(); 78 } 79 80 bool ClearKeyDecryptionManager::HasSeenKeyId(const KeyId& aKeyId) const { 81 CK_LOGD("ClearKeyDecryptionManager::SeenKeyId %s", 82 mDecryptors.find(aKeyId) != mDecryptors.end() ? "t" : "f"); 83 return mDecryptors.find(aKeyId) != mDecryptors.end(); 84 } 85 86 bool ClearKeyDecryptionManager::IsExpectingKeyForKeyId( 87 const KeyId& aKeyId) const { 88 CK_LOGARRAY("ClearKeyDecryptionManager::IsExpectingKeyForId ", aKeyId.data(), 89 aKeyId.size()); 90 const auto& decryptor = mDecryptors.find(aKeyId); 91 return decryptor != mDecryptors.end() && !decryptor->second->HasKey(); 92 } 93 94 bool ClearKeyDecryptionManager::HasKeyForKeyId(const KeyId& aKeyId) const { 95 CK_LOGD("ClearKeyDecryptionManager::HasKeyForKeyId"); 96 const auto& decryptor = mDecryptors.find(aKeyId); 97 return decryptor != mDecryptors.end() && decryptor->second->HasKey(); 98 } 99 100 const Key& ClearKeyDecryptionManager::GetDecryptionKey(const KeyId& aKeyId) { 101 assert(HasKeyForKeyId(aKeyId)); 102 return mDecryptors[aKeyId]->DecryptionKey(); 103 } 104 105 void ClearKeyDecryptionManager::InitKey(KeyId aKeyId, Key aKey) { 106 CK_LOGD("ClearKeyDecryptionManager::InitKey ", aKeyId.data(), aKeyId.size()); 107 if (IsExpectingKeyForKeyId(aKeyId)) { 108 CK_LOGARRAY("Initialized Key ", aKeyId.data(), aKeyId.size()); 109 mDecryptors[aKeyId]->InitKey(aKey); 110 } else { 111 CK_LOGARRAY("Failed to initialize key ", aKeyId.data(), aKeyId.size()); 112 } 113 } 114 115 void ClearKeyDecryptionManager::ExpectKeyId(KeyId aKeyId) { 116 CK_LOGD("ClearKeyDecryptionManager::ExpectKeyId ", aKeyId.data(), 117 aKeyId.size()); 118 if (!HasSeenKeyId(aKeyId)) { 119 mDecryptors[aKeyId] = new ClearKeyDecryptor(); 120 } 121 mDecryptors[aKeyId]->AddRef(); 122 } 123 124 void ClearKeyDecryptionManager::ReleaseKeyId(KeyId aKeyId) { 125 CK_LOGD("ClearKeyDecryptionManager::ReleaseKeyId"); 126 assert(HasSeenKeyId(aKeyId)); 127 128 ClearKeyDecryptor* decryptor = mDecryptors[aKeyId]; 129 if (!decryptor->Release()) { 130 mDecryptors.erase(aKeyId); 131 } 132 } 133 134 Status ClearKeyDecryptionManager::Decrypt(std::vector<uint8_t>& aBuffer, 135 const CryptoMetaData& aMetadata) { 136 return Decrypt(aBuffer.data(), aBuffer.size(), aMetadata); 137 } 138 139 Status ClearKeyDecryptionManager::Decrypt(uint8_t* aBuffer, 140 uint32_t aBufferSize, 141 const CryptoMetaData& aMetadata) { 142 CK_LOGD("ClearKeyDecryptionManager::Decrypt"); 143 if (!HasKeyForKeyId(aMetadata.mKeyId)) { 144 CK_LOGARRAY("Unable to find decryptor for keyId: ", aMetadata.mKeyId.data(), 145 aMetadata.mKeyId.size()); 146 return Status::kNoKey; 147 } 148 149 CK_LOGARRAY("Found decryptor for keyId: ", aMetadata.mKeyId.data(), 150 aMetadata.mKeyId.size()); 151 return mDecryptors[aMetadata.mKeyId]->Decrypt(aBuffer, aBufferSize, 152 aMetadata); 153 } 154 155 ClearKeyDecryptor::ClearKeyDecryptor() { CK_LOGD("ClearKeyDecryptor ctor"); } 156 157 ClearKeyDecryptor::~ClearKeyDecryptor() { 158 if (HasKey()) { 159 CK_LOGARRAY("ClearKeyDecryptor dtor; key = ", mKey.data(), mKey.size()); 160 } else { 161 CK_LOGD("ClearKeyDecryptor dtor"); 162 } 163 } 164 165 void ClearKeyDecryptor::InitKey(const Key& aKey) { mKey = aKey; } 166 167 Status ClearKeyDecryptor::Decrypt(uint8_t* aBuffer, uint32_t aBufferSize, 168 const CryptoMetaData& aMetadata) { 169 CK_LOGD("ClearKeyDecryptor::Decrypt"); 170 if (aBufferSize == 0) { 171 // Nothing to decrypt. 172 return Status::kSuccess; 173 } 174 175 // If the sample is split up into multiple encrypted subsamples, we need to 176 // stitch them into one continuous buffer for decryption. 177 std::vector<uint8_t> tmp(aBufferSize); 178 static_assert(sizeof(uintptr_t) == sizeof(uint8_t*), 179 "We need uintptr_t to be exactly the same size as a pointer"); 180 181 // Decrypt CBCS case: 182 if (aMetadata.mEncryptionScheme == EncryptionScheme::kCbcs) { 183 mozilla::CheckedInt<uintptr_t> data = reinterpret_cast<uintptr_t>(aBuffer); 184 if (!data.isValid()) { 185 return Status::kDecryptError; 186 } 187 const uintptr_t endBuffer = 188 reinterpret_cast<uintptr_t>(aBuffer + aBufferSize); 189 190 if (aMetadata.NumSubsamples() == 0) { 191 if (data.value() > endBuffer) { 192 return Status::kDecryptError; 193 } 194 mozilla::Span<uint8_t> encryptedSpan = 195 mozilla::Span(reinterpret_cast<uint8_t*>(data.value()), aBufferSize); 196 if (!ClearKeyUtils::DecryptCbcs(mKey, aMetadata.mIV, encryptedSpan, 197 aMetadata.mCryptByteBlock, 198 aMetadata.mSkipByteBlock)) { 199 return Status::kDecryptError; 200 } 201 return Status::kSuccess; 202 } 203 204 for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) { 205 data += aMetadata.mClearBytes[i]; 206 if (!data.isValid() || data.value() > endBuffer) { 207 return Status::kDecryptError; 208 } 209 mozilla::CheckedInt<uintptr_t> dataAfterCipher = 210 data + aMetadata.mCipherBytes[i]; 211 if (!dataAfterCipher.isValid() || dataAfterCipher.value() > endBuffer) { 212 // Trying to read past the end of the buffer! 213 return Status::kDecryptError; 214 } 215 mozilla::Span<uint8_t> encryptedSpan = mozilla::Span( 216 reinterpret_cast<uint8_t*>(data.value()), aMetadata.mCipherBytes[i]); 217 if (!ClearKeyUtils::DecryptCbcs(mKey, aMetadata.mIV, encryptedSpan, 218 aMetadata.mCryptByteBlock, 219 aMetadata.mSkipByteBlock)) { 220 return Status::kDecryptError; 221 } 222 data += aMetadata.mCipherBytes[i]; 223 if (!data.isValid()) { 224 return Status::kDecryptError; 225 } 226 } 227 return Status::kSuccess; 228 } 229 230 // Decrypt CENC case: 231 if (aMetadata.NumSubsamples()) { 232 // Take all encrypted parts of subsamples and stitch them into one 233 // continuous encrypted buffer. 234 mozilla::CheckedInt<uintptr_t> data = reinterpret_cast<uintptr_t>(aBuffer); 235 const uintptr_t endBuffer = 236 reinterpret_cast<uintptr_t>(aBuffer + aBufferSize); 237 uint8_t* iter = tmp.data(); 238 for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) { 239 data += aMetadata.mClearBytes[i]; 240 if (!data.isValid() || data.value() > endBuffer) { 241 // Trying to read past the end of the buffer! 242 return Status::kDecryptError; 243 } 244 const uint32_t& cipherBytes = aMetadata.mCipherBytes[i]; 245 mozilla::CheckedInt<uintptr_t> dataAfterCipher = data + cipherBytes; 246 if (!dataAfterCipher.isValid() || dataAfterCipher.value() > endBuffer) { 247 // Trying to read past the end of the buffer! 248 return Status::kDecryptError; 249 } 250 251 memcpy(iter, reinterpret_cast<uint8_t*>(data.value()), cipherBytes); 252 253 data = dataAfterCipher; 254 iter += cipherBytes; 255 } 256 257 tmp.resize((size_t)(iter - tmp.data())); 258 } else { 259 memcpy(tmp.data(), aBuffer, aBufferSize); 260 } 261 262 // It is possible that we could be passed an unencrypted sample, if all 263 // encrypted sample lengths are zero, and in this case, a zero length 264 // IV is allowed. 265 assert(aMetadata.mIV.size() == 8 || aMetadata.mIV.size() == 16 || 266 (aMetadata.mIV.empty() && AllZero(aMetadata.mCipherBytes))); 267 268 std::vector<uint8_t> iv(aMetadata.mIV); 269 iv.insert(iv.end(), CENC_KEY_LEN - aMetadata.mIV.size(), 0); 270 271 if (!ClearKeyUtils::DecryptAES(mKey, tmp, iv)) { 272 return Status::kDecryptError; 273 } 274 275 if (aMetadata.NumSubsamples()) { 276 // Take the decrypted buffer, split up into subsamples, and insert those 277 // subsamples back into their original position in the original buffer. 278 uint8_t* data = aBuffer; 279 uint8_t* iter = tmp.data(); 280 for (size_t i = 0; i < aMetadata.NumSubsamples(); i++) { 281 data += aMetadata.mClearBytes[i]; 282 uint32_t cipherBytes = aMetadata.mCipherBytes[i]; 283 284 memcpy(data, iter, cipherBytes); 285 286 data += cipherBytes; 287 iter += cipherBytes; 288 } 289 } else { 290 memcpy(aBuffer, tmp.data(), aBufferSize); 291 } 292 293 return Status::kSuccess; 294 }