1 /* 2 * Copyright (C) 2018 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 "hidl_ClearKeyPlugin" 19 #include <utils/Log.h> 20 21 #include <stdio.h> 22 #include <inttypes.h> 23 24 #include "DrmPlugin.h" 25 #include "ClearKeyDrmProperties.h" 26 #include "Session.h" 27 #include "TypeConvert.h" 28 #include "Utils.h" 29 30 namespace { 31 const std::string kKeySetIdPrefix("ckid"); 32 const int kKeySetIdLength = 16; 33 const int kSecureStopIdStart = 100; 34 const std::string kOfflineLicense("\"type\":\"persistent-license\""); 35 const std::string kStreaming("Streaming"); 36 const std::string kTemporaryLicense("\"type\":\"temporary\""); 37 const std::string kTrue("True"); 38 39 const std::string kQueryKeyLicenseType("LicenseType"); 40 // Value: "Streaming" or "Offline" 41 const std::string kQueryKeyPlayAllowed("PlayAllowed"); 42 // Value: "True" or "False" 43 const std::string kQueryKeyRenewAllowed("RenewAllowed"); 44 // Value: "True" or "False" 45 46 const int kSecureStopIdSize = 10; 47 48 std::vector<uint8_t> uint32ToVector(uint32_t value) { 49 // 10 bytes to display max value 4294967295 + one byte null terminator 50 char buffer[kSecureStopIdSize]; 51 memset(buffer, 0, kSecureStopIdSize); 52 snprintf(buffer, kSecureStopIdSize, "%" PRIu32, value); 53 return std::vector<uint8_t>(buffer, buffer + sizeof(buffer)); 54 } 55 56 }; // unnamed namespace 57 58 namespace android { 59 namespace hardware { 60 namespace drm { 61 namespace V1_2 { 62 namespace clearkey { 63 64 KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) { 65 switch (keyRequestType) { 66 case KeyRequestType_V1_1::NONE: 67 case KeyRequestType_V1_1::UPDATE: 68 return KeyRequestType::UNKNOWN; 69 default: 70 return static_cast<KeyRequestType>(keyRequestType); 71 } 72 } 73 74 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary) 75 : mSessionLibrary(sessionLibrary), 76 mOpenSessionOkCount(0), 77 mCloseSessionOkCount(0), 78 mCloseSessionNotOpenedCount(0), 79 mNextSecureStopId(kSecureStopIdStart), 80 mMockError(Status_V1_2::OK) { 81 mPlayPolicy.clear(); 82 initProperties(); 83 mSecureStops.clear(); 84 mReleaseKeysMap.clear(); 85 std::srand(std::time(nullptr)); 86 } 87 88 void DrmPlugin::initProperties() { 89 mStringProperties.clear(); 90 mStringProperties[kVendorKey] = kVendorValue; 91 mStringProperties[kVersionKey] = kVersionValue; 92 mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue; 93 mStringProperties[kAlgorithmsKey] = kAlgorithmsValue; 94 mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue; 95 mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue; 96 97 std::vector<uint8_t> valueVector; 98 valueVector.clear(); 99 valueVector.insert(valueVector.end(), 100 kTestDeviceIdData, kTestDeviceIdData + sizeof(kTestDeviceIdData) / sizeof(uint8_t)); 101 mByteArrayProperties[kDeviceIdKey] = valueVector; 102 103 valueVector.clear(); 104 valueVector.insert(valueVector.end(), 105 kMetricsData, kMetricsData + sizeof(kMetricsData) / sizeof(uint8_t)); 106 mByteArrayProperties[kMetricsKey] = valueVector; 107 } 108 109 // The secure stop in ClearKey implementation is not installed securely. 110 // This function merely creates a test environment for testing secure stops APIs. 111 // The content in this secure stop is implementation dependent, the clearkey 112 // secureStop does not serve as a reference implementation. 113 void DrmPlugin::installSecureStop(const hidl_vec<uint8_t>& sessionId) { 114 ClearkeySecureStop clearkeySecureStop; 115 clearkeySecureStop.id = uint32ToVector(++mNextSecureStopId); 116 clearkeySecureStop.data.assign(sessionId.begin(), sessionId.end()); 117 118 mSecureStops.insert(std::pair<std::vector<uint8_t>, ClearkeySecureStop>( 119 clearkeySecureStop.id, clearkeySecureStop)); 120 } 121 122 Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) { 123 sp<Session> session = mSessionLibrary->createSession(); 124 processMockError(session); 125 std::vector<uint8_t> sessionId = session->sessionId(); 126 127 Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO); 128 _hidl_cb(status, toHidlVec(sessionId)); 129 mOpenSessionOkCount++; 130 return Void(); 131 } 132 133 Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel, 134 openSession_1_1_cb _hidl_cb) { 135 sp<Session> session = mSessionLibrary->createSession(); 136 processMockError(session); 137 std::vector<uint8_t> sessionId = session->sessionId(); 138 139 Status status = setSecurityLevel(sessionId, securityLevel); 140 _hidl_cb(status, toHidlVec(sessionId)); 141 mOpenSessionOkCount++; 142 return Void(); 143 } 144 145 Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) { 146 if (sessionId.size() == 0) { 147 return Status::BAD_VALUE; 148 } 149 150 sp<Session> session = mSessionLibrary->findSession(toVector(sessionId)); 151 if (session.get()) { 152 if (session->getMockError() != Status_V1_2::OK) { 153 sendSessionLostState(sessionId); 154 return Status::ERROR_DRM_INVALID_STATE; 155 } 156 mCloseSessionOkCount++; 157 mSessionLibrary->destroySession(session); 158 return Status::OK; 159 } 160 mCloseSessionNotOpenedCount++; 161 return Status::ERROR_DRM_SESSION_NOT_OPENED; 162 } 163 164 Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope, 165 const hidl_vec<uint8_t>& initData, 166 const hidl_string& mimeType, 167 KeyType keyType, 168 const hidl_vec<KeyValue>& optionalParameters, 169 std::vector<uint8_t> *request, 170 KeyRequestType_V1_1 *keyRequestType, 171 std::string *defaultUrl) { 172 UNUSED(optionalParameters); 173 174 // GetKeyRequestOfflineKeyTypeNotSupported() in vts 1.0 and 1.1 expects 175 // KeyType::OFFLINE to return ERROR_DRM_CANNOT_HANDLE in clearkey plugin. 176 // Those tests pass in an empty initData, we use the empty initData to 177 // signal such specific use case. 178 if (keyType == KeyType::OFFLINE && 0 == initData.size()) { 179 return Status_V1_2::ERROR_DRM_CANNOT_HANDLE; 180 } 181 182 *defaultUrl = ""; 183 *keyRequestType = KeyRequestType_V1_1::UNKNOWN; 184 *request = std::vector<uint8_t>(); 185 186 if (scope.size() == 0 || 187 (keyType != KeyType::STREAMING && 188 keyType != KeyType::OFFLINE && 189 keyType != KeyType::RELEASE)) { 190 return Status_V1_2::BAD_VALUE; 191 } 192 193 const std::vector<uint8_t> scopeId = toVector(scope); 194 sp<Session> session; 195 if (keyType == KeyType::STREAMING || keyType == KeyType::OFFLINE) { 196 std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end()); 197 session = mSessionLibrary->findSession(sessionId); 198 if (!session.get()) { 199 return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED; 200 } else if (session->getMockError() != Status_V1_2::OK) { 201 return session->getMockError(); 202 } 203 204 *keyRequestType = KeyRequestType_V1_1::INITIAL; 205 } 206 207 Status_V1_2 status = static_cast<Status_V1_2>( 208 session->getKeyRequest(initData, mimeType, keyType, request)); 209 210 if (keyType == KeyType::RELEASE) { 211 std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end()); 212 std::string requestString(request->begin(), request->end()); 213 if (requestString.find(kOfflineLicense) != std::string::npos) { 214 std::string emptyResponse; 215 std::string keySetIdString(keySetId.begin(), keySetId.end()); 216 if (!mFileHandle.StoreLicense(keySetIdString, 217 DeviceFiles::kLicenseStateReleasing, 218 emptyResponse)) { 219 ALOGE("Problem releasing offline license"); 220 return Status_V1_2::ERROR_DRM_UNKNOWN; 221 } 222 if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) { 223 sp<Session> session = mSessionLibrary->createSession(); 224 mReleaseKeysMap[keySetIdString] = session->sessionId(); 225 } else { 226 ALOGI("key is in use, ignore release request"); 227 } 228 } else { 229 ALOGE("Offline license not found, nothing to release"); 230 } 231 *keyRequestType = KeyRequestType_V1_1::RELEASE; 232 } 233 return status; 234 } 235 236 Return<void> DrmPlugin::getKeyRequest( 237 const hidl_vec<uint8_t>& scope, 238 const hidl_vec<uint8_t>& initData, 239 const hidl_string& mimeType, 240 KeyType keyType, 241 const hidl_vec<KeyValue>& optionalParameters, 242 getKeyRequest_cb _hidl_cb) { 243 UNUSED(optionalParameters); 244 245 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN; 246 std::string defaultUrl(""); 247 std::vector<uint8_t> request; 248 Status_V1_2 status = getKeyRequestCommon( 249 scope, initData, mimeType, keyType, optionalParameters, 250 &request, &keyRequestType, &defaultUrl); 251 252 _hidl_cb(toStatus_1_0(status), toHidlVec(request), 253 toKeyRequestType_V1_0(keyRequestType), 254 hidl_string(defaultUrl)); 255 return Void(); 256 } 257 258 Return<void> DrmPlugin::getKeyRequest_1_1( 259 const hidl_vec<uint8_t>& scope, 260 const hidl_vec<uint8_t>& initData, 261 const hidl_string& mimeType, 262 KeyType keyType, 263 const hidl_vec<KeyValue>& optionalParameters, 264 getKeyRequest_1_1_cb _hidl_cb) { 265 UNUSED(optionalParameters); 266 267 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN; 268 std::string defaultUrl(""); 269 std::vector<uint8_t> request; 270 Status_V1_2 status = getKeyRequestCommon( 271 scope, initData, mimeType, keyType, optionalParameters, 272 &request, &keyRequestType, &defaultUrl); 273 274 _hidl_cb(toStatus_1_0(status), toHidlVec(request), 275 keyRequestType, hidl_string(defaultUrl)); 276 return Void(); 277 } 278 279 Return<void> DrmPlugin::getKeyRequest_1_2( 280 const hidl_vec<uint8_t>& scope, 281 const hidl_vec<uint8_t>& initData, 282 const hidl_string& mimeType, 283 KeyType keyType, 284 const hidl_vec<KeyValue>& optionalParameters, 285 getKeyRequest_1_2_cb _hidl_cb) { 286 UNUSED(optionalParameters); 287 288 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN; 289 std::string defaultUrl(""); 290 std::vector<uint8_t> request; 291 Status_V1_2 status = getKeyRequestCommon( 292 scope, initData, mimeType, keyType, optionalParameters, 293 &request, &keyRequestType, &defaultUrl); 294 295 _hidl_cb(status, toHidlVec(request), keyRequestType, hidl_string(defaultUrl)); 296 return Void(); 297 } 298 299 void DrmPlugin::setPlayPolicy() { 300 mPlayPolicy.clear(); 301 302 KeyValue policy; 303 policy.key = kQueryKeyLicenseType; 304 policy.value = kStreaming; 305 mPlayPolicy.push_back(policy); 306 307 policy.key = kQueryKeyPlayAllowed; 308 policy.value = kTrue; 309 mPlayPolicy.push_back(policy); 310 311 policy.key = kQueryKeyRenewAllowed; 312 mPlayPolicy.push_back(policy); 313 } 314 315 bool DrmPlugin::makeKeySetId(std::string* keySetId) { 316 if (!keySetId) { 317 ALOGE("keySetId destination not provided"); 318 return false; 319 } 320 std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end()); 321 ksid.resize(kKeySetIdLength); 322 std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0); 323 324 while (keySetId->empty()) { 325 for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) { 326 *itr = std::rand() % 0xff; 327 } 328 *keySetId = kKeySetIdPrefix + ByteArrayToHexString( 329 reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size()); 330 if (mFileHandle.LicenseExists(*keySetId)) { 331 // collision, regenerate 332 ALOGV("Retry generating KeySetId"); 333 keySetId->clear(); 334 } 335 } 336 return true; 337 } 338 339 Return<void> DrmPlugin::provideKeyResponse( 340 const hidl_vec<uint8_t>& scope, 341 const hidl_vec<uint8_t>& response, 342 provideKeyResponse_cb _hidl_cb) { 343 if (scope.size() == 0 || response.size() == 0) { 344 // Returns empty keySetId 345 _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>()); 346 return Void(); 347 } 348 349 std::string responseString( 350 reinterpret_cast<const char*>(response.data()), response.size()); 351 const std::vector<uint8_t> scopeId = toVector(scope); 352 std::vector<uint8_t> sessionId; 353 std::string keySetId; 354 355 Status status = Status::OK; 356 bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos; 357 bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0); 358 if (isRelease) { 359 keySetId.assign(scopeId.begin(), scopeId.end()); 360 361 auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end())); 362 if (iter != mReleaseKeysMap.end()) { 363 sessionId.assign(iter->second.begin(), iter->second.end()); 364 } 365 } else { 366 sessionId.assign(scopeId.begin(), scopeId.end()); 367 // non offline license returns empty keySetId 368 keySetId.clear(); 369 } 370 371 sp<Session> session = mSessionLibrary->findSession(sessionId); 372 if (!session.get()) { 373 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>()); 374 return Void(); 375 } 376 setPlayPolicy(); 377 378 status = session->provideKeyResponse(response); 379 if (status == Status::OK) { 380 if (isOfflineLicense) { 381 if (isRelease) { 382 mFileHandle.DeleteLicense(keySetId); 383 } else { 384 if (!makeKeySetId(&keySetId)) { 385 _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>()); 386 return Void(); 387 } 388 389 bool ok = mFileHandle.StoreLicense( 390 keySetId, 391 DeviceFiles::kLicenseStateActive, 392 std::string(response.begin(), response.end())); 393 if (!ok) { 394 ALOGE("Failed to store offline license"); 395 } 396 } 397 } 398 399 // Test calling AMediaDrm listeners. 400 sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId); 401 402 sendExpirationUpdate(sessionId, 100); 403 404 std::vector<KeyStatus_V1_2> keysStatus; 405 KeyStatus_V1_2 keyStatus; 406 407 std::vector<uint8_t> keyId1 = { 0xA, 0xB, 0xC }; 408 keyStatus.keyId = keyId1; 409 keyStatus.type = V1_2::KeyStatusType::USABLE; 410 keysStatus.push_back(keyStatus); 411 412 std::vector<uint8_t> keyId2 = { 0xD, 0xE, 0xF }; 413 keyStatus.keyId = keyId2; 414 keyStatus.type = V1_2::KeyStatusType::EXPIRED; 415 keysStatus.push_back(keyStatus); 416 417 std::vector<uint8_t> keyId3 = { 0x0, 0x1, 0x2 }; 418 keyStatus.keyId = keyId3; 419 keyStatus.type = V1_2::KeyStatusType::USABLEINFUTURE; 420 keysStatus.push_back(keyStatus); 421 422 sendKeysChange_1_2(sessionId, keysStatus, true); 423 424 installSecureStop(sessionId); 425 } else { 426 ALOGE("provideKeyResponse returns error=%d", status); 427 } 428 429 std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end()); 430 _hidl_cb(status, toHidlVec(keySetIdVec)); 431 return Void(); 432 } 433 434 Return<Status> DrmPlugin::restoreKeys( 435 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) { 436 if (sessionId.size() == 0 || keySetId.size() == 0) { 437 return Status::BAD_VALUE; 438 } 439 440 DeviceFiles::LicenseState licenseState; 441 std::string offlineLicense; 442 Status status = Status::OK; 443 if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()), 444 &licenseState, &offlineLicense)) { 445 ALOGE("Failed to restore offline license"); 446 return Status::ERROR_DRM_NO_LICENSE; 447 } 448 449 if (DeviceFiles::kLicenseStateUnknown == licenseState || 450 DeviceFiles::kLicenseStateReleasing == licenseState) { 451 ALOGE("Invalid license state=%d", licenseState); 452 return Status::ERROR_DRM_NO_LICENSE; 453 } 454 455 sp<Session> session = mSessionLibrary->findSession(toVector(sessionId)); 456 if (!session.get()) { 457 return Status::ERROR_DRM_SESSION_NOT_OPENED; 458 } 459 status = session->provideKeyResponse(std::vector<uint8_t>(offlineLicense.begin(), 460 offlineLicense.end())); 461 if (status != Status::OK) { 462 ALOGE("Failed to restore keys"); 463 } 464 return status; 465 } 466 467 Return<void> DrmPlugin::getPropertyString( 468 const hidl_string& propertyName, getPropertyString_cb _hidl_cb) { 469 std::string name(propertyName.c_str()); 470 std::string value; 471 472 if (name == kVendorKey) { 473 value = mStringProperties[kVendorKey]; 474 } else if (name == kVersionKey) { 475 value = mStringProperties[kVersionKey]; 476 } else if (name == kPluginDescriptionKey) { 477 value = mStringProperties[kPluginDescriptionKey]; 478 } else if (name == kAlgorithmsKey) { 479 value = mStringProperties[kAlgorithmsKey]; 480 } else if (name == kListenerTestSupportKey) { 481 value = mStringProperties[kListenerTestSupportKey]; 482 } else if (name == kDrmErrorTestKey) { 483 value = mStringProperties[kDrmErrorTestKey]; 484 } else { 485 ALOGE("App requested unknown string property %s", name.c_str()); 486 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, ""); 487 return Void(); 488 } 489 _hidl_cb(Status::OK, value.c_str()); 490 return Void(); 491 } 492 493 Return<void> DrmPlugin::getPropertyByteArray( 494 const hidl_string& propertyName, getPropertyByteArray_cb _hidl_cb) { 495 std::map<std::string, std::vector<uint8_t> >::iterator itr = 496 mByteArrayProperties.find(std::string(propertyName.c_str())); 497 if (itr == mByteArrayProperties.end()) { 498 ALOGE("App requested unknown property: %s", propertyName.c_str()); 499 _hidl_cb(Status::BAD_VALUE, std::vector<uint8_t>()); 500 return Void(); 501 } 502 _hidl_cb(Status::OK, itr->second); 503 return Void(); 504 505 } 506 507 Return<Status> DrmPlugin::setPropertyString( 508 const hidl_string& name, const hidl_string& value) { 509 std::string immutableKeys; 510 immutableKeys.append(kAlgorithmsKey + ","); 511 immutableKeys.append(kPluginDescriptionKey + ","); 512 immutableKeys.append(kVendorKey + ","); 513 immutableKeys.append(kVersionKey + ","); 514 515 std::string key = std::string(name.c_str()); 516 if (immutableKeys.find(key) != std::string::npos) { 517 ALOGD("Cannot set immutable property: %s", key.c_str()); 518 return Status::BAD_VALUE; 519 } 520 521 std::map<std::string, std::string>::iterator itr = 522 mStringProperties.find(key); 523 if (itr == mStringProperties.end()) { 524 ALOGE("Cannot set undefined property string, key=%s", key.c_str()); 525 return Status::BAD_VALUE; 526 } 527 528 if (name == kDrmErrorTestKey) { 529 if (value == kResourceContentionValue) { 530 mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION; 531 } else if (value == kLostStateValue) { 532 mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE; 533 } else if (value == kFrameTooLargeValue) { 534 mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE; 535 } else if (value == kInvalidStateValue) { 536 mMockError = Status_V1_2::ERROR_DRM_INVALID_STATE; 537 } else { 538 mMockError = Status_V1_2::ERROR_DRM_UNKNOWN; 539 } 540 } 541 542 mStringProperties[key] = std::string(value.c_str()); 543 return Status::OK; 544 } 545 546 Return<Status> DrmPlugin::setPropertyByteArray( 547 const hidl_string& name, const hidl_vec<uint8_t>& value) { 548 UNUSED(value); 549 if (name == kDeviceIdKey) { 550 ALOGD("Cannot set immutable property: %s", name.c_str()); 551 return Status::BAD_VALUE; 552 } else if (name == kClientIdKey) { 553 mByteArrayProperties[kClientIdKey] = toVector(value); 554 return Status::OK; 555 } 556 557 // Setting of undefined properties is not supported 558 ALOGE("Failed to set property byte array, key=%s", name.c_str()); 559 return Status::ERROR_DRM_CANNOT_HANDLE; 560 } 561 562 Return<void> DrmPlugin::queryKeyStatus( 563 const hidl_vec<uint8_t>& sessionId, 564 queryKeyStatus_cb _hidl_cb) { 565 566 if (sessionId.size() == 0) { 567 // Returns empty key status KeyValue pair 568 _hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>()); 569 return Void(); 570 } 571 572 std::vector<KeyValue> infoMapVec; 573 infoMapVec.clear(); 574 575 KeyValue keyValuePair; 576 for (size_t i = 0; i < mPlayPolicy.size(); ++i) { 577 keyValuePair.key = mPlayPolicy[i].key; 578 keyValuePair.value = mPlayPolicy[i].value; 579 infoMapVec.push_back(keyValuePair); 580 } 581 _hidl_cb(Status::OK, toHidlVec(infoMapVec)); 582 return Void(); 583 } 584 585 Return<void> DrmPlugin::getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) { 586 uint32_t currentSessions = mSessionLibrary->numOpenSessions(); 587 uint32_t maxSessions = 10; 588 _hidl_cb(Status::OK, currentSessions, maxSessions); 589 return Void(); 590 } 591 592 Return<void> DrmPlugin::getSecurityLevel(const hidl_vec<uint8_t>& sessionId, 593 getSecurityLevel_cb _hidl_cb) { 594 if (sessionId.size() == 0) { 595 _hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN); 596 return Void(); 597 } 598 599 std::vector<uint8_t> sid = toVector(sessionId); 600 sp<Session> session = mSessionLibrary->findSession(sid); 601 if (!session.get()) { 602 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, SecurityLevel::UNKNOWN); 603 return Void(); 604 } 605 606 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr = 607 mSecurityLevel.find(sid); 608 if (itr == mSecurityLevel.end()) { 609 ALOGE("Session id not found"); 610 _hidl_cb(Status::ERROR_DRM_INVALID_STATE, SecurityLevel::UNKNOWN); 611 return Void(); 612 } 613 614 _hidl_cb(Status::OK, itr->second); 615 return Void(); 616 } 617 618 Return<Status> DrmPlugin::setSecurityLevel(const hidl_vec<uint8_t>& sessionId, 619 SecurityLevel level) { 620 if (sessionId.size() == 0) { 621 ALOGE("Invalid empty session id"); 622 return Status::BAD_VALUE; 623 } 624 625 if (level > SecurityLevel::SW_SECURE_CRYPTO) { 626 ALOGE("Cannot set security level > max"); 627 return Status::ERROR_DRM_CANNOT_HANDLE; 628 } 629 630 std::vector<uint8_t> sid = toVector(sessionId); 631 sp<Session> session = mSessionLibrary->findSession(sid); 632 if (!session.get()) { 633 return Status::ERROR_DRM_SESSION_NOT_OPENED; 634 } 635 636 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr = 637 mSecurityLevel.find(sid); 638 if (itr != mSecurityLevel.end()) { 639 mSecurityLevel[sid] = level; 640 } else { 641 if (!mSecurityLevel.insert( 642 std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level)).second) { 643 ALOGE("Failed to set security level"); 644 return Status::ERROR_DRM_INVALID_STATE; 645 } 646 } 647 return Status::OK; 648 } 649 650 Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) { 651 // Set the open session count metric. 652 DrmMetricGroup::Attribute openSessionOkAttribute = { 653 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, "" 654 }; 655 DrmMetricGroup::Value openSessionMetricValue = { 656 "count", DrmMetricGroup::ValueType::INT64_TYPE, mOpenSessionOkCount, 0.0, "" 657 }; 658 DrmMetricGroup::Metric openSessionMetric = { 659 "open_session", { openSessionOkAttribute }, { openSessionMetricValue } 660 }; 661 662 // Set the close session count metric. 663 DrmMetricGroup::Attribute closeSessionOkAttribute = { 664 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, "" 665 }; 666 DrmMetricGroup::Value closeSessionMetricValue = { 667 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionOkCount, 0.0, "" 668 }; 669 DrmMetricGroup::Metric closeSessionMetric = { 670 "close_session", { closeSessionOkAttribute }, { closeSessionMetricValue } 671 }; 672 673 // Set the close session, not opened metric. 674 DrmMetricGroup::Attribute closeSessionNotOpenedAttribute = { 675 "status", DrmMetricGroup::ValueType::INT64_TYPE, 676 (int64_t) Status::ERROR_DRM_SESSION_NOT_OPENED, 0.0, "" 677 }; 678 DrmMetricGroup::Value closeSessionNotOpenedMetricValue = { 679 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionNotOpenedCount, 0.0, "" 680 }; 681 DrmMetricGroup::Metric closeSessionNotOpenedMetric = { 682 "close_session", { closeSessionNotOpenedAttribute }, { closeSessionNotOpenedMetricValue } 683 }; 684 685 DrmMetricGroup metrics = { { openSessionMetric, closeSessionMetric, 686 closeSessionNotOpenedMetric } }; 687 688 _hidl_cb(Status::OK, hidl_vec<DrmMetricGroup>({metrics})); 689 return Void(); 690 } 691 692 Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) { 693 std::vector<std::string> licenseNames = mFileHandle.ListLicenses(); 694 std::vector<KeySetId> keySetIds; 695 if (mMockError != Status_V1_2::OK) { 696 _hidl_cb(toStatus_1_0(mMockError), keySetIds); 697 return Void(); 698 } 699 for (const auto& name : licenseNames) { 700 std::vector<uint8_t> keySetId(name.begin(), name.end()); 701 keySetIds.push_back(keySetId); 702 } 703 _hidl_cb(Status::OK, keySetIds); 704 return Void(); 705 } 706 707 708 Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) { 709 if (mMockError != Status_V1_2::OK) { 710 return toStatus_1_0(mMockError); 711 } 712 std::string licenseName(keySetId.begin(), keySetId.end()); 713 if (mFileHandle.DeleteLicense(licenseName)) { 714 return Status::OK; 715 } 716 return Status::BAD_VALUE; 717 } 718 719 Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId, 720 getOfflineLicenseState_cb _hidl_cb) { 721 std::string licenseName(keySetId.begin(), keySetId.end()); 722 DeviceFiles::LicenseState state; 723 std::string license; 724 OfflineLicenseState hLicenseState; 725 if (mMockError != Status_V1_2::OK) { 726 _hidl_cb(toStatus_1_0(mMockError), OfflineLicenseState::UNKNOWN); 727 } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) { 728 switch (state) { 729 case DeviceFiles::kLicenseStateActive: 730 hLicenseState = OfflineLicenseState::USABLE; 731 break; 732 case DeviceFiles::kLicenseStateReleasing: 733 hLicenseState = OfflineLicenseState::INACTIVE; 734 break; 735 case DeviceFiles::kLicenseStateUnknown: 736 hLicenseState = OfflineLicenseState::UNKNOWN; 737 break; 738 } 739 _hidl_cb(Status::OK, hLicenseState); 740 } else { 741 _hidl_cb(Status::BAD_VALUE, OfflineLicenseState::UNKNOWN); 742 } 743 return Void(); 744 } 745 746 Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { 747 std::vector<SecureStop> stops; 748 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) { 749 ClearkeySecureStop clearkeyStop = itr->second; 750 std::vector<uint8_t> stopVec; 751 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end()); 752 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end()); 753 754 SecureStop stop; 755 stop.opaqueData = toHidlVec(stopVec); 756 stops.push_back(stop); 757 } 758 _hidl_cb(Status::OK, stops); 759 return Void(); 760 } 761 762 Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId, 763 getSecureStop_cb _hidl_cb) { 764 SecureStop stop; 765 auto itr = mSecureStops.find(toVector(secureStopId)); 766 if (itr != mSecureStops.end()) { 767 ClearkeySecureStop clearkeyStop = itr->second; 768 std::vector<uint8_t> stopVec; 769 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end()); 770 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end()); 771 772 stop.opaqueData = toHidlVec(stopVec); 773 _hidl_cb(Status::OK, stop); 774 } else { 775 _hidl_cb(Status::BAD_VALUE, stop); 776 } 777 778 return Void(); 779 } 780 781 Return<Status> DrmPlugin::releaseSecureStop(const hidl_vec<uint8_t>& secureStopId) { 782 return removeSecureStop(secureStopId); 783 } 784 785 Return<Status> DrmPlugin::releaseAllSecureStops() { 786 return removeAllSecureStops(); 787 } 788 789 Return<void> DrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) { 790 std::vector<SecureStopId> ids; 791 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) { 792 ids.push_back(itr->first); 793 } 794 795 _hidl_cb(Status::OK, toHidlVec(ids)); 796 return Void(); 797 } 798 799 Return<Status> DrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) { 800 if (ssRelease.opaqueData.size() == 0) { 801 return Status::BAD_VALUE; 802 } 803 804 Status status = Status::OK; 805 std::vector<uint8_t> input = toVector(ssRelease.opaqueData); 806 807 // The format of opaqueData is shared between the server 808 // and the drm service. The clearkey implementation consists of: 809 // count - number of secure stops 810 // list of fixed length secure stops 811 size_t countBufferSize = sizeof(uint32_t); 812 uint32_t count = 0; 813 sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count); 814 815 // Avoid divide by 0 below. 816 if (count == 0) { 817 return Status::BAD_VALUE; 818 } 819 820 size_t secureStopSize = (input.size() - countBufferSize) / count; 821 uint8_t buffer[secureStopSize]; 822 size_t offset = countBufferSize; // skip the count 823 for (size_t i = 0; i < count; ++i, offset += secureStopSize) { 824 memcpy(buffer, input.data() + offset, secureStopSize); 825 std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize); 826 827 status = removeSecureStop(toHidlVec(id)); 828 if (Status::OK != status) break; 829 } 830 831 return status; 832 } 833 834 Return<Status> DrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId) { 835 if (1 != mSecureStops.erase(toVector(secureStopId))) { 836 return Status::BAD_VALUE; 837 } 838 return Status::OK; 839 } 840 841 Return<Status> DrmPlugin::removeAllSecureStops() { 842 mSecureStops.clear(); 843 mNextSecureStopId = kSecureStopIdStart; 844 return Status::OK; 845 } 846 847 } // namespace clearkey 848 } // namespace V1_2 849 } // namespace drm 850 } // namespace hardware 851 } // namespace android 852