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