Home | History | Annotate | Download | only in clearkey
      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