DrmHal.cpp revision 38875a41d62003ee9ad1f537106a86289fb0c437
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 return NULL; 205 } 206 207 ALOGD("makeDrmFactory: service is %s", 208 factory->isRemote() ? "Remote" : "Not Remote"); 209 210 return factory; 211} 212 213sp<IDrmPlugin> DrmHal::makeDrmPlugin(const uint8_t uuid[16], 214 const String8& appPackageName) { 215 if (mFactory == NULL){ 216 return NULL; 217 } 218 219 sp<IDrmPlugin> plugin; 220 Return<void> hResult = mFactory->createPlugin(uuid, appPackageName.string(), 221 [&](Status status, const sp<IDrmPlugin>& hPlugin) { 222 if (status != Status::OK) { 223 ALOGD("Failed to make drm plugin"); 224 return; 225 } 226 plugin = hPlugin; 227 } 228 ); 229 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)) { 352 result = true; 353 if (mimeType != "") { 354 result = mFactory->isContentTypeSupported(mimeType.string()); 355 } 356 } 357 return result; 358} 359 360status_t DrmHal::createPlugin(const uint8_t uuid[16], 361 const String8& appPackageName) { 362 Mutex::Autolock autoLock(mLock); 363 364 mPlugin = makeDrmPlugin(uuid, appPackageName); 365 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, 608 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 609 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, 793 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 794 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 795 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, 819 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 820 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 821 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, 845 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 846 Vector<uint8_t> &signature) { 847 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, 871 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 872 Vector<uint8_t> const &signature, 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, Vector<uint8_t> const &message, 900 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 901 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 949