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