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 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> 27 #include <android/hidl/manager/1.0/IServiceManager.h> 28 #include <hidl/ServiceManagement.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 39 using ::android::hardware::drm::V1_0::EventType; 40 using ::android::hardware::drm::V1_0::IDrmFactory; 41 using ::android::hardware::drm::V1_0::IDrmPlugin; 42 using ::android::hardware::drm::V1_0::KeyedVector; 43 using ::android::hardware::drm::V1_0::KeyRequestType; 44 using ::android::hardware::drm::V1_0::KeyStatus; 45 using ::android::hardware::drm::V1_0::KeyStatusType; 46 using ::android::hardware::drm::V1_0::KeyType; 47 using ::android::hardware::drm::V1_0::KeyValue; 48 using ::android::hardware::drm::V1_0::SecureStop; 49 using ::android::hardware::drm::V1_0::Status; 50 using ::android::hardware::hidl_array; 51 using ::android::hardware::hidl_string; 52 using ::android::hardware::hidl_vec; 53 using ::android::hardware::Return; 54 using ::android::hardware::Void; 55 using ::android::hidl::manager::V1_0::IServiceManager; 56 using ::android::sp; 57 58 namespace android { 59 60 static inline int getCallingPid() { 61 return IPCThreadState::self()->getCallingPid(); 62 } 63 64 static bool checkPermission(const char* permissionString) { 65 if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 66 bool ok = checkCallingPermission(String16(permissionString)); 67 if (!ok) ALOGE("Request requires %s", permissionString); 68 return ok; 69 } 70 71 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) { 72 Vector<uint8_t> vector; 73 vector.appendArray(vec.data(), vec.size()); 74 return *const_cast<const Vector<uint8_t> *>(&vector); 75 } 76 77 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) { 78 hidl_vec<uint8_t> vec; 79 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size()); 80 return vec; 81 } 82 83 static String8 toString8(const hidl_string &string) { 84 return String8(string.c_str()); 85 } 86 87 static hidl_string toHidlString(const String8& string) { 88 return hidl_string(string.string()); 89 } 90 91 92 static ::KeyedVector toHidlKeyedVector(const KeyedVector<String8, String8>& 93 keyedVector) { 94 std::vector<KeyValue> stdKeyedVector; 95 for (size_t i = 0; i < keyedVector.size(); i++) { 96 KeyValue keyValue; 97 keyValue.key = toHidlString(keyedVector.keyAt(i)); 98 keyValue.value = toHidlString(keyedVector.valueAt(i)); 99 stdKeyedVector.push_back(keyValue); 100 } 101 return ::KeyedVector(stdKeyedVector); 102 } 103 104 static KeyedVector<String8, String8> toKeyedVector(const ::KeyedVector& 105 hKeyedVector) { 106 KeyedVector<String8, String8> keyedVector; 107 for (size_t i = 0; i < hKeyedVector.size(); i++) { 108 keyedVector.add(toString8(hKeyedVector[i].key), 109 toString8(hKeyedVector[i].value)); 110 } 111 return keyedVector; 112 } 113 114 static List<Vector<uint8_t>> toSecureStops(const hidl_vec<SecureStop>& 115 hSecureStops) { 116 List<Vector<uint8_t>> secureStops; 117 for (size_t i = 0; i < hSecureStops.size(); i++) { 118 secureStops.push_back(toVector(hSecureStops[i].opaqueData)); 119 } 120 return secureStops; 121 } 122 123 static status_t toStatusT(Status status) { 124 switch (status) { 125 case Status::OK: 126 return OK; 127 break; 128 case Status::ERROR_DRM_NO_LICENSE: 129 return ERROR_DRM_NO_LICENSE; 130 break; 131 case Status::ERROR_DRM_LICENSE_EXPIRED: 132 return ERROR_DRM_LICENSE_EXPIRED; 133 break; 134 case Status::ERROR_DRM_SESSION_NOT_OPENED: 135 return ERROR_DRM_SESSION_NOT_OPENED; 136 break; 137 case Status::ERROR_DRM_CANNOT_HANDLE: 138 return ERROR_DRM_CANNOT_HANDLE; 139 break; 140 case Status::ERROR_DRM_INVALID_STATE: 141 return ERROR_DRM_TAMPER_DETECTED; 142 break; 143 case Status::BAD_VALUE: 144 return BAD_VALUE; 145 break; 146 case Status::ERROR_DRM_NOT_PROVISIONED: 147 return ERROR_DRM_NOT_PROVISIONED; 148 break; 149 case Status::ERROR_DRM_RESOURCE_BUSY: 150 return ERROR_DRM_RESOURCE_BUSY; 151 break; 152 case Status::ERROR_DRM_DEVICE_REVOKED: 153 return ERROR_DRM_DEVICE_REVOKED; 154 break; 155 case Status::ERROR_DRM_UNKNOWN: 156 default: 157 return ERROR_DRM_UNKNOWN; 158 break; 159 } 160 } 161 162 163 Mutex DrmHal::mLock; 164 165 struct DrmSessionClient : public DrmSessionClientInterface { 166 explicit DrmSessionClient(DrmHal* drm) : mDrm(drm) {} 167 168 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { 169 sp<DrmHal> drm = mDrm.promote(); 170 if (drm == NULL) { 171 return true; 172 } 173 status_t err = drm->closeSession(sessionId); 174 if (err != OK) { 175 return false; 176 } 177 drm->sendEvent(EventType::SESSION_RECLAIMED, 178 toHidlVec(sessionId), hidl_vec<uint8_t>()); 179 return true; 180 } 181 182 protected: 183 virtual ~DrmSessionClient() {} 184 185 private: 186 wp<DrmHal> mDrm; 187 188 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient); 189 }; 190 191 DrmHal::DrmHal() 192 : mDrmSessionClient(new DrmSessionClient(this)), 193 mFactories(makeDrmFactories()), 194 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT) { 195 } 196 197 DrmHal::~DrmHal() { 198 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient); 199 } 200 201 Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() { 202 Vector<sp<IDrmFactory>> factories; 203 204 auto manager = hardware::defaultServiceManager(); 205 206 if (manager != NULL) { 207 manager->listByInterface(IDrmFactory::descriptor, 208 [&factories](const hidl_vec<hidl_string> ®istered) { 209 for (const auto &instance : registered) { 210 auto factory = IDrmFactory::getService(instance); 211 if (factory != NULL) { 212 factories.push_back(factory); 213 ALOGI("makeDrmFactories: factory instance %s is %s", 214 instance.c_str(), 215 factory->isRemote() ? "Remote" : "Not Remote"); 216 } 217 } 218 } 219 ); 220 } 221 222 if (factories.size() == 0) { 223 // must be in passthrough mode, load the default passthrough service 224 auto passthrough = IDrmFactory::getService(); 225 if (passthrough != NULL) { 226 ALOGI("makeDrmFactories: using default drm instance"); 227 factories.push_back(passthrough); 228 } else { 229 ALOGE("Failed to find any drm factories"); 230 } 231 } 232 return factories; 233 } 234 235 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory, 236 const uint8_t uuid[16], const String8& appPackageName) { 237 238 sp<IDrmPlugin> plugin; 239 Return<void> hResult = factory->createPlugin(uuid, appPackageName.string(), 240 [&](Status status, const sp<IDrmPlugin>& hPlugin) { 241 if (status != Status::OK) { 242 ALOGE("Failed to make drm plugin"); 243 return; 244 } 245 plugin = hPlugin; 246 } 247 ); 248 return plugin; 249 } 250 251 status_t DrmHal::initCheck() const { 252 return mInitCheck; 253 } 254 255 status_t DrmHal::setListener(const sp<IDrmClient>& listener) 256 { 257 Mutex::Autolock lock(mEventLock); 258 if (mListener != NULL){ 259 IInterface::asBinder(mListener)->unlinkToDeath(this); 260 } 261 if (listener != NULL) { 262 IInterface::asBinder(listener)->linkToDeath(this); 263 } 264 mListener = listener; 265 return NO_ERROR; 266 } 267 268 Return<void> DrmHal::sendEvent(EventType hEventType, 269 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) { 270 271 mEventLock.lock(); 272 sp<IDrmClient> listener = mListener; 273 mEventLock.unlock(); 274 275 if (listener != NULL) { 276 Parcel obj; 277 writeByteArray(obj, sessionId); 278 writeByteArray(obj, data); 279 280 Mutex::Autolock lock(mNotifyLock); 281 DrmPlugin::EventType eventType; 282 switch(hEventType) { 283 case EventType::PROVISION_REQUIRED: 284 eventType = DrmPlugin::kDrmPluginEventProvisionRequired; 285 break; 286 case EventType::KEY_NEEDED: 287 eventType = DrmPlugin::kDrmPluginEventKeyNeeded; 288 break; 289 case EventType::KEY_EXPIRED: 290 eventType = DrmPlugin::kDrmPluginEventKeyExpired; 291 break; 292 case EventType::VENDOR_DEFINED: 293 eventType = DrmPlugin::kDrmPluginEventVendorDefined; 294 break; 295 case EventType::SESSION_RECLAIMED: 296 eventType = DrmPlugin::kDrmPluginEventSessionReclaimed; 297 break; 298 default: 299 return Void(); 300 } 301 listener->notify(eventType, 0, &obj); 302 } 303 return Void(); 304 } 305 306 Return<void> DrmHal::sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, 307 int64_t expiryTimeInMS) { 308 309 mEventLock.lock(); 310 sp<IDrmClient> listener = mListener; 311 mEventLock.unlock(); 312 313 if (listener != NULL) { 314 Parcel obj; 315 writeByteArray(obj, sessionId); 316 obj.writeInt64(expiryTimeInMS); 317 318 Mutex::Autolock lock(mNotifyLock); 319 listener->notify(DrmPlugin::kDrmPluginEventExpirationUpdate, 0, &obj); 320 } 321 return Void(); 322 } 323 324 Return<void> DrmHal::sendKeysChange(const hidl_vec<uint8_t>& sessionId, 325 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) { 326 327 mEventLock.lock(); 328 sp<IDrmClient> listener = mListener; 329 mEventLock.unlock(); 330 331 if (listener != NULL) { 332 Parcel obj; 333 writeByteArray(obj, sessionId); 334 335 size_t nKeys = keyStatusList.size(); 336 obj.writeInt32(nKeys); 337 for (size_t i = 0; i < nKeys; ++i) { 338 const KeyStatus &keyStatus = keyStatusList[i]; 339 writeByteArray(obj, keyStatus.keyId); 340 uint32_t type; 341 switch(keyStatus.type) { 342 case KeyStatusType::USABLE: 343 type = DrmPlugin::kKeyStatusType_Usable; 344 break; 345 case KeyStatusType::EXPIRED: 346 type = DrmPlugin::kKeyStatusType_Expired; 347 break; 348 case KeyStatusType::OUTPUTNOTALLOWED: 349 type = DrmPlugin::kKeyStatusType_OutputNotAllowed; 350 break; 351 case KeyStatusType::STATUSPENDING: 352 type = DrmPlugin::kKeyStatusType_StatusPending; 353 break; 354 case KeyStatusType::INTERNALERROR: 355 default: 356 type = DrmPlugin::kKeyStatusType_InternalError; 357 break; 358 } 359 obj.writeInt32(type); 360 } 361 obj.writeInt32(hasNewUsableKey); 362 363 Mutex::Autolock lock(mNotifyLock); 364 listener->notify(DrmPlugin::kDrmPluginEventKeysChange, 0, &obj); 365 } 366 return Void(); 367 } 368 369 bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) { 370 Mutex::Autolock autoLock(mLock); 371 372 for (size_t i = 0; i < mFactories.size(); i++) { 373 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 374 if (mimeType != "") { 375 if (mFactories[i]->isContentTypeSupported(mimeType.string())) { 376 return true; 377 } 378 } else { 379 return true; 380 } 381 } 382 } 383 return false; 384 } 385 386 status_t DrmHal::createPlugin(const uint8_t uuid[16], 387 const String8& appPackageName) { 388 Mutex::Autolock autoLock(mLock); 389 390 for (size_t i = 0; i < mFactories.size(); i++) { 391 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 392 mPlugin = makeDrmPlugin(mFactories[i], uuid, appPackageName); 393 } 394 } 395 396 if (mPlugin == NULL) { 397 mInitCheck = ERROR_UNSUPPORTED; 398 } else { 399 mInitCheck = OK; 400 mPlugin->setListener(this); 401 } 402 403 return mInitCheck; 404 } 405 406 status_t DrmHal::destroyPlugin() { 407 Mutex::Autolock autoLock(mLock); 408 409 if (mInitCheck != OK) { 410 return mInitCheck; 411 } 412 413 setListener(NULL); 414 if (mPlugin != NULL) { 415 mPlugin->setListener(NULL); 416 } 417 mPlugin.clear(); 418 mInitCheck = NO_INIT; 419 420 return OK; 421 } 422 423 status_t DrmHal::openSession(Vector<uint8_t> &sessionId) { 424 Mutex::Autolock autoLock(mLock); 425 426 if (mInitCheck != OK) { 427 return mInitCheck; 428 } 429 430 status_t err = UNKNOWN_ERROR; 431 432 bool retry = true; 433 do { 434 hidl_vec<uint8_t> hSessionId; 435 436 Return<void> hResult = mPlugin->openSession( 437 [&](Status status, const hidl_vec<uint8_t>& id) { 438 if (status == Status::OK) { 439 sessionId = toVector(id); 440 } 441 err = toStatusT(status); 442 } 443 ); 444 445 if (!hResult.isOk()) { 446 err = DEAD_OBJECT; 447 } 448 449 if (err == ERROR_DRM_RESOURCE_BUSY && retry) { 450 mLock.unlock(); 451 // reclaimSession may call back to closeSession, since mLock is 452 // shared between Drm instances, we should unlock here to avoid 453 // deadlock. 454 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); 455 mLock.lock(); 456 } else { 457 retry = false; 458 } 459 } while (retry); 460 461 if (err == OK) { 462 DrmSessionManager::Instance()->addSession(getCallingPid(), 463 mDrmSessionClient, sessionId); 464 } 465 return err; 466 } 467 468 status_t DrmHal::closeSession(Vector<uint8_t> const &sessionId) { 469 Mutex::Autolock autoLock(mLock); 470 471 if (mInitCheck != OK) { 472 return mInitCheck; 473 } 474 475 Status status = mPlugin->closeSession(toHidlVec(sessionId)); 476 if (status == Status::OK) { 477 DrmSessionManager::Instance()->removeSession(sessionId); 478 } 479 return toStatusT(status); 480 } 481 482 status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId, 483 Vector<uint8_t> const &initData, String8 const &mimeType, 484 DrmPlugin::KeyType keyType, KeyedVector<String8, 485 String8> const &optionalParameters, Vector<uint8_t> &request, 486 String8 &defaultUrl, DrmPlugin::KeyRequestType *keyRequestType) { 487 Mutex::Autolock autoLock(mLock); 488 489 if (mInitCheck != OK) { 490 return mInitCheck; 491 } 492 493 DrmSessionManager::Instance()->useSession(sessionId); 494 495 KeyType hKeyType; 496 if (keyType == DrmPlugin::kKeyType_Streaming) { 497 hKeyType = KeyType::STREAMING; 498 } else if (keyType == DrmPlugin::kKeyType_Offline) { 499 hKeyType = KeyType::OFFLINE; 500 } else if (keyType == DrmPlugin::kKeyType_Release) { 501 hKeyType = KeyType::RELEASE; 502 } else { 503 return BAD_VALUE; 504 } 505 506 ::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters); 507 508 status_t err = UNKNOWN_ERROR; 509 510 Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId), 511 toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters, 512 [&](Status status, const hidl_vec<uint8_t>& hRequest, 513 KeyRequestType hKeyRequestType, const hidl_string& hDefaultUrl) { 514 515 if (status == Status::OK) { 516 request = toVector(hRequest); 517 defaultUrl = toString8(hDefaultUrl); 518 519 switch (hKeyRequestType) { 520 case KeyRequestType::INITIAL: 521 *keyRequestType = DrmPlugin::kKeyRequestType_Initial; 522 break; 523 case KeyRequestType::RENEWAL: 524 *keyRequestType = DrmPlugin::kKeyRequestType_Renewal; 525 break; 526 case KeyRequestType::RELEASE: 527 *keyRequestType = DrmPlugin::kKeyRequestType_Release; 528 break; 529 default: 530 *keyRequestType = DrmPlugin::kKeyRequestType_Unknown; 531 break; 532 } 533 err = toStatusT(status); 534 } 535 }); 536 537 return hResult.isOk() ? err : DEAD_OBJECT; 538 } 539 540 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId, 541 Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) { 542 Mutex::Autolock autoLock(mLock); 543 544 if (mInitCheck != OK) { 545 return mInitCheck; 546 } 547 548 DrmSessionManager::Instance()->useSession(sessionId); 549 550 status_t err = UNKNOWN_ERROR; 551 552 Return<void> hResult = mPlugin->provideKeyResponse(toHidlVec(sessionId), 553 toHidlVec(response), 554 [&](Status status, const hidl_vec<uint8_t>& hKeySetId) { 555 if (status == Status::OK) { 556 keySetId = toVector(hKeySetId); 557 } 558 err = toStatusT(status); 559 } 560 ); 561 562 return hResult.isOk() ? err : DEAD_OBJECT; 563 } 564 565 status_t DrmHal::removeKeys(Vector<uint8_t> const &keySetId) { 566 Mutex::Autolock autoLock(mLock); 567 568 if (mInitCheck != OK) { 569 return mInitCheck; 570 } 571 572 return toStatusT(mPlugin->removeKeys(toHidlVec(keySetId))); 573 } 574 575 status_t DrmHal::restoreKeys(Vector<uint8_t> const &sessionId, 576 Vector<uint8_t> const &keySetId) { 577 Mutex::Autolock autoLock(mLock); 578 579 if (mInitCheck != OK) { 580 return mInitCheck; 581 } 582 583 DrmSessionManager::Instance()->useSession(sessionId); 584 585 return toStatusT(mPlugin->restoreKeys(toHidlVec(sessionId), 586 toHidlVec(keySetId))); 587 } 588 589 status_t DrmHal::queryKeyStatus(Vector<uint8_t> const &sessionId, 590 KeyedVector<String8, String8> &infoMap) const { 591 Mutex::Autolock autoLock(mLock); 592 593 if (mInitCheck != OK) { 594 return mInitCheck; 595 } 596 597 DrmSessionManager::Instance()->useSession(sessionId); 598 599 ::KeyedVector hInfoMap; 600 601 status_t err = UNKNOWN_ERROR; 602 603 Return<void> hResult = mPlugin->queryKeyStatus(toHidlVec(sessionId), 604 [&](Status status, const hidl_vec<KeyValue>& map) { 605 if (status == Status::OK) { 606 infoMap = toKeyedVector(map); 607 } 608 err = toStatusT(status); 609 } 610 ); 611 612 return hResult.isOk() ? err : DEAD_OBJECT; 613 } 614 615 status_t DrmHal::getProvisionRequest(String8 const &certType, 616 String8 const &certAuthority, Vector<uint8_t> &request, 617 String8 &defaultUrl) { 618 Mutex::Autolock autoLock(mLock); 619 620 if (mInitCheck != OK) { 621 return mInitCheck; 622 } 623 624 status_t err = UNKNOWN_ERROR; 625 626 Return<void> hResult = mPlugin->getProvisionRequest( 627 toHidlString(certType), toHidlString(certAuthority), 628 [&](Status status, const hidl_vec<uint8_t>& hRequest, 629 const hidl_string& hDefaultUrl) { 630 if (status == Status::OK) { 631 request = toVector(hRequest); 632 defaultUrl = toString8(hDefaultUrl); 633 } 634 err = toStatusT(status); 635 } 636 ); 637 638 return hResult.isOk() ? err : DEAD_OBJECT; 639 } 640 641 status_t DrmHal::provideProvisionResponse(Vector<uint8_t> const &response, 642 Vector<uint8_t> &certificate, Vector<uint8_t> &wrappedKey) { 643 Mutex::Autolock autoLock(mLock); 644 645 if (mInitCheck != OK) { 646 return mInitCheck; 647 } 648 649 status_t err = UNKNOWN_ERROR; 650 651 Return<void> hResult = mPlugin->provideProvisionResponse(toHidlVec(response), 652 [&](Status status, const hidl_vec<uint8_t>& hCertificate, 653 const hidl_vec<uint8_t>& hWrappedKey) { 654 if (status == Status::OK) { 655 certificate = toVector(hCertificate); 656 wrappedKey = toVector(hWrappedKey); 657 } 658 err = toStatusT(status); 659 } 660 ); 661 662 return hResult.isOk() ? err : DEAD_OBJECT; 663 } 664 665 status_t DrmHal::getSecureStops(List<Vector<uint8_t>> &secureStops) { 666 Mutex::Autolock autoLock(mLock); 667 668 if (mInitCheck != OK) { 669 return mInitCheck; 670 } 671 672 status_t err = UNKNOWN_ERROR; 673 674 Return<void> hResult = mPlugin->getSecureStops( 675 [&](Status status, const hidl_vec<SecureStop>& hSecureStops) { 676 if (status == Status::OK) { 677 secureStops = toSecureStops(hSecureStops); 678 } 679 err = toStatusT(status); 680 } 681 ); 682 683 return hResult.isOk() ? err : DEAD_OBJECT; 684 } 685 686 687 status_t DrmHal::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { 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->getSecureStop(toHidlVec(ssid), 697 [&](Status status, const SecureStop& hSecureStop) { 698 if (status == Status::OK) { 699 secureStop = toVector(hSecureStop.opaqueData); 700 } 701 err = toStatusT(status); 702 } 703 ); 704 705 return hResult.isOk() ? err : DEAD_OBJECT; 706 } 707 708 status_t DrmHal::releaseSecureStops(Vector<uint8_t> const &ssRelease) { 709 Mutex::Autolock autoLock(mLock); 710 711 if (mInitCheck != OK) { 712 return mInitCheck; 713 } 714 715 return toStatusT(mPlugin->releaseSecureStop(toHidlVec(ssRelease))); 716 } 717 718 status_t DrmHal::releaseAllSecureStops() { 719 Mutex::Autolock autoLock(mLock); 720 721 if (mInitCheck != OK) { 722 return mInitCheck; 723 } 724 725 return toStatusT(mPlugin->releaseAllSecureStops()); 726 } 727 728 status_t DrmHal::getPropertyString(String8 const &name, String8 &value ) const { 729 Mutex::Autolock autoLock(mLock); 730 731 if (mInitCheck != OK) { 732 return mInitCheck; 733 } 734 735 status_t err = UNKNOWN_ERROR; 736 737 Return<void> hResult = mPlugin->getPropertyString(toHidlString(name), 738 [&](Status status, const hidl_string& hValue) { 739 if (status == Status::OK) { 740 value = toString8(hValue); 741 } 742 err = toStatusT(status); 743 } 744 ); 745 746 return hResult.isOk() ? err : DEAD_OBJECT; 747 } 748 749 status_t DrmHal::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const { 750 Mutex::Autolock autoLock(mLock); 751 752 if (mInitCheck != OK) { 753 return mInitCheck; 754 } 755 756 status_t err = UNKNOWN_ERROR; 757 758 Return<void> hResult = mPlugin->getPropertyByteArray(toHidlString(name), 759 [&](Status status, const hidl_vec<uint8_t>& hValue) { 760 if (status == Status::OK) { 761 value = toVector(hValue); 762 } 763 err = toStatusT(status); 764 } 765 ); 766 767 return hResult.isOk() ? err : DEAD_OBJECT; 768 } 769 770 status_t DrmHal::setPropertyString(String8 const &name, String8 const &value ) const { 771 Mutex::Autolock autoLock(mLock); 772 773 if (mInitCheck != OK) { 774 return mInitCheck; 775 } 776 777 Status status = mPlugin->setPropertyString(toHidlString(name), 778 toHidlString(value)); 779 return toStatusT(status); 780 } 781 782 status_t DrmHal::setPropertyByteArray(String8 const &name, 783 Vector<uint8_t> const &value ) const { 784 Mutex::Autolock autoLock(mLock); 785 786 if (mInitCheck != OK) { 787 return mInitCheck; 788 } 789 790 Status status = mPlugin->setPropertyByteArray(toHidlString(name), 791 toHidlVec(value)); 792 return toStatusT(status); 793 } 794 795 796 status_t DrmHal::setCipherAlgorithm(Vector<uint8_t> const &sessionId, 797 String8 const &algorithm) { 798 Mutex::Autolock autoLock(mLock); 799 800 if (mInitCheck != OK) { 801 return mInitCheck; 802 } 803 804 DrmSessionManager::Instance()->useSession(sessionId); 805 806 Status status = mPlugin->setCipherAlgorithm(toHidlVec(sessionId), 807 toHidlString(algorithm)); 808 return toStatusT(status); 809 } 810 811 status_t DrmHal::setMacAlgorithm(Vector<uint8_t> const &sessionId, 812 String8 const &algorithm) { 813 Mutex::Autolock autoLock(mLock); 814 815 if (mInitCheck != OK) { 816 return mInitCheck; 817 } 818 819 DrmSessionManager::Instance()->useSession(sessionId); 820 821 Status status = mPlugin->setMacAlgorithm(toHidlVec(sessionId), 822 toHidlString(algorithm)); 823 return toStatusT(status); 824 } 825 826 status_t DrmHal::encrypt(Vector<uint8_t> const &sessionId, 827 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 828 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 829 Mutex::Autolock autoLock(mLock); 830 831 if (mInitCheck != OK) { 832 return mInitCheck; 833 } 834 835 DrmSessionManager::Instance()->useSession(sessionId); 836 837 status_t err = UNKNOWN_ERROR; 838 839 Return<void> hResult = mPlugin->encrypt(toHidlVec(sessionId), 840 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 841 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 842 if (status == Status::OK) { 843 output = toVector(hOutput); 844 } 845 err = toStatusT(status); 846 } 847 ); 848 849 return hResult.isOk() ? err : DEAD_OBJECT; 850 } 851 852 status_t DrmHal::decrypt(Vector<uint8_t> const &sessionId, 853 Vector<uint8_t> const &keyId, Vector<uint8_t> const &input, 854 Vector<uint8_t> const &iv, Vector<uint8_t> &output) { 855 Mutex::Autolock autoLock(mLock); 856 857 if (mInitCheck != OK) { 858 return mInitCheck; 859 } 860 861 DrmSessionManager::Instance()->useSession(sessionId); 862 863 status_t err = UNKNOWN_ERROR; 864 865 Return<void> hResult = mPlugin->decrypt(toHidlVec(sessionId), 866 toHidlVec(keyId), toHidlVec(input), toHidlVec(iv), 867 [&](Status status, const hidl_vec<uint8_t>& hOutput) { 868 if (status == Status::OK) { 869 output = toVector(hOutput); 870 } 871 err = toStatusT(status); 872 } 873 ); 874 875 return hResult.isOk() ? err : DEAD_OBJECT; 876 } 877 878 status_t DrmHal::sign(Vector<uint8_t> const &sessionId, 879 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 880 Vector<uint8_t> &signature) { 881 Mutex::Autolock autoLock(mLock); 882 883 if (mInitCheck != OK) { 884 return mInitCheck; 885 } 886 887 DrmSessionManager::Instance()->useSession(sessionId); 888 889 status_t err = UNKNOWN_ERROR; 890 891 Return<void> hResult = mPlugin->sign(toHidlVec(sessionId), 892 toHidlVec(keyId), toHidlVec(message), 893 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 894 if (status == Status::OK) { 895 signature = toVector(hSignature); 896 } 897 err = toStatusT(status); 898 } 899 ); 900 901 return hResult.isOk() ? err : DEAD_OBJECT; 902 } 903 904 status_t DrmHal::verify(Vector<uint8_t> const &sessionId, 905 Vector<uint8_t> const &keyId, Vector<uint8_t> const &message, 906 Vector<uint8_t> const &signature, bool &match) { 907 Mutex::Autolock autoLock(mLock); 908 909 if (mInitCheck != OK) { 910 return mInitCheck; 911 } 912 913 DrmSessionManager::Instance()->useSession(sessionId); 914 915 status_t err = UNKNOWN_ERROR; 916 917 Return<void> hResult = mPlugin->verify(toHidlVec(sessionId),toHidlVec(keyId), 918 toHidlVec(message), toHidlVec(signature), 919 [&](Status status, bool hMatch) { 920 if (status == Status::OK) { 921 match = hMatch; 922 } else { 923 match = false; 924 } 925 err = toStatusT(status); 926 } 927 ); 928 929 return hResult.isOk() ? err : DEAD_OBJECT; 930 } 931 932 status_t DrmHal::signRSA(Vector<uint8_t> const &sessionId, 933 String8 const &algorithm, Vector<uint8_t> const &message, 934 Vector<uint8_t> const &wrappedKey, Vector<uint8_t> &signature) { 935 Mutex::Autolock autoLock(mLock); 936 937 if (mInitCheck != OK) { 938 return mInitCheck; 939 } 940 941 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) { 942 return -EPERM; 943 } 944 945 DrmSessionManager::Instance()->useSession(sessionId); 946 947 status_t err = UNKNOWN_ERROR; 948 949 Return<void> hResult = mPlugin->signRSA(toHidlVec(sessionId), 950 toHidlString(algorithm), toHidlVec(message), toHidlVec(wrappedKey), 951 [&](Status status, const hidl_vec<uint8_t>& hSignature) { 952 if (status == Status::OK) { 953 signature = toVector(hSignature); 954 } 955 err = toStatusT(status); 956 } 957 ); 958 959 return hResult.isOk() ? err : DEAD_OBJECT; 960 } 961 962 void DrmHal::binderDied(const wp<IBinder> &the_late_who __unused) 963 { 964 Mutex::Autolock autoLock(mLock); 965 setListener(NULL); 966 if (mPlugin != NULL) { 967 mPlugin->setListener(NULL); 968 } 969 mPlugin.clear(); 970 mInitCheck = NO_INIT; 971 } 972 973 void DrmHal::writeByteArray(Parcel &obj, hidl_vec<uint8_t> const &vec) 974 { 975 if (vec.size()) { 976 obj.writeInt32(vec.size()); 977 obj.write(vec.data(), vec.size()); 978 } else { 979 obj.writeInt32(0); 980 } 981 } 982 983 } // namespace android 984