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