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