• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 "Drm"
19 #include <utils/Log.h>
20 
21 #include <dirent.h>
22 #include <dlfcn.h>
23 
24 #include <media/DrmPluginPath.h>
25 #include <media/DrmSessionClientInterface.h>
26 #include <media/DrmSessionManager.h>
27 #include <media/Drm.h>
28 #include <media/drm/DrmAPI.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/stagefright/foundation/AString.h>
31 #include <media/stagefright/foundation/hexdump.h>
32 #include <media/stagefright/MediaErrors.h>
33 #include <binder/IServiceManager.h>
34 #include <binder/IPCThreadState.h>
35 
36 namespace android {
37 
getCallingPid()38 static inline int getCallingPid() {
39     return IPCThreadState::self()->getCallingPid();
40 }
41 
checkPermission(const char * permissionString)42 static bool checkPermission(const char* permissionString) {
43     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
44     bool ok = checkCallingPermission(String16(permissionString));
45     if (!ok) ALOGE("Request requires %s", permissionString);
46     return ok;
47 }
48 
49 KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
50 KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
51 Mutex Drm::mMapLock;
52 Mutex Drm::mLock;
53 
operator <(const Vector<uint8_t> & lhs,const Vector<uint8_t> & rhs)54 static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
55     if (lhs.size() < rhs.size()) {
56         return true;
57     } else if (lhs.size() > rhs.size()) {
58         return false;
59     }
60 
61     return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
62 }
63 
64 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient65     explicit DrmSessionClient(Drm* drm) : mDrm(drm) {}
66 
reclaimSessionandroid::DrmSessionClient67     virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
68         sp<Drm> drm = mDrm.promote();
69         if (drm == NULL) {
70             return true;
71         }
72         status_t err = drm->closeSession(sessionId);
73         if (err != OK) {
74             return false;
75         }
76         drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
77         return true;
78     }
79 
80 protected:
~DrmSessionClientandroid::DrmSessionClient81     virtual ~DrmSessionClient() {}
82 
83 private:
84     wp<Drm> mDrm;
85 
86     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
87 };
88 
Drm()89 Drm::Drm()
90     : mInitCheck(NO_INIT),
91       mDrmSessionClient(new DrmSessionClient(this)),
92       mListener(NULL),
93       mFactory(NULL),
94       mPlugin(NULL) {
95 }
96 
~Drm()97 Drm::~Drm() {
98     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
99     delete mPlugin;
100     mPlugin = NULL;
101     closeFactory();
102 }
103 
closeFactory()104 void Drm::closeFactory() {
105     delete mFactory;
106     mFactory = NULL;
107     mLibrary.clear();
108 }
109 
initCheck() const110 status_t Drm::initCheck() const {
111     return mInitCheck;
112 }
113 
setListener(const sp<IDrmClient> & listener)114 status_t Drm::setListener(const sp<IDrmClient>& listener)
115 {
116     Mutex::Autolock lock(mEventLock);
117     if (mListener != NULL){
118         IInterface::asBinder(mListener)->unlinkToDeath(this);
119     }
120     if (listener != NULL) {
121         IInterface::asBinder(listener)->linkToDeath(this);
122     }
123     mListener = listener;
124     return NO_ERROR;
125 }
126 
sendEvent(DrmPlugin::EventType eventType,int extra,Vector<uint8_t> const * sessionId,Vector<uint8_t> const * data)127 void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
128                     Vector<uint8_t> const *sessionId,
129                     Vector<uint8_t> const *data)
130 {
131     mEventLock.lock();
132     sp<IDrmClient> listener = mListener;
133     mEventLock.unlock();
134 
135     if (listener != NULL) {
136         Parcel obj;
137         writeByteArray(obj, sessionId);
138         writeByteArray(obj, data);
139 
140         Mutex::Autolock lock(mNotifyLock);
141         listener->notify(eventType, extra, &obj);
142     }
143 }
144 
sendExpirationUpdate(Vector<uint8_t> const * sessionId,int64_t expiryTimeInMS)145 void Drm::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
146                                int64_t expiryTimeInMS)
147 {
148     mEventLock.lock();
149     sp<IDrmClient> listener = mListener;
150     mEventLock.unlock();
151 
152     if (listener != NULL) {
153         Parcel obj;
154         writeByteArray(obj, sessionId);
155         obj.writeInt64(expiryTimeInMS);
156 
157         Mutex::Autolock lock(mNotifyLock);
158         listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
159     }
160 }
161 
sendKeysChange(Vector<uint8_t> const * sessionId,Vector<DrmPlugin::KeyStatus> const * keyStatusList,bool hasNewUsableKey)162 void Drm::sendKeysChange(Vector<uint8_t> const *sessionId,
163                          Vector<DrmPlugin::KeyStatus> const *keyStatusList,
164                          bool hasNewUsableKey)
165 {
166     mEventLock.lock();
167     sp<IDrmClient> listener = mListener;
168     mEventLock.unlock();
169 
170     if (listener != NULL) {
171         Parcel obj;
172         writeByteArray(obj, sessionId);
173 
174         size_t nkeys = keyStatusList->size();
175         obj.writeInt32(keyStatusList->size());
176         for (size_t i = 0; i < nkeys; ++i) {
177             const DrmPlugin::KeyStatus *keyStatus = &keyStatusList->itemAt(i);
178             writeByteArray(obj, &keyStatus->mKeyId);
179             obj.writeInt32(keyStatus->mType);
180         }
181         obj.writeInt32(hasNewUsableKey);
182 
183         Mutex::Autolock lock(mNotifyLock);
184         listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
185     }
186 }
187 
188 /*
189  * Search the plugins directory for a plugin that supports the scheme
190  * specified by uuid
191  *
192  * If found:
193  *    mLibrary holds a strong pointer to the dlopen'd library
194  *    mFactory is set to the library's factory method
195  *    mInitCheck is set to OK
196  *
197  * If not found:
198  *    mLibrary is cleared and mFactory are set to NULL
199  *    mInitCheck is set to an error (!OK)
200  */
findFactoryForScheme(const uint8_t uuid[16])201 void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
202 
203     closeFactory();
204 
205     // lock static maps
206     Mutex::Autolock autoLock(mMapLock);
207 
208     // first check cache
209     Vector<uint8_t> uuidVector;
210     uuidVector.appendArray(uuid, sizeof(uuid[0]) * 16);
211     ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
212     if (index >= 0) {
213         if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
214             mInitCheck = OK;
215             return;
216         } else {
217             ALOGE("Failed to load from cached library path!");
218             mInitCheck = ERROR_UNSUPPORTED;
219             return;
220         }
221     }
222 
223     // no luck, have to search
224     String8 dirPath(getDrmPluginPath());
225     DIR* pDir = opendir(dirPath.string());
226 
227     if (pDir == NULL) {
228         mInitCheck = ERROR_UNSUPPORTED;
229         ALOGE("Failed to open plugin directory %s", dirPath.string());
230         return;
231     }
232 
233 
234     struct dirent* pEntry;
235     while ((pEntry = readdir(pDir))) {
236 
237         String8 pluginPath = dirPath + "/" + pEntry->d_name;
238 
239         if (pluginPath.getPathExtension() == ".so") {
240 
241             if (loadLibraryForScheme(pluginPath, uuid)) {
242                 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
243                 mInitCheck = OK;
244                 closedir(pDir);
245                 return;
246             }
247         }
248     }
249 
250     closedir(pDir);
251 
252     ALOGE("Failed to find drm plugin");
253     mInitCheck = ERROR_UNSUPPORTED;
254 }
255 
loadLibraryForScheme(const String8 & path,const uint8_t uuid[16])256 bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
257 
258     // get strong pointer to open shared library
259     ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
260     if (index >= 0) {
261         mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
262     } else {
263         index = mLibraryPathToOpenLibraryMap.add(path, NULL);
264     }
265 
266     if (!mLibrary.get()) {
267         mLibrary = new SharedLibrary(path);
268         if (!*mLibrary) {
269             return false;
270         }
271 
272         mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
273     }
274 
275     typedef DrmFactory *(*CreateDrmFactoryFunc)();
276 
277     CreateDrmFactoryFunc createDrmFactory =
278         (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
279 
280     if (createDrmFactory == NULL ||
281         (mFactory = createDrmFactory()) == NULL ||
282         !mFactory->isCryptoSchemeSupported(uuid)) {
283         closeFactory();
284         return false;
285     }
286     return true;
287 }
288 
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType)289 bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
290 
291     Mutex::Autolock autoLock(mLock);
292 
293     if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
294         findFactoryForScheme(uuid);
295         if (mInitCheck != OK) {
296             return false;
297         }
298     }
299 
300     if (mimeType != "") {
301         return mFactory->isContentTypeSupported(mimeType);
302     }
303 
304     return true;
305 }
306 
createPlugin(const uint8_t uuid[16],const String8 &)307 status_t Drm::createPlugin(const uint8_t uuid[16],
308                            const String8& /* appPackageName */) {
309     Mutex::Autolock autoLock(mLock);
310 
311     if (mPlugin != NULL) {
312         return -EINVAL;
313     }
314 
315     if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
316         findFactoryForScheme(uuid);
317     }
318 
319     if (mInitCheck != OK) {
320         return mInitCheck;
321     }
322 
323     status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
324     if (mPlugin) {
325         mPlugin->setListener(this);
326     } else {
327         ALOGE("Failed to create plugin");
328         return UNEXPECTED_NULL;
329     }
330     return result;
331 }
332 
destroyPlugin()333 status_t Drm::destroyPlugin() {
334     Mutex::Autolock autoLock(mLock);
335 
336     if (mInitCheck != OK) {
337         return mInitCheck;
338     }
339 
340     if (mPlugin == NULL) {
341         return -EINVAL;
342     }
343 
344     setListener(NULL);
345     delete mPlugin;
346     mPlugin = NULL;
347 
348     return OK;
349 }
350 
openSession(Vector<uint8_t> & sessionId)351 status_t Drm::openSession(Vector<uint8_t> &sessionId) {
352     Mutex::Autolock autoLock(mLock);
353 
354     if (mInitCheck != OK) {
355         return mInitCheck;
356     }
357 
358     if (mPlugin == NULL) {
359         return -EINVAL;
360     }
361 
362     status_t err = mPlugin->openSession(sessionId);
363     if (err == ERROR_DRM_RESOURCE_BUSY) {
364         bool retry = false;
365         mLock.unlock();
366         // reclaimSession may call back to closeSession, since mLock is shared between Drm
367         // instances, we should unlock here to avoid deadlock.
368         retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
369         mLock.lock();
370         if (mInitCheck != OK) {
371             return mInitCheck;
372         }
373 
374         if (mPlugin == NULL) {
375             return -EINVAL;
376         }
377         if (retry) {
378             err = mPlugin->openSession(sessionId);
379         }
380     }
381     if (err == OK) {
382         DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
383     }
384     return err;
385 }
386 
closeSession(Vector<uint8_t> const & sessionId)387 status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
388     Mutex::Autolock autoLock(mLock);
389 
390     if (mInitCheck != OK) {
391         return mInitCheck;
392     }
393 
394     if (mPlugin == NULL) {
395         return -EINVAL;
396     }
397 
398     status_t err = mPlugin->closeSession(sessionId);
399     if (err == OK) {
400         DrmSessionManager::Instance()->removeSession(sessionId);
401     }
402     return err;
403 }
404 
getKeyRequest(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & initData,String8 const & mimeType,DrmPlugin::KeyType keyType,KeyedVector<String8,String8> const & optionalParameters,Vector<uint8_t> & request,String8 & defaultUrl,DrmPlugin::KeyRequestType * keyRequestType)405 status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
406                             Vector<uint8_t> const &initData,
407                             String8 const &mimeType, DrmPlugin::KeyType keyType,
408                             KeyedVector<String8, String8> const &optionalParameters,
409                             Vector<uint8_t> &request, String8 &defaultUrl,
410                             DrmPlugin::KeyRequestType *keyRequestType) {
411     Mutex::Autolock autoLock(mLock);
412 
413     if (mInitCheck != OK) {
414         return mInitCheck;
415     }
416 
417     if (mPlugin == NULL) {
418         return -EINVAL;
419     }
420 
421     DrmSessionManager::Instance()->useSession(sessionId);
422 
423     return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
424                                   optionalParameters, request, defaultUrl,
425                                   keyRequestType);
426 }
427 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)428 status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
429                                  Vector<uint8_t> const &response,
430                                  Vector<uint8_t> &keySetId) {
431     Mutex::Autolock autoLock(mLock);
432 
433     if (mInitCheck != OK) {
434         return mInitCheck;
435     }
436 
437     if (mPlugin == NULL) {
438         return -EINVAL;
439     }
440 
441     DrmSessionManager::Instance()->useSession(sessionId);
442 
443     return mPlugin->provideKeyResponse(sessionId, response, keySetId);
444 }
445 
removeKeys(Vector<uint8_t> const & keySetId)446 status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
447     Mutex::Autolock autoLock(mLock);
448 
449     if (mInitCheck != OK) {
450         return mInitCheck;
451     }
452 
453     if (mPlugin == NULL) {
454         return -EINVAL;
455     }
456 
457     return mPlugin->removeKeys(keySetId);
458 }
459 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)460 status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
461                           Vector<uint8_t> const &keySetId) {
462     Mutex::Autolock autoLock(mLock);
463 
464     if (mInitCheck != OK) {
465         return mInitCheck;
466     }
467 
468     if (mPlugin == NULL) {
469         return -EINVAL;
470     }
471 
472     DrmSessionManager::Instance()->useSession(sessionId);
473 
474     return mPlugin->restoreKeys(sessionId, keySetId);
475 }
476 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const477 status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
478                              KeyedVector<String8, String8> &infoMap) const {
479     Mutex::Autolock autoLock(mLock);
480 
481     if (mInitCheck != OK) {
482         return mInitCheck;
483     }
484 
485     if (mPlugin == NULL) {
486         return -EINVAL;
487     }
488 
489     DrmSessionManager::Instance()->useSession(sessionId);
490 
491     return mPlugin->queryKeyStatus(sessionId, infoMap);
492 }
493 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)494 status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
495                                   Vector<uint8_t> &request, String8 &defaultUrl) {
496     Mutex::Autolock autoLock(mLock);
497 
498     if (mInitCheck != OK) {
499         return mInitCheck;
500     }
501 
502     if (mPlugin == NULL) {
503         return -EINVAL;
504     }
505 
506     return mPlugin->getProvisionRequest(certType, certAuthority,
507                                         request, defaultUrl);
508 }
509 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)510 status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
511                                        Vector<uint8_t> &certificate,
512                                        Vector<uint8_t> &wrappedKey) {
513     Mutex::Autolock autoLock(mLock);
514 
515     if (mInitCheck != OK) {
516         return mInitCheck;
517     }
518 
519     if (mPlugin == NULL) {
520         return -EINVAL;
521     }
522 
523     return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
524 }
525 
getSecureStops(List<Vector<uint8_t>> & secureStops)526 status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
527     Mutex::Autolock autoLock(mLock);
528 
529     if (mInitCheck != OK) {
530         return mInitCheck;
531     }
532 
533     if (mPlugin == NULL) {
534         return -EINVAL;
535     }
536 
537     return mPlugin->getSecureStops(secureStops);
538 }
539 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)540 status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
541     Mutex::Autolock autoLock(mLock);
542 
543     if (mInitCheck != OK) {
544         return mInitCheck;
545     }
546 
547     if (mPlugin == NULL) {
548         return -EINVAL;
549     }
550 
551     return mPlugin->getSecureStop(ssid, secureStop);
552 }
553 
releaseSecureStops(Vector<uint8_t> const & ssRelease)554 status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
555     Mutex::Autolock autoLock(mLock);
556 
557     if (mInitCheck != OK) {
558         return mInitCheck;
559     }
560 
561     if (mPlugin == NULL) {
562         return -EINVAL;
563     }
564 
565     return mPlugin->releaseSecureStops(ssRelease);
566 }
567 
releaseAllSecureStops()568 status_t Drm::releaseAllSecureStops() {
569     Mutex::Autolock autoLock(mLock);
570 
571     if (mInitCheck != OK) {
572         return mInitCheck;
573     }
574 
575     if (mPlugin == NULL) {
576         return -EINVAL;
577     }
578 
579     return mPlugin->releaseAllSecureStops();
580 }
581 
getPropertyString(String8 const & name,String8 & value) const582 status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
583     Mutex::Autolock autoLock(mLock);
584 
585     if (mInitCheck != OK) {
586         return mInitCheck;
587     }
588 
589     if (mPlugin == NULL) {
590         return -EINVAL;
591     }
592 
593     return mPlugin->getPropertyString(name, value);
594 }
595 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const596 status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
597     Mutex::Autolock autoLock(mLock);
598 
599     if (mInitCheck != OK) {
600         return mInitCheck;
601     }
602 
603     if (mPlugin == NULL) {
604         return -EINVAL;
605     }
606 
607     return mPlugin->getPropertyByteArray(name, value);
608 }
609 
setPropertyString(String8 const & name,String8 const & value) const610 status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
611     Mutex::Autolock autoLock(mLock);
612 
613     if (mInitCheck != OK) {
614         return mInitCheck;
615     }
616 
617     if (mPlugin == NULL) {
618         return -EINVAL;
619     }
620 
621     return mPlugin->setPropertyString(name, value);
622 }
623 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const624 status_t Drm::setPropertyByteArray(String8 const &name,
625                                    Vector<uint8_t> const &value ) const {
626     Mutex::Autolock autoLock(mLock);
627 
628     if (mInitCheck != OK) {
629         return mInitCheck;
630     }
631 
632     if (mPlugin == NULL) {
633         return -EINVAL;
634     }
635 
636     return mPlugin->setPropertyByteArray(name, value);
637 }
638 
639 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)640 status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
641                                  String8 const &algorithm) {
642     Mutex::Autolock autoLock(mLock);
643 
644     if (mInitCheck != OK) {
645         return mInitCheck;
646     }
647 
648     if (mPlugin == NULL) {
649         return -EINVAL;
650     }
651 
652     DrmSessionManager::Instance()->useSession(sessionId);
653 
654     return mPlugin->setCipherAlgorithm(sessionId, algorithm);
655 }
656 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)657 status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
658                               String8 const &algorithm) {
659     Mutex::Autolock autoLock(mLock);
660 
661     if (mInitCheck != OK) {
662         return mInitCheck;
663     }
664 
665     if (mPlugin == NULL) {
666         return -EINVAL;
667     }
668 
669     DrmSessionManager::Instance()->useSession(sessionId);
670 
671     return mPlugin->setMacAlgorithm(sessionId, algorithm);
672 }
673 
encrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)674 status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
675                       Vector<uint8_t> const &keyId,
676                       Vector<uint8_t> const &input,
677                       Vector<uint8_t> const &iv,
678                       Vector<uint8_t> &output) {
679     Mutex::Autolock autoLock(mLock);
680 
681     if (mInitCheck != OK) {
682         return mInitCheck;
683     }
684 
685     if (mPlugin == NULL) {
686         return -EINVAL;
687     }
688 
689     DrmSessionManager::Instance()->useSession(sessionId);
690 
691     return mPlugin->encrypt(sessionId, keyId, input, iv, output);
692 }
693 
decrypt(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & input,Vector<uint8_t> const & iv,Vector<uint8_t> & output)694 status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
695                       Vector<uint8_t> const &keyId,
696                       Vector<uint8_t> const &input,
697                       Vector<uint8_t> const &iv,
698                       Vector<uint8_t> &output) {
699     Mutex::Autolock autoLock(mLock);
700 
701     if (mInitCheck != OK) {
702         return mInitCheck;
703     }
704 
705     if (mPlugin == NULL) {
706         return -EINVAL;
707     }
708 
709     DrmSessionManager::Instance()->useSession(sessionId);
710 
711     return mPlugin->decrypt(sessionId, keyId, input, iv, output);
712 }
713 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)714 status_t Drm::sign(Vector<uint8_t> const &sessionId,
715                    Vector<uint8_t> const &keyId,
716                    Vector<uint8_t> const &message,
717                    Vector<uint8_t> &signature) {
718     Mutex::Autolock autoLock(mLock);
719 
720     if (mInitCheck != OK) {
721         return mInitCheck;
722     }
723 
724     if (mPlugin == NULL) {
725         return -EINVAL;
726     }
727 
728     DrmSessionManager::Instance()->useSession(sessionId);
729 
730     return mPlugin->sign(sessionId, keyId, message, signature);
731 }
732 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)733 status_t Drm::verify(Vector<uint8_t> const &sessionId,
734                      Vector<uint8_t> const &keyId,
735                      Vector<uint8_t> const &message,
736                      Vector<uint8_t> const &signature,
737                      bool &match) {
738     Mutex::Autolock autoLock(mLock);
739 
740     if (mInitCheck != OK) {
741         return mInitCheck;
742     }
743 
744     if (mPlugin == NULL) {
745         return -EINVAL;
746     }
747 
748     DrmSessionManager::Instance()->useSession(sessionId);
749 
750     return mPlugin->verify(sessionId, keyId, message, signature, match);
751 }
752 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)753 status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
754                       String8 const &algorithm,
755                       Vector<uint8_t> const &message,
756                       Vector<uint8_t> const &wrappedKey,
757                       Vector<uint8_t> &signature) {
758     Mutex::Autolock autoLock(mLock);
759 
760     if (mInitCheck != OK) {
761         return mInitCheck;
762     }
763 
764     if (mPlugin == NULL) {
765         return -EINVAL;
766     }
767 
768     if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
769         return -EPERM;
770     }
771 
772     DrmSessionManager::Instance()->useSession(sessionId);
773 
774     return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
775 }
776 
binderDied(const wp<IBinder> & the_late_who __unused)777 void Drm::binderDied(const wp<IBinder> &the_late_who __unused)
778 {
779     mEventLock.lock();
780     mListener.clear();
781     mEventLock.unlock();
782 
783     Mutex::Autolock autoLock(mLock);
784     delete mPlugin;
785     mPlugin = NULL;
786     closeFactory();
787 }
788 
writeByteArray(Parcel & obj,Vector<uint8_t> const * array)789 void Drm::writeByteArray(Parcel &obj, Vector<uint8_t> const *array)
790 {
791     if (array && array->size()) {
792         obj.writeInt32(array->size());
793         obj.write(array->array(), array->size());
794     } else {
795         obj.writeInt32(0);
796     }
797 }
798 
799 }  // namespace android
800