blob: 8200d550be66f4688e44098b67bacadc5dc1e425 [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)) {
Edwin Wong38875a42017-02-15 18:21:48 -0800352 result = true;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800353 if (mimeType != "") {
354 result = mFactory->isContentTypeSupported(mimeType.string());
355 }
356 }
357 return result;
358}
359
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800360status_t DrmHal::createPlugin(const uint8_t uuid[16],
361 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800362 Mutex::Autolock autoLock(mLock);
363
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800364 mPlugin = makeDrmPlugin(uuid, appPackageName);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800365
366 if (mPlugin == NULL) {
367 mInitCheck = ERROR_UNSUPPORTED;
368 } else {
369 mInitCheck = OK;
370 mPlugin->setListener(this);
371 }
372
373 return mInitCheck;
374}
375
376status_t DrmHal::destroyPlugin() {
377 Mutex::Autolock autoLock(mLock);
378
379 if (mInitCheck != OK) {
380 return mInitCheck;
381 }
382
383 setListener(NULL);
384 mPlugin.clear();
385
386 return OK;
387}
388
389status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
390 Mutex::Autolock autoLock(mLock);
391
392 if (mInitCheck != OK) {
393 return mInitCheck;
394 }
395
396 status_t err = UNKNOWN_ERROR;
397
398 bool retry = true;
399 do {
400 hidl_vec<uint8_t> hSessionId;
401
402 Return<void> hResult = mPlugin->openSession(
403 [&](Status status, const hidl_vec<uint8_t>& id) {
404 if (status == Status::OK) {
405 sessionId = toVector(id);
406 }
407 err = toStatusT(status);
408 }
409 );
410
411 if (!hResult.isOk()) {
412 err = DEAD_OBJECT;
413 }
414
415 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
416 mLock.unlock();
417 // reclaimSession may call back to closeSession, since mLock is
418 // shared between Drm instances, we should unlock here to avoid
419 // deadlock.
420 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
421 mLock.lock();
422 } else {
423 retry = false;
424 }
425 } while (retry);
426
427 if (err == OK) {
428 DrmSessionManager::Instance()->addSession(getCallingPid(),
429 mDrmSessionClient, sessionId);
430 }
431 return err;
432}
433
434status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
435 Mutex::Autolock autoLock(mLock);
436
437 if (mInitCheck != OK) {
438 return mInitCheck;
439 }
440
441 Status status = mPlugin->closeSession(toHidlVec(sessionId));
442 if (status == Status::OK) {
443 DrmSessionManager::Instance()->removeSession(sessionId);
444 }
445 return toStatusT(status);
446}
447
448status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
449 Vector<uint8_t> const &initData, String8 const &mimeType,
450 DrmPlugin::KeyType keyType, KeyedVector<String8,
451 String8> const &optionalParameters, Vector<uint8_t> &request,
452 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
453 Mutex::Autolock autoLock(mLock);
454
455 if (mInitCheck != OK) {
456 return mInitCheck;
457 }
458
459 DrmSessionManager::Instance()->useSession(sessionId);
460
461 KeyType hKeyType;
462 if (keyType == DrmPlugin::kKeyType_Streaming) {
463 hKeyType = KeyType::STREAMING;
464 } else if (keyType == DrmPlugin::kKeyType_Offline) {
465 hKeyType = KeyType::OFFLINE;
466 } else if (keyType == DrmPlugin::kKeyType_Release) {
467 hKeyType = KeyType::RELEASE;
468 } else {
469 return BAD_VALUE;
470 }
471
472 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
473
474 status_t err = UNKNOWN_ERROR;
475
476 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
477 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
478 [&](Status status, const hidl_vec<uint8_t>& hRequest,
479 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
480
481 if (status == Status::OK) {
482 request = toVector(hRequest);
483 defaultUrl = toString8(hDefaultUrl);
484
485 switch (hKeyRequestType) {
486 case KeyRequestType::INITIAL:
487 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
488 break;
489 case KeyRequestType::RENEWAL:
490 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
491 break;
492 case KeyRequestType::RELEASE:
493 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
494 break;
495 default:
496 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
497 break;
498 }
499 err = toStatusT(status);
500 }
501 });
502
503 return hResult.isOk() ? err : DEAD_OBJECT;
504}
505
506status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
507 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
508 Mutex::Autolock autoLock(mLock);
509
510 if (mInitCheck != OK) {
511 return mInitCheck;
512 }
513
514 DrmSessionManager::Instance()->useSession(sessionId);
515
516 status_t err = UNKNOWN_ERROR;
517
518 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
519 toHidlVec(response),
520 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
521 if (status == Status::OK) {
522 keySetId = toVector(hKeySetId);
523 }
524 err = toStatusT(status);
525 }
526 );
527
528 return hResult.isOk() ? err : DEAD_OBJECT;
529}
530
531status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
532 Mutex::Autolock autoLock(mLock);
533
534 if (mInitCheck != OK) {
535 return mInitCheck;
536 }
537
538 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
539}
540
541status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
542 Vector<uint8_t> const &keySetId) {
543 Mutex::Autolock autoLock(mLock);
544
545 if (mInitCheck != OK) {
546 return mInitCheck;
547 }
548
549 DrmSessionManager::Instance()->useSession(sessionId);
550
551 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
552 toHidlVec(keySetId)));
553}
554
555status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
556 KeyedVector<String8, String8> &infoMap) const {
557 Mutex::Autolock autoLock(mLock);
558
559 if (mInitCheck != OK) {
560 return mInitCheck;
561 }
562
563 DrmSessionManager::Instance()->useSession(sessionId);
564
565 ::KeyedVector hInfoMap;
566
567 status_t err = UNKNOWN_ERROR;
568
569 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
570 [&](Status status, const hidl_vec<KeyValue>& map) {
571 if (status == Status::OK) {
572 infoMap = toKeyedVector(map);
573 }
574 err = toStatusT(status);
575 }
576 );
577
578 return hResult.isOk() ? err : DEAD_OBJECT;
579}
580
581status_t DrmHal::getProvisionRequest(String8 const &certType,
582 String8 const &certAuthority, Vector<uint8_t> &request,
583 String8 &defaultUrl) {
584 Mutex::Autolock autoLock(mLock);
585
586 if (mInitCheck != OK) {
587 return mInitCheck;
588 }
589
590 status_t err = UNKNOWN_ERROR;
591
592 Return<void> hResult = mPlugin->getProvisionRequest(
593 toHidlString(certType), toHidlString(certAuthority),
594 [&](Status status, const hidl_vec<uint8_t>& hRequest,
595 const hidl_string& hDefaultUrl) {
596 if (status == Status::OK) {
597 request = toVector(hRequest);
598 defaultUrl = toString8(hDefaultUrl);
599 }
600 err = toStatusT(status);
601 }
602 );
603
604 return hResult.isOk() ? err : DEAD_OBJECT;
605}
606
607status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800608 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800609 Mutex::Autolock autoLock(mLock);
610
611 if (mInitCheck != OK) {
612 return mInitCheck;
613 }
614
615 status_t err = UNKNOWN_ERROR;
616
617 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
618 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
619 const hidl_vec<uint8_t>& hWrappedKey) {
620 if (status == Status::OK) {
621 certificate = toVector(hCertificate);
622 wrappedKey = toVector(hWrappedKey);
623 }
624 err = toStatusT(status);
625 }
626 );
627
628 return hResult.isOk() ? err : DEAD_OBJECT;
629}
630
631status_t DrmHal::getSecureStops(List<Vector<uint8_t> > &secureStops) {
632 Mutex::Autolock autoLock(mLock);
633
634 if (mInitCheck != OK) {
635 return mInitCheck;
636 }
637
638 status_t err = UNKNOWN_ERROR;
639
640 Return<void> hResult = mPlugin->getSecureStops(
641 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
642 if (status == Status::OK) {
643 secureStops = toSecureStops(hSecureStops);
644 }
645 err = toStatusT(status);
646 }
647 );
648
649 return hResult.isOk() ? err : DEAD_OBJECT;
650}
651
652
653status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
654 Mutex::Autolock autoLock(mLock);
655
656 if (mInitCheck != OK) {
657 return mInitCheck;
658 }
659
660 status_t err = UNKNOWN_ERROR;
661
662 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
663 [&](Status status, const SecureStop& hSecureStop) {
664 if (status == Status::OK) {
665 secureStop = toVector(hSecureStop.opaqueData);
666 }
667 err = toStatusT(status);
668 }
669 );
670
671 return hResult.isOk() ? err : DEAD_OBJECT;
672}
673
674status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
675 Mutex::Autolock autoLock(mLock);
676
677 if (mInitCheck != OK) {
678 return mInitCheck;
679 }
680
681 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
682}
683
684status_t DrmHal::releaseAllSecureStops() {
685 Mutex::Autolock autoLock(mLock);
686
687 if (mInitCheck != OK) {
688 return mInitCheck;
689 }
690
691 return toStatusT(mPlugin->releaseAllSecureStops());
692}
693
694status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
695 Mutex::Autolock autoLock(mLock);
696
697 if (mInitCheck != OK) {
698 return mInitCheck;
699 }
700
701 status_t err = UNKNOWN_ERROR;
702
703 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
704 [&](Status status, const hidl_string& hValue) {
705 if (status == Status::OK) {
706 value = toString8(hValue);
707 }
708 err = toStatusT(status);
709 }
710 );
711
712 return hResult.isOk() ? err : DEAD_OBJECT;
713}
714
715status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
716 Mutex::Autolock autoLock(mLock);
717
718 if (mInitCheck != OK) {
719 return mInitCheck;
720 }
721
722 status_t err = UNKNOWN_ERROR;
723
724 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
725 [&](Status status, const hidl_vec<uint8_t>& hValue) {
726 if (status == Status::OK) {
727 value = toVector(hValue);
728 }
729 err = toStatusT(status);
730 }
731 );
732
733 return hResult.isOk() ? err : DEAD_OBJECT;
734}
735
736status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
737 Mutex::Autolock autoLock(mLock);
738
739 if (mInitCheck != OK) {
740 return mInitCheck;
741 }
742
743 Status status = mPlugin->setPropertyString(toHidlString(name),
744 toHidlString(value));
745 return toStatusT(status);
746}
747
748status_t DrmHal::setPropertyByteArray(String8 const &name,
749 Vector<uint8_t> const &value ) const {
750 Mutex::Autolock autoLock(mLock);
751
752 if (mInitCheck != OK) {
753 return mInitCheck;
754 }
755
756 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
757 toHidlVec(value));
758 return toStatusT(status);
759}
760
761
762status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
763 String8 const &algorithm) {
764 Mutex::Autolock autoLock(mLock);
765
766 if (mInitCheck != OK) {
767 return mInitCheck;
768 }
769
770 DrmSessionManager::Instance()->useSession(sessionId);
771
772 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
773 toHidlString(algorithm));
774 return toStatusT(status);
775}
776
777status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
778 String8 const &algorithm) {
779 Mutex::Autolock autoLock(mLock);
780
781 if (mInitCheck != OK) {
782 return mInitCheck;
783 }
784
785 DrmSessionManager::Instance()->useSession(sessionId);
786
787 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
788 toHidlString(algorithm));
789 return toStatusT(status);
790}
791
792status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800793 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
794 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800795 Mutex::Autolock autoLock(mLock);
796
797 if (mInitCheck != OK) {
798 return mInitCheck;
799 }
800
801 DrmSessionManager::Instance()->useSession(sessionId);
802
803 status_t err = UNKNOWN_ERROR;
804
805 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId),
806 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
807 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
808 if (status == Status::OK) {
809 output = toVector(hOutput);
810 }
811 err = toStatusT(status);
812 }
813 );
814
815 return hResult.isOk() ? err : DEAD_OBJECT;
816}
817
818status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800819 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
820 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800821 Mutex::Autolock autoLock(mLock);
822
823 if (mInitCheck != OK) {
824 return mInitCheck;
825 }
826
827 DrmSessionManager::Instance()->useSession(sessionId);
828
829 status_t err = UNKNOWN_ERROR;
830
831 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId),
832 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
833 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
834 if (status == Status::OK) {
835 output = toVector(hOutput);
836 }
837 err = toStatusT(status);
838 }
839 );
840
841 return hResult.isOk() ? err : DEAD_OBJECT;
842}
843
844status_t DrmHal::sign(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800845 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
846 Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800847 Mutex::Autolock autoLock(mLock);
848
849 if (mInitCheck != OK) {
850 return mInitCheck;
851 }
852
853 DrmSessionManager::Instance()->useSession(sessionId);
854
855 status_t err = UNKNOWN_ERROR;
856
857 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId),
858 toHidlVec(keyId), toHidlVec(message),
859 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
860 if (status == Status::OK) {
861 signature = toVector(hSignature);
862 }
863 err = toStatusT(status);
864 }
865 );
866
867 return hResult.isOk() ? err : DEAD_OBJECT;
868}
869
870status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800871 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
872 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800873 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,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800899 String8 const &algorithm, Vector<uint8_t> const &message,
900 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800901 Mutex::Autolock autoLock(mLock);
902
903 if (mInitCheck != OK) {
904 return mInitCheck;
905 }
906
907 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
908 return -EPERM;
909 }
910
911 DrmSessionManager::Instance()->useSession(sessionId);
912
913 status_t err = UNKNOWN_ERROR;
914
915 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
916 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
917 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
918 if (status == Status::OK) {
919 signature = toVector(hSignature);
920 }
921 err = toStatusT(status);
922 }
923 );
924
925 return hResult.isOk() ? err : DEAD_OBJECT;
926}
927
928void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
929{
930 mEventLock.lock();
931 mListener.clear();
932 mEventLock.unlock();
933
934 Mutex::Autolock autoLock(mLock);
935 mPlugin.clear();
936}
937
938void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
939{
940 if (vec.size()) {
941 obj.writeInt32(vec.size());
942 obj.write(vec.data(), vec.size());
943 } else {
944 obj.writeInt32(0);
945 }
946}
947
948} // namespace android