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