blob: 16035c06a2ba2380e7863413bf8dc7cfdbfb50da [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>
Jeff Tinkera53d6552017-01-20 00:31:46 -080023
24#include <android/hardware/drm/1.0/IDrmFactory.h>
25#include <android/hardware/drm/1.0/IDrmPlugin.h>
26#include <android/hardware/drm/1.0/types.h>
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080027#include <android/hidl/manager/1.0/IServiceManager.h>
Jeff Tinkera53d6552017-01-20 00:31:46 -080028
29#include <media/DrmHal.h>
30#include <media/DrmSessionClientInterface.h>
31#include <media/DrmSessionManager.h>
32#include <media/drm/DrmAPI.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AString.h>
35#include <media/stagefright/foundation/hexdump.h>
36#include <media/stagefright/MediaErrors.h>
37
38using ::android::hardware::drm::V1_0::EventType;
39using ::android::hardware::drm::V1_0::IDrmFactory;
40using ::android::hardware::drm::V1_0::IDrmPlugin;
41using ::android::hardware::drm::V1_0::KeyedVector;
42using ::android::hardware::drm::V1_0::KeyRequestType;
43using ::android::hardware::drm::V1_0::KeyStatus;
44using ::android::hardware::drm::V1_0::KeyStatusType;
45using ::android::hardware::drm::V1_0::KeyType;
46using ::android::hardware::drm::V1_0::KeyValue;
47using ::android::hardware::drm::V1_0::SecureStop;
48using ::android::hardware::drm::V1_0::Status;
49using ::android::hardware::hidl_array;
50using ::android::hardware::hidl_string;
51using ::android::hardware::hidl_vec;
52using ::android::hardware::Return;
53using ::android::hardware::Void;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -080054using ::android::hidl::manager::V1_0::IServiceManager;
Jeff Tinkera53d6552017-01-20 00:31:46 -080055using ::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
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800113static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>&
Jeff Tinkera53d6552017-01-20 00:31:46 -0800114 hSecureStops) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800115 List<Vector<uint8_t>> secureStops;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800116 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)),
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800192 mFactories(makeDrmFactories()),
193 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800194}
195
196DrmHal::~DrmHal() {
197 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
198}
199
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800200Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
201 Vector<sp<IDrmFactory>> factories;
202
Jeff Tinker6a4921a2017-03-09 23:26:01 -0800203 auto manager = ::IServiceManager::getService();
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800204
205 if (manager != NULL) {
206 manager->listByInterface(IDrmFactory::descriptor,
207 [&factories](const hidl_vec<hidl_string> &registered) {
208 for (const auto &instance : registered) {
209 auto factory = IDrmFactory::getService(instance);
210 if (factory != NULL) {
211 factories.push_back(factory);
212 ALOGI("makeDrmFactories: factory instance %s is %s",
213 instance.c_str(),
214 factory->isRemote() ? "Remote" : "Not Remote");
215 }
216 }
217 }
218 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800219 }
Jeff Tinkerc82b9c32017-02-14 11:39:51 -0800220
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800221 if (factories.size() == 0) {
222 // must be in passthrough mode, load the default passthrough service
223 auto passthrough = IDrmFactory::getService("drm");
224 if (passthrough != NULL) {
225 ALOGI("makeDrmFactories: using default drm instance");
226 factories.push_back(passthrough);
227 } else {
228 ALOGE("Failed to find any drm factories");
229 }
230 }
231 return factories;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800232}
233
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800234sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
235 const uint8_t uuid[16], const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800236
237 sp<IDrmPlugin> plugin;
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800238 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(),
Jeff Tinkera53d6552017-01-20 00:31:46 -0800239 [&](Status status, const sp<IDrmPlugin>& hPlugin) {
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800240 if (status != Status::OK) {
241 ALOGE("Failed to make drm plugin");
242 return;
243 }
244 plugin = hPlugin;
245 }
246 );
Jeff Tinkera53d6552017-01-20 00:31:46 -0800247 return plugin;
248}
249
250status_t DrmHal::initCheck() const {
251 return mInitCheck;
252}
253
254status_t DrmHal::setListener(const sp<IDrmClient>& listener)
255{
256 Mutex::Autolock lock(mEventLock);
257 if (mListener != NULL){
258 IInterface::asBinder(mListener)->unlinkToDeath(this);
259 }
260 if (listener != NULL) {
261 IInterface::asBinder(listener)->linkToDeath(this);
262 }
263 mListener = listener;
264 return NO_ERROR;
265}
266
267Return<void> DrmHal::sendEvent(EventType hEventType,
268 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
269
270 mEventLock.lock();
271 sp<IDrmClient> listener = mListener;
272 mEventLock.unlock();
273
274 if (listener != NULL) {
275 Parcel obj;
276 writeByteArray(obj, sessionId);
277 writeByteArray(obj, data);
278
279 Mutex::Autolock lock(mNotifyLock);
280 DrmPlugin::EventType eventType;
281 switch(hEventType) {
282 case EventType::PROVISION_REQUIRED:
283 eventType = DrmPlugin::kDrmPluginEventProvisionRequired;
284 break;
285 case EventType::KEY_NEEDED:
286 eventType = DrmPlugin::kDrmPluginEventKeyNeeded;
287 break;
288 case EventType::KEY_EXPIRED:
289 eventType = DrmPlugin::kDrmPluginEventKeyExpired;
290 break;
291 case EventType::VENDOR_DEFINED:
292 eventType = DrmPlugin::kDrmPluginEventVendorDefined;
293 break;
294 default:
295 return Void();
296 }
297 listener->notify(eventType, 0, &obj);
298 }
299 return Void();
300}
301
302Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
303 int64_t expiryTimeInMS) {
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 obj.writeInt64(expiryTimeInMS);
313
314 Mutex::Autolock lock(mNotifyLock);
315 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj);
316 }
317 return Void();
318}
319
320Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
321 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
322
323 mEventLock.lock();
324 sp<IDrmClient> listener = mListener;
325 mEventLock.unlock();
326
327 if (listener != NULL) {
328 Parcel obj;
329 writeByteArray(obj, sessionId);
330
331 size_t nKeys = keyStatusList.size();
332 obj.writeInt32(nKeys);
333 for (size_t i = 0; i < nKeys; ++i) {
334 const KeyStatus &keyStatus = keyStatusList[i];
335 writeByteArray(obj, keyStatus.keyId);
336 uint32_t type;
337 switch(keyStatus.type) {
338 case KeyStatusType::USABLE:
339 type = DrmPlugin::kKeyStatusType_Usable;
340 break;
341 case KeyStatusType::EXPIRED:
342 type = DrmPlugin::kKeyStatusType_Expired;
343 break;
344 case KeyStatusType::OUTPUTNOTALLOWED:
345 type = DrmPlugin::kKeyStatusType_OutputNotAllowed;
346 break;
347 case KeyStatusType::STATUSPENDING:
348 type = DrmPlugin::kKeyStatusType_StatusPending;
349 break;
350 case KeyStatusType::INTERNALERROR:
351 default:
352 type = DrmPlugin::kKeyStatusType_InternalError;
353 break;
354 }
355 obj.writeInt32(type);
356 }
357 obj.writeInt32(hasNewUsableKey);
358
359 Mutex::Autolock lock(mNotifyLock);
360 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj);
361 }
362 return Void();
363}
364
365bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
366 Mutex::Autolock autoLock(mLock);
Jeff Tinkera53d6552017-01-20 00:31:46 -0800367
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800368 for (size_t i = 0; i < mFactories.size(); i++) {
369 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
370 if (mimeType != "") {
371 if (mFactories[i]->isContentTypeSupported(mimeType.string())) {
372 return true;
373 }
374 } else {
375 return true;
376 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800377 }
378 }
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800379 return false;
Jeff Tinkera53d6552017-01-20 00:31:46 -0800380}
381
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800382status_t DrmHal::createPlugin(const uint8_t uuid[16],
383 const String8& appPackageName) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800384 Mutex::Autolock autoLock(mLock);
385
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800386 for (size_t i = 0; i < mFactories.size(); i++) {
387 if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
388 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName);
389 }
390 }
Jeff Tinkera53d6552017-01-20 00:31:46 -0800391
392 if (mPlugin == NULL) {
393 mInitCheck = ERROR_UNSUPPORTED;
394 } else {
395 mInitCheck = OK;
396 mPlugin->setListener(this);
397 }
398
399 return mInitCheck;
400}
401
402status_t DrmHal::destroyPlugin() {
403 Mutex::Autolock autoLock(mLock);
404
405 if (mInitCheck != OK) {
406 return mInitCheck;
407 }
408
409 setListener(NULL);
410 mPlugin.clear();
411
412 return OK;
413}
414
415status_t DrmHal::openSession(Vector<uint8_t> &sessionId) {
416 Mutex::Autolock autoLock(mLock);
417
418 if (mInitCheck != OK) {
419 return mInitCheck;
420 }
421
422 status_t err = UNKNOWN_ERROR;
423
424 bool retry = true;
425 do {
426 hidl_vec<uint8_t> hSessionId;
427
428 Return<void> hResult = mPlugin->openSession(
429 [&](Status status, const hidl_vec<uint8_t>& id) {
430 if (status == Status::OK) {
431 sessionId = toVector(id);
432 }
433 err = toStatusT(status);
434 }
435 );
436
437 if (!hResult.isOk()) {
438 err = DEAD_OBJECT;
439 }
440
441 if (err == ERROR_DRM_RESOURCE_BUSY && retry) {
442 mLock.unlock();
443 // reclaimSession may call back to closeSession, since mLock is
444 // shared between Drm instances, we should unlock here to avoid
445 // deadlock.
446 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
447 mLock.lock();
448 } else {
449 retry = false;
450 }
451 } while (retry);
452
453 if (err == OK) {
454 DrmSessionManager::Instance()->addSession(getCallingPid(),
455 mDrmSessionClient, sessionId);
456 }
457 return err;
458}
459
460status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) {
461 Mutex::Autolock autoLock(mLock);
462
463 if (mInitCheck != OK) {
464 return mInitCheck;
465 }
466
467 Status status = mPlugin->closeSession(toHidlVec(sessionId));
468 if (status == Status::OK) {
469 DrmSessionManager::Instance()->removeSession(sessionId);
470 }
471 return toStatusT(status);
472}
473
474status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
475 Vector<uint8_t> const &initData, String8 const &mimeType,
476 DrmPlugin::KeyType keyType, KeyedVector<String8,
477 String8> const &optionalParameters, Vector<uint8_t> &request,
478 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) {
479 Mutex::Autolock autoLock(mLock);
480
481 if (mInitCheck != OK) {
482 return mInitCheck;
483 }
484
485 DrmSessionManager::Instance()->useSession(sessionId);
486
487 KeyType hKeyType;
488 if (keyType == DrmPlugin::kKeyType_Streaming) {
489 hKeyType = KeyType::STREAMING;
490 } else if (keyType == DrmPlugin::kKeyType_Offline) {
491 hKeyType = KeyType::OFFLINE;
492 } else if (keyType == DrmPlugin::kKeyType_Release) {
493 hKeyType = KeyType::RELEASE;
494 } else {
495 return BAD_VALUE;
496 }
497
498 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
499
500 status_t err = UNKNOWN_ERROR;
501
502 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
503 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
504 [&](Status status, const hidl_vec<uint8_t>& hRequest,
505 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) {
506
507 if (status == Status::OK) {
508 request = toVector(hRequest);
509 defaultUrl = toString8(hDefaultUrl);
510
511 switch (hKeyRequestType) {
512 case KeyRequestType::INITIAL:
513 *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
514 break;
515 case KeyRequestType::RENEWAL:
516 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
517 break;
518 case KeyRequestType::RELEASE:
519 *keyRequestType = DrmPlugin::kKeyRequestType_Release;
520 break;
521 default:
522 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
523 break;
524 }
525 err = toStatusT(status);
526 }
527 });
528
529 return hResult.isOk() ? err : DEAD_OBJECT;
530}
531
532status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
533 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
534 Mutex::Autolock autoLock(mLock);
535
536 if (mInitCheck != OK) {
537 return mInitCheck;
538 }
539
540 DrmSessionManager::Instance()->useSession(sessionId);
541
542 status_t err = UNKNOWN_ERROR;
543
544 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId),
545 toHidlVec(response),
546 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) {
547 if (status == Status::OK) {
548 keySetId = toVector(hKeySetId);
549 }
550 err = toStatusT(status);
551 }
552 );
553
554 return hResult.isOk() ? err : DEAD_OBJECT;
555}
556
557status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) {
558 Mutex::Autolock autoLock(mLock);
559
560 if (mInitCheck != OK) {
561 return mInitCheck;
562 }
563
564 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId)));
565}
566
567status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId,
568 Vector<uint8_t> const &keySetId) {
569 Mutex::Autolock autoLock(mLock);
570
571 if (mInitCheck != OK) {
572 return mInitCheck;
573 }
574
575 DrmSessionManager::Instance()->useSession(sessionId);
576
577 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId),
578 toHidlVec(keySetId)));
579}
580
581status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId,
582 KeyedVector<String8, String8> &infoMap) const {
583 Mutex::Autolock autoLock(mLock);
584
585 if (mInitCheck != OK) {
586 return mInitCheck;
587 }
588
589 DrmSessionManager::Instance()->useSession(sessionId);
590
591 ::KeyedVector hInfoMap;
592
593 status_t err = UNKNOWN_ERROR;
594
595 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId),
596 [&](Status status, const hidl_vec<KeyValue>& map) {
597 if (status == Status::OK) {
598 infoMap = toKeyedVector(map);
599 }
600 err = toStatusT(status);
601 }
602 );
603
604 return hResult.isOk() ? err : DEAD_OBJECT;
605}
606
607status_t DrmHal::getProvisionRequest(String8 const &certType,
608 String8 const &certAuthority, Vector<uint8_t> &request,
609 String8 &defaultUrl) {
610 Mutex::Autolock autoLock(mLock);
611
612 if (mInitCheck != OK) {
613 return mInitCheck;
614 }
615
616 status_t err = UNKNOWN_ERROR;
617
618 Return<void> hResult = mPlugin->getProvisionRequest(
619 toHidlString(certType), toHidlString(certAuthority),
620 [&](Status status, const hidl_vec<uint8_t>& hRequest,
621 const hidl_string& hDefaultUrl) {
622 if (status == Status::OK) {
623 request = toVector(hRequest);
624 defaultUrl = toString8(hDefaultUrl);
625 }
626 err = toStatusT(status);
627 }
628 );
629
630 return hResult.isOk() ? err : DEAD_OBJECT;
631}
632
633status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800634 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800635 Mutex::Autolock autoLock(mLock);
636
637 if (mInitCheck != OK) {
638 return mInitCheck;
639 }
640
641 status_t err = UNKNOWN_ERROR;
642
643 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response),
644 [&](Status status, const hidl_vec<uint8_t>& hCertificate,
645 const hidl_vec<uint8_t>& hWrappedKey) {
646 if (status == Status::OK) {
647 certificate = toVector(hCertificate);
648 wrappedKey = toVector(hWrappedKey);
649 }
650 err = toStatusT(status);
651 }
652 );
653
654 return hResult.isOk() ? err : DEAD_OBJECT;
655}
656
Jeff Tinkerabeb36a2017-02-17 09:42:46 -0800657status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800658 Mutex::Autolock autoLock(mLock);
659
660 if (mInitCheck != OK) {
661 return mInitCheck;
662 }
663
664 status_t err = UNKNOWN_ERROR;
665
666 Return<void> hResult = mPlugin->getSecureStops(
667 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) {
668 if (status == Status::OK) {
669 secureStops = toSecureStops(hSecureStops);
670 }
671 err = toStatusT(status);
672 }
673 );
674
675 return hResult.isOk() ? err : DEAD_OBJECT;
676}
677
678
679status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
680 Mutex::Autolock autoLock(mLock);
681
682 if (mInitCheck != OK) {
683 return mInitCheck;
684 }
685
686 status_t err = UNKNOWN_ERROR;
687
688 Return<void> hResult = mPlugin->getSecureStop(toHidlVec(ssid),
689 [&](Status status, const SecureStop& hSecureStop) {
690 if (status == Status::OK) {
691 secureStop = toVector(hSecureStop.opaqueData);
692 }
693 err = toStatusT(status);
694 }
695 );
696
697 return hResult.isOk() ? err : DEAD_OBJECT;
698}
699
700status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
701 Mutex::Autolock autoLock(mLock);
702
703 if (mInitCheck != OK) {
704 return mInitCheck;
705 }
706
707 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease)));
708}
709
710status_t DrmHal::releaseAllSecureStops() {
711 Mutex::Autolock autoLock(mLock);
712
713 if (mInitCheck != OK) {
714 return mInitCheck;
715 }
716
717 return toStatusT(mPlugin->releaseAllSecureStops());
718}
719
720status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const {
721 Mutex::Autolock autoLock(mLock);
722
723 if (mInitCheck != OK) {
724 return mInitCheck;
725 }
726
727 status_t err = UNKNOWN_ERROR;
728
729 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name),
730 [&](Status status, const hidl_string& hValue) {
731 if (status == Status::OK) {
732 value = toString8(hValue);
733 }
734 err = toStatusT(status);
735 }
736 );
737
738 return hResult.isOk() ? err : DEAD_OBJECT;
739}
740
741status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
742 Mutex::Autolock autoLock(mLock);
743
744 if (mInitCheck != OK) {
745 return mInitCheck;
746 }
747
748 status_t err = UNKNOWN_ERROR;
749
750 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name),
751 [&](Status status, const hidl_vec<uint8_t>& hValue) {
752 if (status == Status::OK) {
753 value = toVector(hValue);
754 }
755 err = toStatusT(status);
756 }
757 );
758
759 return hResult.isOk() ? err : DEAD_OBJECT;
760}
761
762status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const {
763 Mutex::Autolock autoLock(mLock);
764
765 if (mInitCheck != OK) {
766 return mInitCheck;
767 }
768
769 Status status = mPlugin->setPropertyString(toHidlString(name),
770 toHidlString(value));
771 return toStatusT(status);
772}
773
774status_t DrmHal::setPropertyByteArray(String8 const &name,
775 Vector<uint8_t> const &value ) const {
776 Mutex::Autolock autoLock(mLock);
777
778 if (mInitCheck != OK) {
779 return mInitCheck;
780 }
781
782 Status status = mPlugin->setPropertyByteArray(toHidlString(name),
783 toHidlVec(value));
784 return toStatusT(status);
785}
786
787
788status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
789 String8 const &algorithm) {
790 Mutex::Autolock autoLock(mLock);
791
792 if (mInitCheck != OK) {
793 return mInitCheck;
794 }
795
796 DrmSessionManager::Instance()->useSession(sessionId);
797
798 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId),
799 toHidlString(algorithm));
800 return toStatusT(status);
801}
802
803status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId,
804 String8 const &algorithm) {
805 Mutex::Autolock autoLock(mLock);
806
807 if (mInitCheck != OK) {
808 return mInitCheck;
809 }
810
811 DrmSessionManager::Instance()->useSession(sessionId);
812
813 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId),
814 toHidlString(algorithm));
815 return toStatusT(status);
816}
817
818status_t DrmHal::encrypt(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->encrypt(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::decrypt(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800845 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input,
846 Vector<uint8_t> const &iv, Vector<uint8_t> &output) {
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->decrypt(toHidlVec(sessionId),
858 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv),
859 [&](Status status, const hidl_vec<uint8_t>& hOutput) {
860 if (status == Status::OK) {
861 output = toVector(hOutput);
862 }
863 err = toStatusT(status);
864 }
865 );
866
867 return hResult.isOk() ? err : DEAD_OBJECT;
868}
869
870status_t DrmHal::sign(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> &signature) {
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->sign(toHidlVec(sessionId),
884 toHidlVec(keyId), toHidlVec(message),
885 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
886 if (status == Status::OK) {
887 signature = toVector(hSignature);
888 }
889 err = toStatusT(status);
890 }
891 );
892
893 return hResult.isOk() ? err : DEAD_OBJECT;
894}
895
896status_t DrmHal::verify(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800897 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message,
898 Vector<uint8_t> const &signature, bool &match) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800899 Mutex::Autolock autoLock(mLock);
900
901 if (mInitCheck != OK) {
902 return mInitCheck;
903 }
904
905 DrmSessionManager::Instance()->useSession(sessionId);
906
907 status_t err = UNKNOWN_ERROR;
908
909 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId),
910 toHidlVec(message), toHidlVec(signature),
911 [&](Status status, bool hMatch) {
912 if (status == Status::OK) {
913 match = hMatch;
914 } else {
915 match = false;
916 }
917 err = toStatusT(status);
918 }
919 );
920
921 return hResult.isOk() ? err : DEAD_OBJECT;
922}
923
924status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId,
Edwin Wong68b3d9f2017-01-06 19:07:54 -0800925 String8 const &algorithm, Vector<uint8_t> const &message,
926 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) {
Jeff Tinkera53d6552017-01-20 00:31:46 -0800927 Mutex::Autolock autoLock(mLock);
928
929 if (mInitCheck != OK) {
930 return mInitCheck;
931 }
932
933 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
934 return -EPERM;
935 }
936
937 DrmSessionManager::Instance()->useSession(sessionId);
938
939 status_t err = UNKNOWN_ERROR;
940
941 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId),
942 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey),
943 [&](Status status, const hidl_vec<uint8_t>& hSignature) {
944 if (status == Status::OK) {
945 signature = toVector(hSignature);
946 }
947 err = toStatusT(status);
948 }
949 );
950
951 return hResult.isOk() ? err : DEAD_OBJECT;
952}
953
954void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused)
955{
956 mEventLock.lock();
957 mListener.clear();
958 mEventLock.unlock();
959
960 Mutex::Autolock autoLock(mLock);
961 mPlugin.clear();
962}
963
964void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec)
965{
966 if (vec.size()) {
967 obj.writeInt32(vec.size());
968 obj.write(vec.data(), vec.size());
969 } else {
970 obj.writeInt32(0);
971 }
972}
973
974} // namespace android