• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "DrmHal"
19 #include <utils/Log.h>
20 
21 #include <binder/IPCThreadState.h>
22 #include <binder/IServiceManager.h>
23 
24 #include <android/hardware/drm/1.0/IDrmFactory.h>
25 #include <android/hardware/drm/1.0/IDrmPlugin.h>
26 #include <android/hardware/drm/1.0/types.h>
27 #include <android/hidl/manager/1.0/IServiceManager.h>
28 #include <hidl/ServiceManagement.h>
29 
30 #include <media/DrmHal.h>
31 #include <media/DrmSessionClientInterface.h>
32 #include <media/DrmSessionManager.h>
33 #include <media/drm/DrmAPI.h>
34 #include <media/stagefright/foundation/ADebug.h>
35 #include <media/stagefright/foundation/AString.h>
36 #include <media/stagefright/foundation/hexdump.h>
37 #include <media/stagefright/MediaErrors.h>
38 
39 using ::android::hardware::drm::V1_0::EventType;
40 using ::android::hardware::drm::V1_0::IDrmFactory;
41 using ::android::hardware::drm::V1_0::IDrmPlugin;
42 using ::android::hardware::drm::V1_0::KeyedVector;
43 using ::android::hardware::drm::V1_0::KeyRequestType;
44 using ::android::hardware::drm::V1_0::KeyStatus;
45 using ::android::hardware::drm::V1_0::KeyStatusType;
46 using ::android::hardware::drm::V1_0::KeyType;
47 using ::android::hardware::drm::V1_0::KeyValue;
48 using ::android::hardware::drm::V1_0::SecureStop;
49 using ::android::hardware::drm::V1_0::Status;
50 using ::android::hardware::hidl_array;
51 using ::android::hardware::hidl_string;
52 using ::android::hardware::hidl_vec;
53 using ::android::hardware::Return;
54 using ::android::hardware::Void;
55 using ::android::hidl::manager::V1_0::IServiceManager;
56 using ::android::sp;
57 
58 namespace android {
59 
getCallingPid()60 static inline int getCallingPid() {
61     return IPCThreadState::self()->getCallingPid();
62 }
63 
checkPermission(const char * permissionString)64 static bool checkPermission(const char* permissionString) {
65     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
66     bool ok = checkCallingPermission(String16(permissionString));
67     if (!ok) ALOGE("Request requires %s", permissionString);
68     return ok;
69 }
70 
toVector(const hidl_vec<uint8_t> & vec)71 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
72     Vector<uint8_t> vector;
73     vector.appendArray(vec.data(), vec.size());
74     return *const_cast<const Vector<uint8_t> *>(&vector);
75 }
76 
toHidlVec(const Vector<uint8_t> & vector)77 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
78     hidl_vec<uint8_t> vec;
79     vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
80     return vec;
81 }
82 
toString8(const hidl_string & string)83 static String8 toString8(const hidl_string &string) {
84     return String8(string.c_str());
85 }
86 
toHidlString(const String8 & string)87 static hidl_string toHidlString(const String8& string) {
88     return hidl_string(string.string());
89 }
90 
91 
toHidlKeyedVector(const KeyedVector<String8,String8> & keyedVector)92 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>&
93         keyedVector) {
94     std::vector<KeyValue> stdKeyedVector;
95     for (size_t i = 0; i < keyedVector.size(); i++) {
96         KeyValue keyValue;
97         keyValue.key = toHidlString(keyedVector.keyAt(i));
98         keyValue.value = toHidlString(keyedVector.valueAt(i));
99         stdKeyedVector.push_back(keyValue);
100     }
101     return ::KeyedVector(stdKeyedVector);
102 }
103 
toKeyedVector(const::KeyedVector & hKeyedVector)104 static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector&
105         hKeyedVector) {
106     KeyedVector<String8, String8> keyedVector;
107     for (size_t i = 0; i < hKeyedVector.size(); i++) {
108         keyedVector.add(toString8(hKeyedVector[i].key),
109                 toString8(hKeyedVector[i].value));
110     }
111     return keyedVector;
112 }
113 
toSecureStops(const hidl_vec<SecureStop> & hSecureStops)114 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
115         hSecureStops) {
116     List<Vector<uint8_t>> secureStops;
117     for (size_t i = 0; i < hSecureStops.size(); i++) {
118         secureStops.push_back(toVector(hSecureStops[i].opaqueData));
119     }
120     return secureStops;
121 }
122 
toStatusT(Status status)123 static status_t toStatusT(Status status) {
124     switch (status) {
125     case Status::OK:
126         return OK;
127         break;
128     case Status::ERROR_DRM_NO_LICENSE:
129         return ERROR_DRM_NO_LICENSE;
130         break;
131     case Status::ERROR_DRM_LICENSE_EXPIRED:
132         return ERROR_DRM_LICENSE_EXPIRED;
133         break;
134     case Status::ERROR_DRM_SESSION_NOT_OPENED:
135         return ERROR_DRM_SESSION_NOT_OPENED;
136         break;
137     case Status::ERROR_DRM_CANNOT_HANDLE:
138         return ERROR_DRM_CANNOT_HANDLE;
139         break;
140     case Status::ERROR_DRM_INVALID_STATE:
141         return ERROR_DRM_TAMPER_DETECTED;
142         break;
143     case Status::BAD_VALUE:
144         return BAD_VALUE;
145         break;
146     case Status::ERROR_DRM_NOT_PROVISIONED:
147         return ERROR_DRM_NOT_PROVISIONED;
148         break;
149     case Status::ERROR_DRM_RESOURCE_BUSY:
150         return ERROR_DRM_RESOURCE_BUSY;
151         break;
152     case Status::ERROR_DRM_DEVICE_REVOKED:
153         return ERROR_DRM_DEVICE_REVOKED;
154         break;
155     case Status::ERROR_DRM_UNKNOWN:
156     default:
157         return ERROR_DRM_UNKNOWN;
158         break;
159     }
160 }
161 
162 
163 Mutex DrmHal::mLock;
164 
165 struct DrmSessionClient : public DrmSessionClientInterface {
DrmSessionClientandroid::DrmSessionClient166     explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {}
167 
reclaimSessionandroid::DrmSessionClient168     virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
169         sp<DrmHal> drm = mDrm.promote();
170         if (drm == NULL) {
171             return true;
172         }
173         status_t err = drm->closeSession(sessionId);
174         if (err != OK) {
175             return false;
176         }
177         drm->sendEvent(EventType::SESSION_RECLAIMED,
178                 toHidlVec(sessionId), hidl_vec<uint8_t>());
179         return true;
180     }
181 
182 protected:
~DrmSessionClientandroid::DrmSessionClient183     virtual ~DrmSessionClient() {}
184 
185 private:
186     wp<DrmHal> mDrm;
187 
188     DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
189 };
190 
DrmHal()191 DrmHal::DrmHal()
192    : mDrmSessionClient(new DrmSessionClient(this)),
193      mFactories(makeDrmFactories()),
194      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
195 }
196 
~DrmHal()197 DrmHal::~DrmHal() {
198     DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
199 }
200 
makeDrmFactories()201 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
202     Vector<sp<IDrmFactory>> factories;
203 
204     auto manager = hardware::defaultServiceManager();
205 
206     if (manager != NULL) {
207         manager->listByInterface(IDrmFactory::descriptor,
208                 [&factories](const hidl_vec<hidl_string> &registered) {
209                     for (const auto &instance : registered) {
210                         auto factory = IDrmFactory::getService(instance);
211                         if (factory != NULL) {
212                             factories.push_back(factory);
213                             ALOGI("makeDrmFactories: factory instance %s is %s",
214                                     instance.c_str(),
215                                     factory->isRemote() ? "Remote" : "Not Remote");
216                         }
217                     }
218                 }
219             );
220     }
221 
222     if (factories.size() == 0) {
223         // must be in passthrough mode, load the default passthrough service
224         auto passthrough = IDrmFactory::getService();
225         if (passthrough != NULL) {
226             ALOGI("makeDrmFactories: using default drm instance");
227             factories.push_back(passthrough);
228         } else {
229             ALOGE("Failed to find any drm factories");
230         }
231     }
232     return factories;
233 }
234 
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)235 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
236         const uint8_t uuid[16], const String8& appPackageName) {
237 
238     sp<IDrmPlugin> plugin;
239     Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
240             [&](Status status, const sp<IDrmPlugin>& hPlugin) {
241                 if (status != Status::OK) {
242                     ALOGE("Failed to make drm plugin");
243                     return;
244                 }
245                 plugin = hPlugin;
246             }
247         );
248     return plugin;
249 }
250 
initCheck() const251 status_t DrmHal::initCheck() const {
252     return mInitCheck;
253 }
254 
setListener(const sp<IDrmClient> & listener)255 status_t DrmHal::setListener(const sp<IDrmClient>& listener)
256 {
257     Mutex::Autolock lock(mEventLock);
258     if (mListener != NULL){
259         IInterface::asBinder(mListener)->unlinkToDeath(this);
260     }
261     if (listener != NULL) {
262         IInterface::asBinder(listener)->linkToDeath(this);
263     }
264     mListener = listener;
265     return NO_ERROR;
266 }
267 
sendEvent(EventType hEventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)268 Return<void> DrmHal::sendEvent(EventType hEventType,
269         const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
270 
271     mEventLock.lock();
272     sp<IDrmClient> listener = mListener;
273     mEventLock.unlock();
274 
275     if (listener != NULL) {
276         Parcel obj;
277         writeByteArray(obj, sessionId);
278         writeByteArray(obj, data);
279 
280         Mutex::Autolock lock(mNotifyLock);
281         DrmPlugin::EventType eventType;
282         switch(hEventType) {
283         case EventType::PROVISION_REQUIRED:
284             eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
285             break;
286         case EventType::KEY_NEEDED:
287             eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
288             break;
289         case EventType::KEY_EXPIRED:
290             eventType = DrmPlugin::kDrmPluginEventKeyExpired;
291             break;
292         case EventType::VENDOR_DEFINED:
293             eventType = DrmPlugin::kDrmPluginEventVendorDefined;
294             break;
295         case EventType::SESSION_RECLAIMED:
296             eventType = DrmPlugin::kDrmPluginEventSessionReclaimed;
297             break;
298         default:
299             return Void();
300         }
301         listener->notify(eventType, 0, &obj);
302     }
303     return Void();
304 }
305 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)306 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
307         int64_t expiryTimeInMS) {
308 
309     mEventLock.lock();
310     sp<IDrmClient> listener = mListener;
311     mEventLock.unlock();
312 
313     if (listener != NULL) {
314         Parcel obj;
315         writeByteArray(obj, sessionId);
316         obj.writeInt64(expiryTimeInMS);
317 
318         Mutex::Autolock lock(mNotifyLock);
319         listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
320     }
321     return Void();
322 }
323 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)324 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
325         const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
326 
327     mEventLock.lock();
328     sp<IDrmClient> listener = mListener;
329     mEventLock.unlock();
330 
331     if (listener != NULL) {
332         Parcel obj;
333         writeByteArray(obj, sessionId);
334 
335         size_t nKeys = keyStatusList.size();
336         obj.writeInt32(nKeys);
337         for (size_t i = 0; i < nKeys; ++i) {
338             const KeyStatus &keyStatus = keyStatusList[i];
339             writeByteArray(obj, keyStatus.keyId);
340             uint32_t type;
341             switch(keyStatus.type) {
342             case KeyStatusType::USABLE:
343                 type = DrmPlugin::kKeyStatusType_Usable;
344                 break;
345             case KeyStatusType::EXPIRED:
346                 type = DrmPlugin::kKeyStatusType_Expired;
347                 break;
348             case KeyStatusType::OUTPUTNOTALLOWED:
349                 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
350                 break;
351             case KeyStatusType::STATUSPENDING:
352                 type = DrmPlugin::kKeyStatusType_StatusPending;
353                 break;
354             case KeyStatusType::INTERNALERROR:
355             default:
356                 type = DrmPlugin::kKeyStatusType_InternalError;
357                 break;
358             }
359             obj.writeInt32(type);
360         }
361         obj.writeInt32(hasNewUsableKey);
362 
363         Mutex::Autolock lock(mNotifyLock);
364         listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
365     }
366     return Void();
367 }
368 
isCryptoSchemeSupported(const uint8_t uuid[16],const String8 & mimeType)369 bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
370     Mutex::Autolock autoLock(mLock);
371 
372     for (size_t i = 0; i < mFactories.size(); i++) {
373         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
374             if (mimeType != "") {
375                 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
376                     return true;
377                 }
378             } else {
379                 return true;
380             }
381         }
382     }
383     return false;
384 }
385 
createPlugin(const uint8_t uuid[16],const String8 & appPackageName)386 status_t DrmHal::createPlugin(const uint8_t uuid[16],
387         const String8& appPackageName) {
388     Mutex::Autolock autoLock(mLock);
389 
390     for (size_t i = 0; i < mFactories.size(); i++) {
391         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
392             mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
393         }
394     }
395 
396     if (mPlugin == NULL) {
397         mInitCheck = ERROR_UNSUPPORTED;
398     } else {
399         mInitCheck = OK;
400         mPlugin->setListener(this);
401     }
402 
403     return mInitCheck;
404 }
405 
destroyPlugin()406 status_t DrmHal::destroyPlugin() {
407     Mutex::Autolock autoLock(mLock);
408 
409     if (mInitCheck != OK) {
410         return mInitCheck;
411     }
412 
413     setListener(NULL);
414     if (mPlugin != NULL) {
415         mPlugin->setListener(NULL);
416     }
417     mPlugin.clear();
418     mInitCheck = NO_INIT;
419 
420     return OK;
421 }
422 
openSession(Vector<uint8_t> & sessionId)423 status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
424     Mutex::Autolock autoLock(mLock);
425 
426     if (mInitCheck != OK) {
427         return mInitCheck;
428     }
429 
430     status_t  err = UNKNOWN_ERROR;
431 
432     bool retry = true;
433     do {
434         hidl_vec<uint8_t> hSessionId;
435 
436         Return<void> hResult = mPlugin->openSession(
437                 [&](Status status, const hidl_vec<uint8_t>& id) {
438                     if (status == Status::OK) {
439                         sessionId = toVector(id);
440                     }
441                     err = toStatusT(status);
442                 }
443             );
444 
445         if (!hResult.isOk()) {
446             err = DEAD_OBJECT;
447         }
448 
449         if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
450             mLock.unlock();
451             // reclaimSession may call back to closeSession, since mLock is
452             // shared between Drm instances, we should unlock here to avoid
453             // deadlock.
454             retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
455             mLock.lock();
456         } else {
457             retry = false;
458         }
459     } while (retry);
460 
461     if (err == OK) {
462         DrmSessionManager::Instance()->addSession(getCallingPid(),
463                 mDrmSessionClient, sessionId);
464     }
465     return err;
466 }
467 
closeSession(Vector<uint8_t> const & sessionId)468 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
469     Mutex::Autolock autoLock(mLock);
470 
471     if (mInitCheck != OK) {
472         return mInitCheck;
473     }
474 
475     Status status = mPlugin->closeSession(toHidlVec(sessionId));
476     if (status == Status::OK) {
477         DrmSessionManager::Instance()->removeSession(sessionId);
478     }
479     return toStatusT(status);
480 }
481 
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)482 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
483         Vector<uint8_t> const &initData, String8 const &mimeType,
484         DrmPlugin::KeyType keyType, KeyedVector<String8,
485         String8> const &optionalParameters, Vector<uint8_t> &request,
486         String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
487     Mutex::Autolock autoLock(mLock);
488 
489     if (mInitCheck != OK) {
490         return mInitCheck;
491     }
492 
493     DrmSessionManager::Instance()->useSession(sessionId);
494 
495     KeyType hKeyType;
496     if (keyType == DrmPlugin::kKeyType_Streaming) {
497         hKeyType = KeyType::STREAMING;
498     } else if (keyType == DrmPlugin::kKeyType_Offline) {
499         hKeyType = KeyType::OFFLINE;
500     } else if (keyType == DrmPlugin::kKeyType_Release) {
501         hKeyType = KeyType::RELEASE;
502     } else {
503         return BAD_VALUE;
504     }
505 
506     ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
507 
508     status_t err = UNKNOWN_ERROR;
509 
510     Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
511             toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
512             [&](Status status, const hidl_vec<uint8_t>& hRequest,
513                     KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
514 
515                 if (status == Status::OK) {
516                     request = toVector(hRequest);
517                     defaultUrl = toString8(hDefaultUrl);
518 
519                     switch (hKeyRequestType) {
520                     case KeyRequestType::INITIAL:
521                         *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
522                         break;
523                     case KeyRequestType::RENEWAL:
524                         *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
525                         break;
526                     case KeyRequestType::RELEASE:
527                         *keyRequestType = DrmPlugin::kKeyRequestType_Release;
528                         break;
529                     default:
530                         *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
531                         break;
532                     }
533                     err = toStatusT(status);
534                 }
535             });
536 
537     return hResult.isOk() ? err : DEAD_OBJECT;
538 }
539 
provideKeyResponse(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & response,Vector<uint8_t> & keySetId)540 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
541         Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
542     Mutex::Autolock autoLock(mLock);
543 
544     if (mInitCheck != OK) {
545         return mInitCheck;
546     }
547 
548     DrmSessionManager::Instance()->useSession(sessionId);
549 
550     status_t err = UNKNOWN_ERROR;
551 
552     Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
553             toHidlVec(response),
554             [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
555                 if (status == Status::OK) {
556                     keySetId = toVector(hKeySetId);
557                 }
558                 err = toStatusT(status);
559             }
560         );
561 
562     return hResult.isOk() ? err : DEAD_OBJECT;
563 }
564 
removeKeys(Vector<uint8_t> const & keySetId)565 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
566     Mutex::Autolock autoLock(mLock);
567 
568     if (mInitCheck != OK) {
569         return mInitCheck;
570     }
571 
572     return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
573 }
574 
restoreKeys(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keySetId)575 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
576         Vector<uint8_t> const &keySetId) {
577     Mutex::Autolock autoLock(mLock);
578 
579     if (mInitCheck != OK) {
580         return mInitCheck;
581     }
582 
583     DrmSessionManager::Instance()->useSession(sessionId);
584 
585     return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
586                     toHidlVec(keySetId)));
587 }
588 
queryKeyStatus(Vector<uint8_t> const & sessionId,KeyedVector<String8,String8> & infoMap) const589 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
590         KeyedVector<String8, String8> &infoMap) const {
591     Mutex::Autolock autoLock(mLock);
592 
593     if (mInitCheck != OK) {
594         return mInitCheck;
595     }
596 
597     DrmSessionManager::Instance()->useSession(sessionId);
598 
599     ::KeyedVector hInfoMap;
600 
601     status_t err = UNKNOWN_ERROR;
602 
603     Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
604             [&](Status status, const hidl_vec<KeyValue>& map) {
605                 if (status == Status::OK) {
606                     infoMap = toKeyedVector(map);
607                 }
608                 err = toStatusT(status);
609             }
610         );
611 
612     return hResult.isOk() ? err : DEAD_OBJECT;
613 }
614 
getProvisionRequest(String8 const & certType,String8 const & certAuthority,Vector<uint8_t> & request,String8 & defaultUrl)615 status_t DrmHal::getProvisionRequest(String8 const &certType,
616         String8 const &certAuthority, Vector<uint8_t> &request,
617         String8 &defaultUrl) {
618     Mutex::Autolock autoLock(mLock);
619 
620     if (mInitCheck != OK) {
621         return mInitCheck;
622     }
623 
624     status_t err = UNKNOWN_ERROR;
625 
626     Return<void> hResult = mPlugin->getProvisionRequest(
627             toHidlString(certType), toHidlString(certAuthority),
628             [&](Status status, const hidl_vec<uint8_t>& hRequest,
629                     const hidl_string& hDefaultUrl) {
630                 if (status == Status::OK) {
631                     request = toVector(hRequest);
632                     defaultUrl = toString8(hDefaultUrl);
633                 }
634                 err = toStatusT(status);
635             }
636         );
637 
638     return hResult.isOk() ? err : DEAD_OBJECT;
639 }
640 
provideProvisionResponse(Vector<uint8_t> const & response,Vector<uint8_t> & certificate,Vector<uint8_t> & wrappedKey)641 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
642         Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
643     Mutex::Autolock autoLock(mLock);
644 
645     if (mInitCheck != OK) {
646         return mInitCheck;
647     }
648 
649     status_t err = UNKNOWN_ERROR;
650 
651     Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
652             [&](Status status, const hidl_vec<uint8_t>& hCertificate,
653                     const hidl_vec<uint8_t>& hWrappedKey) {
654                 if (status == Status::OK) {
655                     certificate = toVector(hCertificate);
656                     wrappedKey = toVector(hWrappedKey);
657                 }
658                 err = toStatusT(status);
659             }
660         );
661 
662     return hResult.isOk() ? err : DEAD_OBJECT;
663 }
664 
getSecureStops(List<Vector<uint8_t>> & secureStops)665 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
666     Mutex::Autolock autoLock(mLock);
667 
668     if (mInitCheck != OK) {
669         return mInitCheck;
670     }
671 
672     status_t err = UNKNOWN_ERROR;
673 
674     Return<void> hResult = mPlugin->getSecureStops(
675             [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
676                 if (status == Status::OK) {
677                     secureStops = toSecureStops(hSecureStops);
678                 }
679                 err = toStatusT(status);
680             }
681     );
682 
683     return hResult.isOk() ? err : DEAD_OBJECT;
684 }
685 
686 
getSecureStop(Vector<uint8_t> const & ssid,Vector<uint8_t> & secureStop)687 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
688     Mutex::Autolock autoLock(mLock);
689 
690     if (mInitCheck != OK) {
691         return mInitCheck;
692     }
693 
694     status_t err = UNKNOWN_ERROR;
695 
696     Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
697             [&](Status status, const SecureStop& hSecureStop) {
698                 if (status == Status::OK) {
699                     secureStop = toVector(hSecureStop.opaqueData);
700                 }
701                 err = toStatusT(status);
702             }
703     );
704 
705     return hResult.isOk() ? err : DEAD_OBJECT;
706 }
707 
releaseSecureStops(Vector<uint8_t> const & ssRelease)708 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
709     Mutex::Autolock autoLock(mLock);
710 
711     if (mInitCheck != OK) {
712         return mInitCheck;
713     }
714 
715     return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
716 }
717 
releaseAllSecureStops()718 status_t DrmHal::releaseAllSecureStops() {
719     Mutex::Autolock autoLock(mLock);
720 
721     if (mInitCheck != OK) {
722         return mInitCheck;
723     }
724 
725     return toStatusT(mPlugin->releaseAllSecureStops());
726 }
727 
getPropertyString(String8 const & name,String8 & value) const728 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
729     Mutex::Autolock autoLock(mLock);
730 
731     if (mInitCheck != OK) {
732         return mInitCheck;
733     }
734 
735     status_t err = UNKNOWN_ERROR;
736 
737     Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
738             [&](Status status, const hidl_string& hValue) {
739                 if (status == Status::OK) {
740                     value = toString8(hValue);
741                 }
742                 err = toStatusT(status);
743             }
744     );
745 
746     return hResult.isOk() ? err : DEAD_OBJECT;
747 }
748 
getPropertyByteArray(String8 const & name,Vector<uint8_t> & value) const749 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
750     Mutex::Autolock autoLock(mLock);
751 
752     if (mInitCheck != OK) {
753         return mInitCheck;
754     }
755 
756     status_t err = UNKNOWN_ERROR;
757 
758     Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
759             [&](Status status, const hidl_vec<uint8_t>& hValue) {
760                 if (status == Status::OK) {
761                     value = toVector(hValue);
762                 }
763                 err = toStatusT(status);
764             }
765     );
766 
767     return hResult.isOk() ? err : DEAD_OBJECT;
768 }
769 
setPropertyString(String8 const & name,String8 const & value) const770 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
771     Mutex::Autolock autoLock(mLock);
772 
773     if (mInitCheck != OK) {
774         return mInitCheck;
775     }
776 
777     Status status =  mPlugin->setPropertyString(toHidlString(name),
778             toHidlString(value));
779     return toStatusT(status);
780 }
781 
setPropertyByteArray(String8 const & name,Vector<uint8_t> const & value) const782 status_t DrmHal::setPropertyByteArray(String8 const &name,
783                                    Vector<uint8_t> const &value ) const {
784     Mutex::Autolock autoLock(mLock);
785 
786     if (mInitCheck != OK) {
787         return mInitCheck;
788     }
789 
790     Status status = mPlugin->setPropertyByteArray(toHidlString(name),
791             toHidlVec(value));
792     return toStatusT(status);
793 }
794 
795 
setCipherAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)796 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
797                                  String8 const &algorithm) {
798     Mutex::Autolock autoLock(mLock);
799 
800     if (mInitCheck != OK) {
801         return mInitCheck;
802     }
803 
804     DrmSessionManager::Instance()->useSession(sessionId);
805 
806     Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
807             toHidlString(algorithm));
808     return toStatusT(status);
809 }
810 
setMacAlgorithm(Vector<uint8_t> const & sessionId,String8 const & algorithm)811 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
812                               String8 const &algorithm) {
813     Mutex::Autolock autoLock(mLock);
814 
815     if (mInitCheck != OK) {
816         return mInitCheck;
817     }
818 
819     DrmSessionManager::Instance()->useSession(sessionId);
820 
821     Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
822             toHidlString(algorithm));
823     return toStatusT(status);
824 }
825 
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)826 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
827         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
828         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
829     Mutex::Autolock autoLock(mLock);
830 
831     if (mInitCheck != OK) {
832         return mInitCheck;
833     }
834 
835     DrmSessionManager::Instance()->useSession(sessionId);
836 
837     status_t err = UNKNOWN_ERROR;
838 
839     Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
840             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
841             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
842                 if (status == Status::OK) {
843                     output = toVector(hOutput);
844                 }
845                 err = toStatusT(status);
846             }
847     );
848 
849     return hResult.isOk() ? err : DEAD_OBJECT;
850 }
851 
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)852 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
853         Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
854         Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
855     Mutex::Autolock autoLock(mLock);
856 
857     if (mInitCheck != OK) {
858         return mInitCheck;
859     }
860 
861     DrmSessionManager::Instance()->useSession(sessionId);
862 
863     status_t  err = UNKNOWN_ERROR;
864 
865     Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
866             toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
867             [&](Status status, const hidl_vec<uint8_t>& hOutput) {
868                 if (status == Status::OK) {
869                     output = toVector(hOutput);
870                 }
871                 err = toStatusT(status);
872             }
873     );
874 
875     return hResult.isOk() ? err : DEAD_OBJECT;
876 }
877 
sign(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> & signature)878 status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
879         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
880         Vector<uint8_t> &signature) {
881     Mutex::Autolock autoLock(mLock);
882 
883     if (mInitCheck != OK) {
884         return mInitCheck;
885     }
886 
887     DrmSessionManager::Instance()->useSession(sessionId);
888 
889     status_t err = UNKNOWN_ERROR;
890 
891     Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
892             toHidlVec(keyId), toHidlVec(message),
893             [&](Status status, const hidl_vec<uint8_t>& hSignature)  {
894                 if (status == Status::OK) {
895                     signature = toVector(hSignature);
896                 }
897                 err = toStatusT(status);
898             }
899     );
900 
901     return hResult.isOk() ? err : DEAD_OBJECT;
902 }
903 
verify(Vector<uint8_t> const & sessionId,Vector<uint8_t> const & keyId,Vector<uint8_t> const & message,Vector<uint8_t> const & signature,bool & match)904 status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
905         Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
906         Vector<uint8_t> const &signature, bool &match) {
907     Mutex::Autolock autoLock(mLock);
908 
909     if (mInitCheck != OK) {
910         return mInitCheck;
911     }
912 
913     DrmSessionManager::Instance()->useSession(sessionId);
914 
915     status_t err = UNKNOWN_ERROR;
916 
917     Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
918             toHidlVec(message), toHidlVec(signature),
919             [&](Status status, bool hMatch) {
920                 if (status == Status::OK) {
921                     match = hMatch;
922                 } else {
923                     match = false;
924                 }
925                 err = toStatusT(status);
926             }
927     );
928 
929     return hResult.isOk() ? err : DEAD_OBJECT;
930 }
931 
signRSA(Vector<uint8_t> const & sessionId,String8 const & algorithm,Vector<uint8_t> const & message,Vector<uint8_t> const & wrappedKey,Vector<uint8_t> & signature)932 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
933         String8 const &algorithm, Vector<uint8_t> const &message,
934         Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
935     Mutex::Autolock autoLock(mLock);
936 
937     if (mInitCheck != OK) {
938         return mInitCheck;
939     }
940 
941     if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
942         return -EPERM;
943     }
944 
945     DrmSessionManager::Instance()->useSession(sessionId);
946 
947     status_t err = UNKNOWN_ERROR;
948 
949     Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
950             toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
951             [&](Status status, const hidl_vec<uint8_t>& hSignature) {
952                 if (status == Status::OK) {
953                     signature = toVector(hSignature);
954                 }
955                 err = toStatusT(status);
956             }
957         );
958 
959     return hResult.isOk() ? err : DEAD_OBJECT;
960 }
961 
binderDied(const wp<IBinder> & the_late_who __unused)962 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
963 {
964     Mutex::Autolock autoLock(mLock);
965     setListener(NULL);
966     if (mPlugin != NULL) {
967         mPlugin->setListener(NULL);
968     }
969     mPlugin.clear();
970     mInitCheck = NO_INIT;
971 }
972 
writeByteArray(Parcel & obj,hidl_vec<uint8_t> const & vec)973 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
974 {
975     if (vec.size()) {
976         obj.writeInt32(vec.size());
977         obj.write(vec.data(), vec.size());
978     } else {
979         obj.writeInt32(0);
980     }
981 }
982 
983 }  // namespace android
984