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> ®istered) {
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