1 /* 2 * Copyright (C) 2017 The Android Open Source Project 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ClearKeyCasPlugin" 19 20 #include "ClearKeyFetcher.h" 21 #include "ecm.h" 22 #include "ClearKeyLicenseFetcher.h" 23 #include "ClearKeyCasPlugin.h" 24 #include "ClearKeySessionLibrary.h" 25 #include <media/stagefright/foundation/ABuffer.h> 26 #include <media/stagefright/foundation/ADebug.h> 27 #include <media/stagefright/foundation/hexdump.h> 28 #include <media/stagefright/MediaErrors.h> 29 #include <utils/Log.h> 30 31 android::CasFactory* createCasFactory() { 32 return new android::clearkeycas::ClearKeyCasFactory(); 33 } 34 35 android::DescramblerFactory *createDescramblerFactory() 36 { 37 return new android::clearkeycas::ClearKeyDescramblerFactory(); 38 } 39 40 namespace android { 41 namespace clearkeycas { 42 43 static const int32_t sClearKeySystemId = 0xF6D8; 44 45 bool ClearKeyCasFactory::isSystemIdSupported(int32_t CA_system_id) const { 46 return CA_system_id == sClearKeySystemId; 47 } 48 49 status_t ClearKeyCasFactory::queryPlugins( 50 std::vector<CasPluginDescriptor> *descriptors) const { 51 descriptors->clear(); 52 descriptors->push_back({sClearKeySystemId, String8("Clear Key CAS")}); 53 return OK; 54 } 55 56 status_t ClearKeyCasFactory::createPlugin( 57 int32_t CA_system_id, 58 void *appData, 59 CasPluginCallback callback, 60 CasPlugin **plugin) { 61 if (!isSystemIdSupported(CA_system_id)) { 62 return BAD_VALUE; 63 } 64 65 *plugin = new ClearKeyCasPlugin(appData, callback); 66 return OK; 67 } 68 /////////////////////////////////////////////////////////////////////////////// 69 bool ClearKeyDescramblerFactory::isSystemIdSupported( 70 int32_t CA_system_id) const { 71 return CA_system_id == sClearKeySystemId; 72 } 73 74 status_t ClearKeyDescramblerFactory::createPlugin( 75 int32_t CA_system_id, DescramblerPlugin** plugin) { 76 if (!isSystemIdSupported(CA_system_id)) { 77 return BAD_VALUE; 78 } 79 80 *plugin = new ClearKeyDescramblerPlugin(); 81 return OK; 82 } 83 84 /////////////////////////////////////////////////////////////////////////////// 85 ClearKeyCasPlugin::ClearKeyCasPlugin( 86 void *appData, CasPluginCallback callback) 87 : mCallback(callback), mAppData(appData) { 88 ALOGV("CTOR"); 89 } 90 91 ClearKeyCasPlugin::~ClearKeyCasPlugin() { 92 ALOGV("DTOR"); 93 ClearKeySessionLibrary::get()->destroyPlugin(this); 94 } 95 96 status_t ClearKeyCasPlugin::setPrivateData(const CasData &/*data*/) { 97 ALOGV("setPrivateData"); 98 99 return OK; 100 } 101 102 static String8 sessionIdToString(const std::vector<uint8_t> &array) { 103 String8 result; 104 for (size_t i = 0; i < array.size(); i++) { 105 result.appendFormat("%02x ", array[i]); 106 } 107 if (result.isEmpty()) { 108 result.append("(null)"); 109 } 110 return result; 111 } 112 113 status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) { 114 ALOGV("openSession"); 115 116 return ClearKeySessionLibrary::get()->addSession(this, sessionId); 117 } 118 119 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) { 120 ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string()); 121 sp<ClearKeyCasSession> session = 122 ClearKeySessionLibrary::get()->findSession(sessionId); 123 if (session == NULL) { 124 return ERROR_CAS_SESSION_NOT_OPENED; 125 } 126 127 ClearKeySessionLibrary::get()->destroySession(sessionId); 128 return OK; 129 } 130 131 status_t ClearKeyCasPlugin::setSessionPrivateData( 132 const CasSessionId &sessionId, const CasData & /*data*/) { 133 ALOGV("setSessionPrivateData: sessionId=%s", 134 sessionIdToString(sessionId).string()); 135 sp<ClearKeyCasSession> session = 136 ClearKeySessionLibrary::get()->findSession(sessionId); 137 if (session == NULL) { 138 return ERROR_CAS_SESSION_NOT_OPENED; 139 } 140 return OK; 141 } 142 143 status_t ClearKeyCasPlugin::processEcm( 144 const CasSessionId &sessionId, const CasEcm& ecm) { 145 ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string()); 146 sp<ClearKeyCasSession> session = 147 ClearKeySessionLibrary::get()->findSession(sessionId); 148 if (session == NULL) { 149 return ERROR_CAS_SESSION_NOT_OPENED; 150 } 151 152 Mutex::Autolock lock(mKeyFetcherLock); 153 154 return session->updateECM(mKeyFetcher.get(), (void*)ecm.data(), ecm.size()); 155 } 156 157 status_t ClearKeyCasPlugin::processEmm(const CasEmm& /*emm*/) { 158 ALOGV("processEmm"); 159 Mutex::Autolock lock(mKeyFetcherLock); 160 161 return OK; 162 } 163 164 status_t ClearKeyCasPlugin::sendEvent( 165 int32_t event, int32_t arg, const CasData &eventData) { 166 ALOGV("sendEvent: event=%d, arg=%d", event, arg); 167 // Echo the received event to the callback. 168 // Clear key plugin doesn't use any event, echo'ing for testing only. 169 if (mCallback != NULL) { 170 mCallback((void*)mAppData, event, arg, (uint8_t*)eventData.data(), eventData.size()); 171 } 172 return OK; 173 } 174 175 status_t ClearKeyCasPlugin::provision(const String8 &str) { 176 ALOGV("provision: provisionString=%s", str.string()); 177 Mutex::Autolock lock(mKeyFetcherLock); 178 179 std::unique_ptr<ClearKeyLicenseFetcher> license_fetcher; 180 license_fetcher.reset(new ClearKeyLicenseFetcher()); 181 status_t err = license_fetcher->Init(str.string()); 182 if (err != OK) { 183 ALOGE("provision: failed to init ClearKeyLicenseFetcher (err=%d)", err); 184 return err; 185 } 186 187 std::unique_ptr<ClearKeyFetcher> key_fetcher; 188 key_fetcher.reset(new ClearKeyFetcher(std::move(license_fetcher))); 189 err = key_fetcher->Init(); 190 if (err != OK) { 191 ALOGE("provision: failed to init ClearKeyFetcher (err=%d)", err); 192 return err; 193 } 194 195 ALOGV("provision: using ClearKeyFetcher"); 196 mKeyFetcher = std::move(key_fetcher); 197 198 return OK; 199 } 200 201 status_t ClearKeyCasPlugin::refreshEntitlements( 202 int32_t refreshType, const CasData &/*refreshData*/) { 203 ALOGV("refreshEntitlements: refreshType=%d", refreshType); 204 Mutex::Autolock lock(mKeyFetcherLock); 205 206 return OK; 207 } 208 209 /////////////////////////////////////////////////////////////////////// 210 211 // AES-128 CBC-CTS decrypt optimized for Transport Packets. |key| is the AES 212 // key (odd key or even key), |length| is the data size, and |buffer| is the 213 // ciphertext to be decrypted in place. 214 status_t TpBlockCtsDecrypt(const AES_KEY& key, size_t length, char* buffer) { 215 CHECK(buffer); 216 217 // Invariant: Packet must be at least 16 bytes. 218 CHECK(length >= AES_BLOCK_SIZE); 219 220 // OpenSSL uses unsigned char. 221 unsigned char* data = reinterpret_cast<unsigned char*>(buffer); 222 223 // Start with zero-filled initialization vector. 224 unsigned char iv[AES_BLOCK_SIZE]; 225 memset(iv, 0, AES_BLOCK_SIZE); 226 227 // Size of partial last block handled via CTS. 228 int cts_byte_count = length % AES_BLOCK_SIZE; 229 230 // If there no is no partial last block, then process using normal CBC. 231 if (cts_byte_count == 0) { 232 AES_cbc_encrypt(data, data, length, &key, iv, 0); 233 return OK; 234 } 235 236 // Cipher text stealing (CTS) - Schneier Figure 9.5 p 196. 237 // In CTS mode, the last two blocks have been swapped. Block[n-1] is really 238 // the original block[n] combined with the low-order bytes of the original 239 // block[n-1], while block[n] is the high-order bytes of the original 240 // block[n-1] padded with zeros. 241 242 // Block[0] - block[n-2] are handled with normal CBC. 243 int cbc_byte_count = length - cts_byte_count - AES_BLOCK_SIZE; 244 if (cbc_byte_count > 0) { 245 AES_cbc_encrypt(data, data, cbc_byte_count, &key, iv, 0); 246 // |data| points to block[n-1]. 247 data += cbc_byte_count; 248 } 249 250 // Save block[n] to use as IV when decrypting block[n-1]. 251 unsigned char block_n[AES_BLOCK_SIZE]; 252 memset(block_n, 0, AES_BLOCK_SIZE); 253 memcpy(block_n, data + AES_BLOCK_SIZE, cts_byte_count); 254 255 // Decrypt block[n-1] using block[n] as IV, consistent with the original 256 // block order. 257 AES_cbc_encrypt(data, data, AES_BLOCK_SIZE, &key, block_n, 0); 258 259 // Return the stolen ciphertext: swap the high-order bytes of block[n] 260 // and block[n-1]. 261 for (int i = 0; i < cts_byte_count; i++) { 262 unsigned char temp = *(data + i); 263 *(data + i) = *(data + AES_BLOCK_SIZE + i); 264 *(data + AES_BLOCK_SIZE + i) = temp; 265 } 266 267 // Decrypt block[n-1] using previous IV. 268 AES_cbc_encrypt(data, data, AES_BLOCK_SIZE, &key, iv, 0); 269 return OK; 270 } 271 272 // PES header and ECM stream header layout 273 // 274 // processECM() receives the data_byte portion from the transport packet. 275 // Below is the layout of the first 16 bytes of the ECM PES packet. Here 276 // we don't parse them, we skip them and go to the ECM container directly. 277 // The layout is included here only for reference. 278 // 279 // 0-2: 0x00 00 01 = start code prefix. 280 // 3: 0xf0 = stream type (90 = ECM). 281 // 4-5: 0x00 00 = PES length (filled in later, this is the length of the 282 // PES header (16) plus the length of the ECM container). 283 // 6-7: 0x00 00 = ECM major version. 284 // 8-9: 0x00 01 = ECM minor version. 285 // 10-11: 0x00 00 = Crypto period ID (filled in later). 286 // 12-13: 0x00 00 = ECM container length (filled in later, either 84 or 287 // 166). 288 // 14-15: 0x00 00 = offset = 0. 289 290 const static size_t kEcmHeaderLength = 16; 291 const static size_t kUserKeyLength = 16; 292 293 status_t ClearKeyCasSession::updateECM( 294 KeyFetcher *keyFetcher, void *ecm, size_t size) { 295 if (keyFetcher == nullptr) { 296 return ERROR_CAS_NOT_PROVISIONED; 297 } 298 299 if (size < kEcmHeaderLength) { 300 ALOGE("updateECM: invalid ecm size %zu", size); 301 return BAD_VALUE; 302 } 303 304 Mutex::Autolock _lock(mKeyLock); 305 306 if (mEcmBuffer != NULL && mEcmBuffer->capacity() == size 307 && !memcmp(mEcmBuffer->base(), ecm, size)) { 308 return OK; 309 } 310 311 mEcmBuffer = ABuffer::CreateAsCopy(ecm, size); 312 mEcmBuffer->setRange(kEcmHeaderLength, size - kEcmHeaderLength); 313 314 uint64_t asset_id; 315 std::vector<KeyFetcher::KeyInfo> keys; 316 status_t err = keyFetcher->ObtainKey(mEcmBuffer, &asset_id, &keys); 317 if (err != OK) { 318 ALOGE("updateECM: failed to obtain key (err=%d)", err); 319 return err; 320 } 321 322 ALOGV("updateECM: %zu key(s) found", keys.size()); 323 for (size_t keyIndex = 0; keyIndex < keys.size(); keyIndex++) { 324 String8 str; 325 326 const sp<ABuffer>& keyBytes = keys[keyIndex].key_bytes; 327 CHECK(keyBytes->size() == kUserKeyLength); 328 329 int result = AES_set_decrypt_key( 330 reinterpret_cast<const uint8_t*>(keyBytes->data()), 331 AES_BLOCK_SIZE * 8, &mKeyInfo[keyIndex].contentKey); 332 mKeyInfo[keyIndex].valid = (result == 0); 333 if (!mKeyInfo[keyIndex].valid) { 334 ALOGE("updateECM: failed to set key %zu, key_id=%d", 335 keyIndex, keys[keyIndex].key_id); 336 } 337 } 338 return OK; 339 } 340 341 // Decryption of a set of sub-samples 342 ssize_t ClearKeyCasSession::decrypt( 343 bool secure, DescramblerPlugin::ScramblingControl scramblingControl, 344 size_t numSubSamples, const DescramblerPlugin::SubSample *subSamples, 345 const void *srcPtr, void *dstPtr, AString * /* errorDetailMsg */) { 346 if (secure) { 347 return ERROR_CAS_CANNOT_HANDLE; 348 } 349 350 scramblingControl = (DescramblerPlugin::ScramblingControl) 351 (scramblingControl & DescramblerPlugin::kScrambling_Mask_Key); 352 353 AES_KEY contentKey; 354 355 if (scramblingControl != DescramblerPlugin::kScrambling_Unscrambled) { 356 // Hold lock to get the key only to avoid contention for decryption 357 Mutex::Autolock _lock(mKeyLock); 358 359 int32_t keyIndex = (scramblingControl & 1); 360 if (!mKeyInfo[keyIndex].valid) { 361 ALOGE("decrypt: key %d is invalid", keyIndex); 362 return ERROR_CAS_DECRYPT; 363 } 364 contentKey = mKeyInfo[keyIndex].contentKey; 365 } 366 367 uint8_t *src = (uint8_t*)srcPtr; 368 uint8_t *dst = (uint8_t*)dstPtr; 369 370 for (size_t i = 0; i < numSubSamples; i++) { 371 size_t numBytesinSubSample = subSamples[i].mNumBytesOfClearData 372 + subSamples[i].mNumBytesOfEncryptedData; 373 if (src != dst) { 374 memcpy(dst, src, numBytesinSubSample); 375 } 376 status_t err = OK; 377 // Don't decrypt if len < AES_BLOCK_SIZE. 378 // The last chunk shorter than AES_BLOCK_SIZE is not encrypted. 379 if (scramblingControl != DescramblerPlugin::kScrambling_Unscrambled 380 && subSamples[i].mNumBytesOfEncryptedData >= AES_BLOCK_SIZE) { 381 err = decryptPayload( 382 contentKey, 383 numBytesinSubSample, 384 subSamples[i].mNumBytesOfClearData, 385 (char *)dst); 386 } 387 388 dst += numBytesinSubSample; 389 src += numBytesinSubSample; 390 } 391 return dst - (uint8_t *)dstPtr; 392 } 393 394 // Decryption of a TS payload 395 status_t ClearKeyCasSession::decryptPayload( 396 const AES_KEY& key, size_t length, size_t offset, char* buffer) const { 397 CHECK(buffer); 398 399 // Invariant: only call decryptPayload with TS packets with at least 16 400 // bytes of payload (AES_BLOCK_SIZE). 401 402 CHECK(length >= offset + AES_BLOCK_SIZE); 403 404 return TpBlockCtsDecrypt(key, length - offset, buffer + offset); 405 } 406 407 /////////////////////////////////////////////////////////////////////////// 408 #undef LOG_TAG 409 #define LOG_TAG "ClearKeyDescramblerPlugin" 410 411 bool ClearKeyDescramblerPlugin::requiresSecureDecoderComponent( 412 const char *mime) const { 413 ALOGV("requiresSecureDecoderComponent: mime=%s", mime); 414 return false; 415 } 416 417 status_t ClearKeyDescramblerPlugin::setMediaCasSession( 418 const CasSessionId &sessionId) { 419 ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string()); 420 421 sp<ClearKeyCasSession> session = 422 ClearKeySessionLibrary::get()->findSession(sessionId); 423 424 if (session == NULL) { 425 ALOGE("ClearKeyDescramblerPlugin: session not found"); 426 return ERROR_CAS_SESSION_NOT_OPENED; 427 } 428 429 mCASSession = session; 430 return OK; 431 } 432 433 ssize_t ClearKeyDescramblerPlugin::descramble( 434 bool secure, 435 ScramblingControl scramblingControl, 436 size_t numSubSamples, 437 const SubSample *subSamples, 438 const void *srcPtr, 439 int32_t srcOffset, 440 void *dstPtr, 441 int32_t dstOffset, 442 AString *errorDetailMsg) { 443 444 ALOGV("descramble: secure=%d, sctrl=%d, subSamples=%s, " 445 "srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d", 446 (int)secure, (int)scramblingControl, 447 subSamplesToString(subSamples, numSubSamples).string(), 448 srcPtr, dstPtr, srcOffset, dstOffset); 449 450 if (mCASSession == NULL) { 451 ALOGE("Uninitialized CAS session!"); 452 return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED; 453 } 454 455 return mCASSession->decrypt( 456 secure, scramblingControl, 457 numSubSamples, subSamples, 458 (uint8_t*)srcPtr + srcOffset, 459 dstPtr == NULL ? NULL : ((uint8_t*)dstPtr + dstOffset), 460 errorDetailMsg); 461 } 462 463 // Conversion utilities 464 String8 ClearKeyDescramblerPlugin::arrayToString( 465 uint8_t const *array, size_t len) const 466 { 467 String8 result("{ "); 468 for (size_t i = 0; i < len; i++) { 469 result.appendFormat("0x%02x ", array[i]); 470 } 471 result += "}"; 472 return result; 473 } 474 475 String8 ClearKeyDescramblerPlugin::subSamplesToString( 476 SubSample const *subSamples, size_t numSubSamples) const 477 { 478 String8 result; 479 for (size_t i = 0; i < numSubSamples; i++) { 480 result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i, 481 subSamples[i].mNumBytesOfClearData, 482 subSamples[i].mNumBytesOfEncryptedData); 483 } 484 return result; 485 } 486 487 } // namespace clearkeycas 488 } // namespace android 489