blob: 73dc93bf109dd73f7467d793601a12c3c0b0dec2 [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");
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800204 return NULL;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800205 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800206
Jeff Tinkerf3a591c2017-02-01 15:42:13 -0800207 ALOGD("makeDrmFactory: service is %s",
208 factory->isRemote() ? "Remote" : "Not Remote");
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800209
Jeff Tinkera53d6552017-01-20 00:31:46 -0800210 return factory;
211}
212
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800213sp<IDrmPlugin> DrmHal::makeDrmPlugin(const uint8_t uuid[16],
214 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800215 if (mFactory == NULL){
216 return NULL;
217 }
218
219 sp<IDrmPlugin> plugin;
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800220 Return<void> hResult = mFactory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800221 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800222 if (status != Status::OK) {
223 ALOGD("Failed to make drm plugin");
224 return;
225 }
226 plugin = hPlugin;
227 }
228 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800229 return plugin;
230}
231
232status_t DrmHal::initCheck() const {
233 return mInitCheck;
234}
235
236status_t DrmHal::setListener(const sp<IDrmClient>& listener)
237{
238 Mutex::Autolock lock(mEventLock);
239 if (mListener != NULL){
240 IInterface::asBinder(mListener)->unlinkToDeath(this);
241 }
242 if (listener != NULL) {
243 IInterface::asBinder(listener)->linkToDeath(this);
244 }
245 mListener = listener;
246 return NO_ERROR;
247}
248
249Return<void> DrmHal::sendEvent(EventType hEventType,
250 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
251
252 mEventLock.lock();
253 sp<IDrmClient> listener = mListener;
254 mEventLock.unlock();
255
256 if (listener != NULL) {
257 Parcel obj;
258 writeByteArray(obj, sessionId);
259 writeByteArray(obj, data);
260
261 Mutex::Autolock lock(mNotifyLock);
262 DrmPlugin::EventType eventType;
263 switch(hEventType) {
264 case EventType::PROVISION_REQUIRED:
265 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
266 break;
267 case EventType::KEY_NEEDED:
268 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
269 break;
270 case EventType::KEY_EXPIRED:
271 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
272 break;
273 case EventType::VENDOR_DEFINED:
274 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
275 break;
276 default:
277 return Void();
278 }
279 listener->notify(eventType, 0, &obj);
280 }
281 return Void();
282}
283
284Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
285 int64_t expiryTimeInMS) {
286
287 mEventLock.lock();
288 sp<IDrmClient> listener = mListener;
289 mEventLock.unlock();
290
291 if (listener != NULL) {
292 Parcel obj;
293 writeByteArray(obj, sessionId);
294 obj.writeInt64(expiryTimeInMS);
295
296 Mutex::Autolock lock(mNotifyLock);
297 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
298 }
299 return Void();
300}
301
302Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
303 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
304
305 mEventLock.lock();
306 sp<IDrmClient> listener = mListener;
307 mEventLock.unlock();
308
309 if (listener != NULL) {
310 Parcel obj;
311 writeByteArray(obj, sessionId);
312
313 size_t nKeys = keyStatusList.size();
314 obj.writeInt32(nKeys);
315 for (size_t i = 0; i < nKeys; ++i) {
316 const KeyStatus &keyStatus = keyStatusList[i];
317 writeByteArray(obj, keyStatus.keyId);
318 uint32_t type;
319 switch(keyStatus.type) {
320 case KeyStatusType::USABLE:
321 type = DrmPlugin::kKeyStatusType_Usable;
322 break;
323 case KeyStatusType::EXPIRED:
324 type = DrmPlugin::kKeyStatusType_Expired;
325 break;
326 case KeyStatusType::OUTPUTNOTALLOWED:
327 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
328 break;
329 case KeyStatusType::STATUSPENDING:
330 type = DrmPlugin::kKeyStatusType_StatusPending;
331 break;
332 case KeyStatusType::INTERNALERROR:
333 default:
334 type = DrmPlugin::kKeyStatusType_InternalError;
335 break;
336 }
337 obj.writeInt32(type);
338 }
339 obj.writeInt32(hasNewUsableKey);
340
341 Mutex::Autolock lock(mNotifyLock);
342 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
343 }
344 return Void();
345}
346
347bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
348 Mutex::Autolock autoLock(mLock);
349 bool result = false;
350
351 if (mFactory != NULL && mFactory->isCryptoSchemeSupported(uuid)) {
352 if (mimeType != "") {
353 result = mFactory->isContentTypeSupported(mimeType.string());
354 }
355 }
356 return result;
357}
358
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800359status_t DrmHal::createPlugin(const uint8_t uuid[16],
360 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800361 Mutex::Autolock autoLock(mLock);
362
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800363 mPlugin = makeDrmPlugin(uuid, appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800364
365 if (mPlugin == NULL) {
366 mInitCheck = ERROR_UNSUPPORTED;
367 } else {
368 mInitCheck = OK;
369 mPlugin->setListener(this);
370 }
371
372 return mInitCheck;
373}
374
375status_t DrmHal::destroyPlugin() {
376 Mutex::Autolock autoLock(mLock);
377
378 if (mInitCheck != OK) {
379 return mInitCheck;
380 }
381
382 setListener(NULL);
383 mPlugin.clear();
384
385 return OK;
386}
387
388status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
389 Mutex::Autolock autoLock(mLock);
390
391 if (mInitCheck != OK) {
392 return mInitCheck;
393 }
394
395 status_t err = UNKNOWN_ERROR;
396
397 bool retry = true;
398 do {
399 hidl_vec<uint8_t> hSessionId;
400
401 Return<void> hResult = mPlugin->openSession(
402 [&](Status status, const hidl_vec<uint8_t>& id) {
403 if (status == Status::OK) {
404 sessionId = toVector(id);
405 }
406 err = toStatusT(status);
407 }
408 );
409
410 if (!hResult.isOk()) {
411 err = DEAD_OBJECT;
412 }
413
414 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
415 mLock.unlock();
416 // reclaimSession may call back to closeSession, since mLock is
417 // shared between Drm instances, we should unlock here to avoid
418 // deadlock.
419 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
420 mLock.lock();
421 } else {
422 retry = false;
423 }
424 } while (retry);
425
426 if (err == OK) {
427 DrmSessionManager::Instance()->addSession(getCallingPid(),
428 mDrmSessionClient, sessionId);
429 }
430 return err;
431}
432
433status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
434 Mutex::Autolock autoLock(mLock);
435
436 if (mInitCheck != OK) {
437 return mInitCheck;
438 }
439
440 Status status = mPlugin->closeSession(toHidlVec(sessionId));
441 if (status == Status::OK) {
442 DrmSessionManager::Instance()->removeSession(sessionId);
443 }
444 return toStatusT(status);
445}
446
447status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
448 Vector<uint8_t> const &initData, String8 const &mimeType,
449 DrmPlugin::KeyType keyType, KeyedVector<String8,
450 String8> const &optionalParameters, Vector<uint8_t> &request,
451 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
452 Mutex::Autolock autoLock(mLock);
453
454 if (mInitCheck != OK) {
455 return mInitCheck;
456 }
457
458 DrmSessionManager::Instance()->useSession(sessionId);
459
460 KeyType hKeyType;
461 if (keyType == DrmPlugin::kKeyType_Streaming) {
462 hKeyType = KeyType::STREAMING;
463 } else if (keyType == DrmPlugin::kKeyType_Offline) {
464 hKeyType = KeyType::OFFLINE;
465 } else if (keyType == DrmPlugin::kKeyType_Release) {
466 hKeyType = KeyType::RELEASE;
467 } else {
468 return BAD_VALUE;
469 }
470
471 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
472
473 status_t err = UNKNOWN_ERROR;
474
475 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
476 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
477 [&](Status status, const hidl_vec<uint8_t>& hRequest,
478 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
479
480 if (status == Status::OK) {
481 request = toVector(hRequest);
482 defaultUrl = toString8(hDefaultUrl);
483
484 switch (hKeyRequestType) {
485 case KeyRequestType::INITIAL:
486 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
487 break;
488 case KeyRequestType::RENEWAL:
489 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
490 break;
491 case KeyRequestType::RELEASE:
492 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
493 break;
494 default:
495 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
496 break;
497 }
498 err = toStatusT(status);
499 }
500 });
501
502 return hResult.isOk() ? err : DEAD_OBJECT;
503}
504
505status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
506 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
507 Mutex::Autolock autoLock(mLock);
508
509 if (mInitCheck != OK) {
510 return mInitCheck;
511 }
512
513 DrmSessionManager::Instance()->useSession(sessionId);
514
515 status_t err = UNKNOWN_ERROR;
516
517 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
518 toHidlVec(response),
519 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
520 if (status == Status::OK) {
521 keySetId = toVector(hKeySetId);
522 }
523 err = toStatusT(status);
524 }
525 );
526
527 return hResult.isOk() ? err : DEAD_OBJECT;
528}
529
530status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
531 Mutex::Autolock autoLock(mLock);
532
533 if (mInitCheck != OK) {
534 return mInitCheck;
535 }
536
537 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
538}
539
540status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
541 Vector<uint8_t> const &keySetId) {
542 Mutex::Autolock autoLock(mLock);
543
544 if (mInitCheck != OK) {
545 return mInitCheck;
546 }
547
548 DrmSessionManager::Instance()->useSession(sessionId);
549
550 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
551 toHidlVec(keySetId)));
552}
553
554status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
555 KeyedVector<String8, String8> &infoMap) const {
556 Mutex::Autolock autoLock(mLock);
557
558 if (mInitCheck != OK) {
559 return mInitCheck;
560 }
561
562 DrmSessionManager::Instance()->useSession(sessionId);
563
564 ::KeyedVector hInfoMap;
565
566 status_t err = UNKNOWN_ERROR;
567
568 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
569 [&](Status status, const hidl_vec<KeyValue>& map) {
570 if (status == Status::OK) {
571 infoMap = toKeyedVector(map);
572 }
573 err = toStatusT(status);
574 }
575 );
576
577 return hResult.isOk() ? err : DEAD_OBJECT;
578}
579
580status_t DrmHal::getProvisionRequest(String8 const &certType,
581 String8 const &certAuthority, Vector<uint8_t> &request,
582 String8 &defaultUrl) {
583 Mutex::Autolock autoLock(mLock);
584
585 if (mInitCheck != OK) {
586 return mInitCheck;
587 }
588
589 status_t err = UNKNOWN_ERROR;
590
591 Return<void> hResult = mPlugin->getProvisionRequest(
592 toHidlString(certType), toHidlString(certAuthority),
593 [&](Status status, const hidl_vec<uint8_t>& hRequest,
594 const hidl_string& hDefaultUrl) {
595 if (status == Status::OK) {
596 request = toVector(hRequest);
597 defaultUrl = toString8(hDefaultUrl);
598 }
599 err = toStatusT(status);
600 }
601 );
602
603 return hResult.isOk() ? err : DEAD_OBJECT;
604}
605
606status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800607 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800608 Mutex::Autolock autoLock(mLock);
609
610 if (mInitCheck != OK) {
611 return mInitCheck;
612 }
613
614 status_t err = UNKNOWN_ERROR;
615
616 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
617 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
618 const hidl_vec<uint8_t>& hWrappedKey) {
619 if (status == Status::OK) {
620 certificate = toVector(hCertificate);
621 wrappedKey = toVector(hWrappedKey);
622 }
623 err = toStatusT(status);
624 }
625 );
626
627 return hResult.isOk() ? err : DEAD_OBJECT;
628}
629
630status_t DrmHal::getSecureStops(List<Vector<uint8_t> > &secureStops) {
631 Mutex::Autolock autoLock(mLock);
632
633 if (mInitCheck != OK) {
634 return mInitCheck;
635 }
636
637 status_t err = UNKNOWN_ERROR;
638
639 Return<void> hResult = mPlugin->getSecureStops(
640 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
641 if (status == Status::OK) {
642 secureStops = toSecureStops(hSecureStops);
643 }
644 err = toStatusT(status);
645 }
646 );
647
648 return hResult.isOk() ? err : DEAD_OBJECT;
649}
650
651
652status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
653 Mutex::Autolock autoLock(mLock);
654
655 if (mInitCheck != OK) {
656 return mInitCheck;
657 }
658
659 status_t err = UNKNOWN_ERROR;
660
661 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
662 [&](Status status, const SecureStop& hSecureStop) {
663 if (status == Status::OK) {
664 secureStop = toVector(hSecureStop.opaqueData);
665 }
666 err = toStatusT(status);
667 }
668 );
669
670 return hResult.isOk() ? err : DEAD_OBJECT;
671}
672
673status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
674 Mutex::Autolock autoLock(mLock);
675
676 if (mInitCheck != OK) {
677 return mInitCheck;
678 }
679
680 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
681}
682
683status_t DrmHal::releaseAllSecureStops() {
684 Mutex::Autolock autoLock(mLock);
685
686 if (mInitCheck != OK) {
687 return mInitCheck;
688 }
689
690 return toStatusT(mPlugin->releaseAllSecureStops());
691}
692
693status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
694 Mutex::Autolock autoLock(mLock);
695
696 if (mInitCheck != OK) {
697 return mInitCheck;
698 }
699
700 status_t err = UNKNOWN_ERROR;
701
702 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
703 [&](Status status, const hidl_string& hValue) {
704 if (status == Status::OK) {
705 value = toString8(hValue);
706 }
707 err = toStatusT(status);
708 }
709 );
710
711 return hResult.isOk() ? err : DEAD_OBJECT;
712}
713
714status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
715 Mutex::Autolock autoLock(mLock);
716
717 if (mInitCheck != OK) {
718 return mInitCheck;
719 }
720
721 status_t err = UNKNOWN_ERROR;
722
723 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
724 [&](Status status, const hidl_vec<uint8_t>& hValue) {
725 if (status == Status::OK) {
726 value = toVector(hValue);
727 }
728 err = toStatusT(status);
729 }
730 );
731
732 return hResult.isOk() ? err : DEAD_OBJECT;
733}
734
735status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
736 Mutex::Autolock autoLock(mLock);
737
738 if (mInitCheck != OK) {
739 return mInitCheck;
740 }
741
742 Status status = mPlugin->setPropertyString(toHidlString(name),
743 toHidlString(value));
744 return toStatusT(status);
745}
746
747status_t DrmHal::setPropertyByteArray(String8 const &name,
748 Vector<uint8_t> const &value ) const {
749 Mutex::Autolock autoLock(mLock);
750
751 if (mInitCheck != OK) {
752 return mInitCheck;
753 }
754
755 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
756 toHidlVec(value));
757 return toStatusT(status);
758}
759
760
761status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
762 String8 const &algorithm) {
763 Mutex::Autolock autoLock(mLock);
764
765 if (mInitCheck != OK) {
766 return mInitCheck;
767 }
768
769 DrmSessionManager::Instance()->useSession(sessionId);
770
771 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
772 toHidlString(algorithm));
773 return toStatusT(status);
774}
775
776status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
777 String8 const &algorithm) {
778 Mutex::Autolock autoLock(mLock);
779
780 if (mInitCheck != OK) {
781 return mInitCheck;
782 }
783
784 DrmSessionManager::Instance()->useSession(sessionId);
785
786 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
787 toHidlString(algorithm));
788 return toStatusT(status);
789}
790
791status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800792 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
793 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800794 Mutex::Autolock autoLock(mLock);
795
796 if (mInitCheck != OK) {
797 return mInitCheck;
798 }
799
800 DrmSessionManager::Instance()->useSession(sessionId);
801
802 status_t err = UNKNOWN_ERROR;
803
804 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
805 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
806 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
807 if (status == Status::OK) {
808 output = toVector(hOutput);
809 }
810 err = toStatusT(status);
811 }
812 );
813
814 return hResult.isOk() ? err : DEAD_OBJECT;
815}
816
817status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800818 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
819 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800820 Mutex::Autolock autoLock(mLock);
821
822 if (mInitCheck != OK) {
823 return mInitCheck;
824 }
825
826 DrmSessionManager::Instance()->useSession(sessionId);
827
828 status_t err = UNKNOWN_ERROR;
829
830 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
831 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
832 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
833 if (status == Status::OK) {
834 output = toVector(hOutput);
835 }
836 err = toStatusT(status);
837 }
838 );
839
840 return hResult.isOk() ? err : DEAD_OBJECT;
841}
842
843status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800844 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
845 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800846 Mutex::Autolock autoLock(mLock);
847
848 if (mInitCheck != OK) {
849 return mInitCheck;
850 }
851
852 DrmSessionManager::Instance()->useSession(sessionId);
853
854 status_t err = UNKNOWN_ERROR;
855
856 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
857 toHidlVec(keyId), toHidlVec(message),
858 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
859 if (status == Status::OK) {
860 signature = toVector(hSignature);
861 }
862 err = toStatusT(status);
863 }
864 );
865
866 return hResult.isOk() ? err : DEAD_OBJECT;
867}
868
869status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800870 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
871 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800872 Mutex::Autolock autoLock(mLock);
873
874 if (mInitCheck != OK) {
875 return mInitCheck;
876 }
877
878 DrmSessionManager::Instance()->useSession(sessionId);
879
880 status_t err = UNKNOWN_ERROR;
881
882 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
883 toHidlVec(message), toHidlVec(signature),
884 [&](Status status, bool hMatch) {
885 if (status == Status::OK) {
886 match = hMatch;
887 } else {
888 match = false;
889 }
890 err = toStatusT(status);
891 }
892 );
893
894 return hResult.isOk() ? err : DEAD_OBJECT;
895}
896
897status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800898 String8 const &algorithm, Vector<uint8_t> const &message,
899 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800900 Mutex::Autolock autoLock(mLock);
901
902 if (mInitCheck != OK) {
903 return mInitCheck;
904 }
905
906 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
907 return -EPERM;
908 }
909
910 DrmSessionManager::Instance()->useSession(sessionId);
911
912 status_t err = UNKNOWN_ERROR;
913
914 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
915 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
916 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
917 if (status == Status::OK) {
918 signature = toVector(hSignature);
919 }
920 err = toStatusT(status);
921 }
922 );
923
924 return hResult.isOk() ? err : DEAD_OBJECT;
925}
926
927void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
928{
929 mEventLock.lock();
930 mListener.clear();
931 mEventLock.unlock();
932
933 Mutex::Autolock autoLock(mLock);
934 mPlugin.clear();
935}
936
937void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
938{
939 if (vec.size()) {
940 obj.writeInt32(vec.size());
941 obj.write(vec.data(), vec.size());
942 } else {
943 obj.writeInt32(0);
944 }
945}
946
947} // namespace android