DrmHal.cpp revision f3a591cc9d604133e2c5cae3d34322b52cd7575d
1/* 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 ALOGD("makeDrmFactory: service is %s", 206 factory->isRemote() ? "Remote" : "Not Remote"); 207 return factory; 208} 209 210sp<IDrmPlugin> DrmHal::makeDrmPlugin(const uint8_t uuid[16], 211 const String8& appPackageName) { 212 if (mFactory == NULL){ 213 return NULL; 214 } 215 216 sp<IDrmPlugin> plugin; 217 Return<void> hResult = mFactory->createPlugin(uuid, appPackageName.string(), 218 [&](Status status, const sp<IDrmPlugin>& hPlugin) { 219 if (status != Status::OK) { 220 ALOGD("Failed to make drm plugin"); 221 return; 222 } 223 plugin = hPlugin; 224 } 225 ); 226 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 356status_t DrmHal::createPlugin(const uint8_t uuid[16], 357 const String8& appPackageName) { 358 Mutex::Autolock autoLock(mLock); 359 360 mPlugin = makeDrmPlugin(uuid, appPackageName); 361 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, 604 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 605 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, 789 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 790 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 791 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, 815 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 816 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 817 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, 841 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 842 Vector<uint8_t> &signature) { 843 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, 867 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 868 Vector<uint8_t> const &signature, bool &match) { 869 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, 895 String8 const &algorithm, Vector<uint8_t> const &message, 896 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 897 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 945