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_TAG "drm_hal_vendor_test (at) 1.0" 18 19 #include <android-base/logging.h> 20 #include <android/hardware/drm/1.0/ICryptoFactory.h> 21 #include <android/hardware/drm/1.0/ICryptoPlugin.h> 22 #include <android/hardware/drm/1.0/IDrmFactory.h> 23 #include <android/hardware/drm/1.0/IDrmPlugin.h> 24 #include <android/hardware/drm/1.0/IDrmPluginListener.h> 25 #include <android/hardware/drm/1.0/types.h> 26 #include <android/hidl/allocator/1.0/IAllocator.h> 27 #include <gtest/gtest.h> 28 #include <hidlmemory/mapping.h> 29 #include <log/log.h> 30 #include <openssl/aes.h> 31 #include <memory> 32 #include <random> 33 34 #include "drm_hal_vendor_module_api.h" 35 #include "vendor_modules.h" 36 #include <VtsHalHidlTargetCallbackBase.h> 37 #include <VtsHalHidlTargetTestBase.h> 38 39 using ::android::hardware::drm::V1_0::BufferType; 40 using ::android::hardware::drm::V1_0::DestinationBuffer; 41 using ::android::hardware::drm::V1_0::EventType; 42 using ::android::hardware::drm::V1_0::ICryptoFactory; 43 using ::android::hardware::drm::V1_0::ICryptoPlugin; 44 using ::android::hardware::drm::V1_0::IDrmFactory; 45 using ::android::hardware::drm::V1_0::IDrmPlugin; 46 using ::android::hardware::drm::V1_0::IDrmPluginListener; 47 using ::android::hardware::drm::V1_0::KeyedVector; 48 using ::android::hardware::drm::V1_0::KeyRequestType; 49 using ::android::hardware::drm::V1_0::KeyStatus; 50 using ::android::hardware::drm::V1_0::KeyStatusType; 51 using ::android::hardware::drm::V1_0::KeyType; 52 using ::android::hardware::drm::V1_0::KeyValue; 53 using ::android::hardware::drm::V1_0::Mode; 54 using ::android::hardware::drm::V1_0::Pattern; 55 using ::android::hardware::drm::V1_0::SecureStop; 56 using ::android::hardware::drm::V1_0::SecureStopId; 57 using ::android::hardware::drm::V1_0::SessionId; 58 using ::android::hardware::drm::V1_0::SharedBuffer; 59 using ::android::hardware::drm::V1_0::Status; 60 using ::android::hardware::drm::V1_0::SubSample; 61 62 using ::android::hardware::hidl_array; 63 using ::android::hardware::hidl_memory; 64 using ::android::hardware::hidl_string; 65 using ::android::hardware::hidl_vec; 66 using ::android::hardware::Return; 67 using ::android::hardware::Void; 68 using ::android::hidl::allocator::V1_0::IAllocator; 69 using ::android::hidl::memory::V1_0::IMemory; 70 using ::android::sp; 71 72 using std::string; 73 using std::unique_ptr; 74 using std::random_device; 75 using std::map; 76 using std::mt19937; 77 using std::vector; 78 79 using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration; 80 using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key; 81 using VtsTestBase = ::testing::VtsHalHidlTargetTestBase; 82 83 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) 84 #define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) 85 86 #define RETURN_IF_SKIPPED \ 87 if (!vendorModule->isInstalled()) { \ 88 std::cout << "[ SKIPPED ] This drm scheme not supported." << \ 89 " library:" << GetParam() << " service-name:" << \ 90 vendorModule->getServiceName() << std::endl; \ 91 return; \ 92 } 93 94 static const uint8_t kInvalidUUID[16] = { 95 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 96 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 97 }; 98 99 static drm_vts::VendorModules* gVendorModules = nullptr; 100 101 class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> { 102 public: 103 DrmHalVendorFactoryTest() 104 : vendorModule(static_cast<DrmHalVTSVendorModule_V1*>( 105 gVendorModules->getModule(GetParam()))), 106 contentConfigurations(vendorModule->getContentConfigurations()) {} 107 108 virtual ~DrmHalVendorFactoryTest() {} 109 110 virtual void SetUp() { 111 const ::testing::TestInfo* const test_info = 112 ::testing::UnitTest::GetInstance()->current_test_info(); 113 ALOGD("Running test %s.%s from vendor module %s", 114 test_info->test_case_name(), test_info->name(), 115 GetParam().c_str()); 116 117 ASSERT_NE(vendorModule, nullptr); 118 119 // First try the binderized service name provided by the vendor module. 120 // If that fails, which it can on non-binderized devices, try the default 121 // service. 122 string name = vendorModule->getServiceName(); 123 drmFactory = VtsTestBase::getService<IDrmFactory>(name); 124 if (drmFactory == nullptr) { 125 drmFactory = VtsTestBase::getService<IDrmFactory>(); 126 } 127 ASSERT_NE(drmFactory, nullptr); 128 129 // Do the same for the crypto factory 130 cryptoFactory = VtsTestBase::getService<ICryptoFactory>(name); 131 if (cryptoFactory == nullptr) { 132 cryptoFactory = VtsTestBase::getService<ICryptoFactory>(); 133 } 134 ASSERT_NE(cryptoFactory, nullptr); 135 136 // If drm scheme not installed skip subsequent tests 137 if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) { 138 vendorModule->setInstalled(false); 139 return; 140 } 141 } 142 143 virtual void TearDown() override {} 144 145 protected: 146 hidl_array<uint8_t, 16> getVendorUUID() { 147 vector<uint8_t> uuid = vendorModule->getUUID(); 148 return hidl_array<uint8_t, 16>(&uuid[0]); 149 } 150 151 sp<IDrmFactory> drmFactory; 152 sp<ICryptoFactory> cryptoFactory; 153 unique_ptr<DrmHalVTSVendorModule_V1> vendorModule; 154 const vector<ContentConfiguration> contentConfigurations; 155 }; 156 157 TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) { 158 const char* kVendorStr = "Vendor module "; 159 size_t count = 0; 160 for (auto config : contentConfigurations) { 161 ASSERT_TRUE(config.name.size() > 0) << kVendorStr << "has no name"; 162 ASSERT_TRUE(config.serverUrl.size() > 0) << kVendorStr 163 << "has no serverUrl"; 164 ASSERT_TRUE(config.initData.size() > 0) << kVendorStr 165 << "has no init data"; 166 ASSERT_TRUE(config.mimeType.size() > 0) << kVendorStr 167 << "has no mime type"; 168 ASSERT_TRUE(config.keys.size() >= 1) << kVendorStr << "has no keys"; 169 for (auto key : config.keys) { 170 ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr 171 << " has zero length keyId"; 172 ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr 173 << " has zero length key value"; 174 } 175 count++; 176 } 177 EXPECT_NE(0u, count); 178 } 179 180 /** 181 * Ensure the factory doesn't support an invalid scheme UUID 182 */ 183 TEST_P(DrmHalVendorFactoryTest, InvalidPluginNotSupported) { 184 EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(kInvalidUUID)); 185 EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(kInvalidUUID)); 186 } 187 188 /** 189 * Ensure the factory doesn't support an empty UUID 190 */ 191 TEST_P(DrmHalVendorFactoryTest, EmptyPluginUUIDNotSupported) { 192 hidl_array<uint8_t, 16> emptyUUID; 193 memset(emptyUUID.data(), 0, 16); 194 EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(emptyUUID)); 195 EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(emptyUUID)); 196 } 197 198 /** 199 * Check if the factory supports the scheme uuid in the config. 200 */ 201 TEST_P(DrmHalVendorFactoryTest, PluginConfigUUIDSupported) { 202 RETURN_IF_SKIPPED; 203 EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getVendorUUID())); 204 EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getVendorUUID())); 205 } 206 207 /** 208 * Ensure empty content type is not supported 209 */ 210 TEST_P(DrmHalVendorFactoryTest, EmptyContentTypeNotSupported) { 211 hidl_string empty; 212 EXPECT_FALSE(drmFactory->isContentTypeSupported(empty)); 213 } 214 215 /** 216 * Ensure invalid content type is not supported 217 */ 218 TEST_P(DrmHalVendorFactoryTest, InvalidContentTypeNotSupported) { 219 hidl_string invalid("abcdabcd"); 220 EXPECT_FALSE(drmFactory->isContentTypeSupported(invalid)); 221 } 222 223 /** 224 * Ensure valid content types in the configs are supported 225 */ 226 TEST_P(DrmHalVendorFactoryTest, ValidContentTypeSupported) { 227 RETURN_IF_SKIPPED; 228 for (auto config : contentConfigurations) { 229 EXPECT_TRUE(drmFactory->isContentTypeSupported(config.mimeType)); 230 } 231 } 232 233 /** 234 * Ensure vendor drm plugin can be created 235 */ 236 TEST_P(DrmHalVendorFactoryTest, CreateVendorDrmPlugin) { 237 RETURN_IF_SKIPPED; 238 hidl_string packageName("android.hardware.drm.test"); 239 auto res = drmFactory->createPlugin( 240 getVendorUUID(), packageName, 241 [&](Status status, const sp<IDrmPlugin>& plugin) { 242 EXPECT_EQ(Status::OK, status); 243 EXPECT_NE(plugin, nullptr); 244 }); 245 EXPECT_OK(res); 246 } 247 248 /** 249 * Ensure vendor crypto plugin can be created 250 */ 251 TEST_P(DrmHalVendorFactoryTest, CreateVendorCryptoPlugin) { 252 RETURN_IF_SKIPPED; 253 hidl_vec<uint8_t> initVec; 254 auto res = cryptoFactory->createPlugin( 255 getVendorUUID(), initVec, 256 [&](Status status, const sp<ICryptoPlugin>& plugin) { 257 EXPECT_EQ(Status::OK, status); 258 EXPECT_NE(plugin, nullptr); 259 }); 260 EXPECT_OK(res); 261 } 262 263 /** 264 * Ensure invalid drm plugin can't be created 265 */ 266 TEST_P(DrmHalVendorFactoryTest, CreateInvalidDrmPlugin) { 267 RETURN_IF_SKIPPED; 268 hidl_string packageName("android.hardware.drm.test"); 269 auto res = drmFactory->createPlugin( 270 kInvalidUUID, packageName, 271 [&](Status status, const sp<IDrmPlugin>& plugin) { 272 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 273 EXPECT_EQ(plugin, nullptr); 274 }); 275 EXPECT_OK(res); 276 } 277 278 /** 279 * Ensure invalid crypto plugin can't be created 280 */ 281 TEST_P(DrmHalVendorFactoryTest, CreateInvalidCryptoPlugin) { 282 RETURN_IF_SKIPPED; 283 hidl_vec<uint8_t> initVec; 284 auto res = cryptoFactory->createPlugin( 285 kInvalidUUID, initVec, 286 [&](Status status, const sp<ICryptoPlugin>& plugin) { 287 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 288 EXPECT_EQ(plugin, nullptr); 289 }); 290 EXPECT_OK(res); 291 } 292 293 class DrmHalVendorPluginTest : public DrmHalVendorFactoryTest { 294 public: 295 virtual ~DrmHalVendorPluginTest() {} 296 virtual void SetUp() override { 297 // Create factories 298 DrmHalVendorFactoryTest::SetUp(); 299 RETURN_IF_SKIPPED; 300 301 hidl_string packageName("android.hardware.drm.test"); 302 auto res = drmFactory->createPlugin( 303 getVendorUUID(), packageName, 304 [this](Status status, const sp<IDrmPlugin>& plugin) { 305 EXPECT_EQ(Status::OK, status); 306 ASSERT_NE(plugin, nullptr); 307 drmPlugin = plugin; 308 }); 309 ASSERT_OK(res); 310 311 hidl_vec<uint8_t> initVec; 312 res = cryptoFactory->createPlugin( 313 getVendorUUID(), initVec, 314 [this](Status status, const sp<ICryptoPlugin>& plugin) { 315 EXPECT_EQ(Status::OK, status); 316 ASSERT_NE(plugin, nullptr); 317 cryptoPlugin = plugin; 318 }); 319 ASSERT_OK(res); 320 } 321 322 virtual void TearDown() override {} 323 324 SessionId openSession(); 325 void closeSession(const SessionId& sessionId); 326 sp<IMemory> getDecryptMemory(size_t size, size_t index); 327 KeyedVector toHidlKeyedVector(const map<string, string>& params); 328 hidl_vec<uint8_t> loadKeys(const SessionId& sessionId, 329 const ContentConfiguration& configuration, 330 const KeyType& type); 331 332 protected: 333 sp<IDrmPlugin> drmPlugin; 334 sp<ICryptoPlugin> cryptoPlugin; 335 }; 336 337 /** 338 * DrmPlugin tests 339 */ 340 341 /** 342 * Test that a DRM plugin can handle provisioning. While 343 * it is not required that a DRM scheme require provisioning, 344 * it should at least return appropriate status values. If 345 * a provisioning request is returned, it is passed to the 346 * vendor module which should provide a provisioning response 347 * that is delivered back to the HAL. 348 */ 349 350 TEST_P(DrmHalVendorPluginTest, DoProvisioning) { 351 RETURN_IF_SKIPPED; 352 hidl_string certificateType; 353 hidl_string certificateAuthority; 354 hidl_vec<uint8_t> provisionRequest; 355 hidl_string defaultUrl; 356 auto res = drmPlugin->getProvisionRequest( 357 certificateType, certificateAuthority, 358 [&](Status status, const hidl_vec<uint8_t>& request, 359 const hidl_string& url) { 360 if (status == Status::OK) { 361 EXPECT_NE(request.size(), 0u); 362 provisionRequest = request; 363 defaultUrl = url; 364 } else if (status == Status::ERROR_DRM_CANNOT_HANDLE) { 365 EXPECT_EQ(0u, request.size()); 366 } 367 }); 368 EXPECT_OK(res); 369 370 if (provisionRequest.size() > 0) { 371 vector<uint8_t> response = vendorModule->handleProvisioningRequest( 372 provisionRequest, defaultUrl); 373 ASSERT_NE(0u, response.size()); 374 375 auto res = drmPlugin->provideProvisionResponse( 376 response, [&](Status status, const hidl_vec<uint8_t>&, 377 const hidl_vec<uint8_t>&) { 378 EXPECT_EQ(Status::OK, status); 379 }); 380 EXPECT_OK(res); 381 } 382 } 383 384 /** 385 * The DRM HAL should return BAD_VALUE if an empty provisioning 386 * response is provided. 387 */ 388 TEST_P(DrmHalVendorPluginTest, ProvideEmptyProvisionResponse) { 389 RETURN_IF_SKIPPED; 390 hidl_vec<uint8_t> response; 391 auto res = drmPlugin->provideProvisionResponse( 392 response, [&](Status status, const hidl_vec<uint8_t>&, 393 const hidl_vec<uint8_t>&) { 394 EXPECT_EQ(Status::BAD_VALUE, status); 395 }); 396 EXPECT_OK(res); 397 } 398 399 /** 400 * Helper method to open a session and verify that a non-empty 401 * session ID is returned 402 */ 403 SessionId DrmHalVendorPluginTest::openSession() { 404 SessionId sessionId; 405 406 auto res = drmPlugin->openSession([&](Status status, const SessionId& id) { 407 EXPECT_EQ(Status::OK, status); 408 EXPECT_NE(id.size(), 0u); 409 sessionId = id; 410 }); 411 EXPECT_OK(res); 412 return sessionId; 413 } 414 415 /** 416 * Helper method to close a session 417 */ 418 void DrmHalVendorPluginTest::closeSession(const SessionId& sessionId) { 419 Status status = drmPlugin->closeSession(sessionId); 420 EXPECT_EQ(Status::OK, status); 421 } 422 423 KeyedVector DrmHalVendorPluginTest::toHidlKeyedVector( 424 const map<string, string>& params) { 425 std::vector<KeyValue> stdKeyedVector; 426 for (auto it = params.begin(); it != params.end(); ++it) { 427 KeyValue keyValue; 428 keyValue.key = it->first; 429 keyValue.value = it->second; 430 stdKeyedVector.push_back(keyValue); 431 } 432 return KeyedVector(stdKeyedVector); 433 } 434 435 /** 436 * Helper method to load keys for subsequent decrypt tests. 437 * These tests use predetermined key request/response to 438 * avoid requiring a round trip to a license server. 439 */ 440 hidl_vec<uint8_t> DrmHalVendorPluginTest::loadKeys( 441 const SessionId& sessionId, const ContentConfiguration& configuration, 442 const KeyType& type = KeyType::STREAMING) { 443 hidl_vec<uint8_t> keyRequest; 444 auto res = drmPlugin->getKeyRequest( 445 sessionId, configuration.initData, configuration.mimeType, type, 446 toHidlKeyedVector(configuration.optionalParameters), 447 [&](Status status, const hidl_vec<uint8_t>& request, 448 KeyRequestType type, const hidl_string&) { 449 EXPECT_EQ(Status::OK, status) << "Failed to get " 450 "key request for configuration " 451 << configuration.name; 452 EXPECT_EQ(type, KeyRequestType::INITIAL); 453 EXPECT_NE(request.size(), 0u) << "Expected key request size" 454 " to have length > 0 bytes"; 455 keyRequest = request; 456 }); 457 EXPECT_OK(res); 458 459 /** 460 * Get key response from vendor module 461 */ 462 hidl_vec<uint8_t> keyResponse = 463 vendorModule->handleKeyRequest(keyRequest, configuration.serverUrl); 464 465 EXPECT_NE(keyResponse.size(), 0u) << "Expected key response size " 466 "to have length > 0 bytes"; 467 468 hidl_vec<uint8_t> keySetId; 469 res = drmPlugin->provideKeyResponse( 470 sessionId, keyResponse, 471 [&](Status status, const hidl_vec<uint8_t>& myKeySetId) { 472 EXPECT_EQ(Status::OK, status) << "Failure providing " 473 "key response for configuration " 474 << configuration.name; 475 keySetId = myKeySetId; 476 }); 477 EXPECT_OK(res); 478 return keySetId; 479 } 480 481 /** 482 * Test that a session can be opened and closed 483 */ 484 TEST_P(DrmHalVendorPluginTest, OpenCloseSession) { 485 RETURN_IF_SKIPPED; 486 auto sessionId = openSession(); 487 closeSession(sessionId); 488 } 489 490 /** 491 * Test that attempting to close an invalid (empty) sessionId 492 * is prohibited with the documented error code. 493 */ 494 TEST_P(DrmHalVendorPluginTest, CloseInvalidSession) { 495 RETURN_IF_SKIPPED; 496 SessionId invalidSessionId; 497 Status status = drmPlugin->closeSession(invalidSessionId); 498 EXPECT_EQ(Status::BAD_VALUE, status); 499 } 500 501 /** 502 * Test that attempting to close a valid session twice 503 * is prohibited with the documented error code. 504 */ 505 TEST_P(DrmHalVendorPluginTest, CloseClosedSession) { 506 RETURN_IF_SKIPPED; 507 auto sessionId = openSession(); 508 closeSession(sessionId); 509 Status status = drmPlugin->closeSession(sessionId); 510 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 511 } 512 513 /** 514 * A get key request should fail if no sessionId is provided 515 */ 516 TEST_P(DrmHalVendorPluginTest, GetKeyRequestNoSession) { 517 RETURN_IF_SKIPPED; 518 SessionId invalidSessionId; 519 hidl_vec<uint8_t> initData; 520 hidl_string mimeType = "video/mp4"; 521 KeyedVector optionalParameters; 522 auto res = drmPlugin->getKeyRequest( 523 invalidSessionId, initData, mimeType, KeyType::STREAMING, 524 optionalParameters, 525 [&](Status status, const hidl_vec<uint8_t>&, KeyRequestType, 526 const hidl_string&) { EXPECT_EQ(Status::BAD_VALUE, status); }); 527 EXPECT_OK(res); 528 } 529 530 /** 531 * Test that an empty sessionID returns BAD_VALUE 532 */ 533 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptySessionId) { 534 RETURN_IF_SKIPPED; 535 SessionId session; 536 537 hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65, 538 0x79, 0x73, 0x22, 0x3a}; 539 auto res = drmPlugin->provideKeyResponse( 540 session, keyResponse, 541 [&](Status status, const hidl_vec<uint8_t>& keySetId) { 542 EXPECT_EQ(Status::BAD_VALUE, status); 543 EXPECT_EQ(keySetId.size(), 0u); 544 }); 545 EXPECT_OK(res); 546 } 547 548 /** 549 * Test that an empty key response returns BAD_VALUE 550 */ 551 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptyResponse) { 552 RETURN_IF_SKIPPED; 553 SessionId session = openSession(); 554 hidl_vec<uint8_t> emptyResponse; 555 auto res = drmPlugin->provideKeyResponse( 556 session, emptyResponse, 557 [&](Status status, const hidl_vec<uint8_t>& keySetId) { 558 EXPECT_EQ(Status::BAD_VALUE, status); 559 EXPECT_EQ(keySetId.size(), 0u); 560 }); 561 EXPECT_OK(res); 562 closeSession(session); 563 } 564 565 /** 566 * Test that a removeKeys on an empty sessionID returns BAD_VALUE 567 */ 568 TEST_P(DrmHalVendorPluginTest, RemoveKeysEmptySessionId) { 569 RETURN_IF_SKIPPED; 570 SessionId sessionId; 571 Status status = drmPlugin->removeKeys(sessionId); 572 EXPECT_TRUE(status == Status::BAD_VALUE); 573 } 574 575 /** 576 * Test that remove keys returns okay on an initialized session 577 * that has no keys. 578 */ 579 TEST_P(DrmHalVendorPluginTest, RemoveKeysNewSession) { 580 RETURN_IF_SKIPPED; 581 SessionId sessionId = openSession(); 582 Status status = drmPlugin->removeKeys(sessionId); 583 EXPECT_TRUE(status == Status::OK); 584 closeSession(sessionId); 585 } 586 587 /** 588 * Test that keys are successfully restored to a new session 589 * for all content having a policy that allows offline use. 590 */ 591 TEST_P(DrmHalVendorPluginTest, RestoreKeys) { 592 RETURN_IF_SKIPPED; 593 for (auto config : contentConfigurations) { 594 if (config.policy.allowOffline) { 595 auto sessionId = openSession(); 596 hidl_vec<uint8_t> keySetId = 597 loadKeys(sessionId, config, KeyType::OFFLINE); 598 closeSession(sessionId); 599 sessionId = openSession(); 600 EXPECT_NE(0u, keySetId.size()); 601 Status status = drmPlugin->restoreKeys(sessionId, keySetId); 602 EXPECT_EQ(Status::OK, status); 603 closeSession(sessionId); 604 } 605 } 606 } 607 608 /** 609 * Test that restoreKeys fails with a null key set ID. 610 * Error message is expected to be Status::BAD_VALUE. 611 */ 612 TEST_P(DrmHalVendorPluginTest, RestoreKeysNull) { 613 RETURN_IF_SKIPPED; 614 SessionId sessionId = openSession(); 615 hidl_vec<uint8_t> nullKeySetId; 616 Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId); 617 EXPECT_EQ(Status::BAD_VALUE, status); 618 closeSession(sessionId); 619 } 620 621 /** 622 * Test that restoreKeys fails to restore keys to a closed 623 * session. Error message is expected to be 624 * Status::ERROR_DRM_SESSION_NOT_OPENED. 625 */ 626 TEST_P(DrmHalVendorPluginTest, RestoreKeysClosedSession) { 627 RETURN_IF_SKIPPED; 628 for (auto config : contentConfigurations) { 629 if (config.policy.allowOffline) { 630 auto sessionId = openSession(); 631 hidl_vec<uint8_t> keySetId = 632 loadKeys(sessionId, config, KeyType::OFFLINE); 633 EXPECT_NE(0u, keySetId.size()); 634 closeSession(sessionId); 635 sessionId = openSession(); 636 closeSession(sessionId); 637 Status status = drmPlugin->restoreKeys(sessionId, keySetId); 638 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 639 } 640 } 641 } 642 643 /** 644 * Test that the plugin either doesn't support getting 645 * secure stops, or has no secure stops available after 646 * clearing them. 647 */ 648 TEST_P(DrmHalVendorPluginTest, GetSecureStops) { 649 RETURN_IF_SKIPPED; 650 // There may be secure stops, depending on if there were keys 651 // loaded and unloaded previously. Clear them to get to a known 652 // state, then make sure there are none. 653 auto res = drmPlugin->getSecureStops( 654 [&](Status status, const hidl_vec<SecureStop>&) { 655 if (status != Status::OK) { 656 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 657 } 658 }); 659 EXPECT_OK(res); 660 661 res = drmPlugin->getSecureStops( 662 [&](Status status, const hidl_vec<SecureStop>& secureStops) { 663 if (status == Status::OK) { 664 EXPECT_EQ(secureStops.size(), 0u); 665 } else { 666 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 667 } 668 }); 669 EXPECT_OK(res); 670 } 671 672 /** 673 * Test that the clearkey plugin returns BAD_VALUE if 674 * an empty ssid is provided. 675 */ 676 TEST_P(DrmHalVendorPluginTest, GetSecureStopEmptySSID) { 677 RETURN_IF_SKIPPED; 678 SecureStopId ssid; 679 auto res = drmPlugin->getSecureStop( 680 ssid, [&](Status status, const SecureStop&) { 681 EXPECT_EQ(Status::BAD_VALUE, status); 682 }); 683 EXPECT_OK(res); 684 } 685 686 /** 687 * Test that releasing all secure stops either isn't supported 688 * or is completed successfully 689 */ 690 TEST_P(DrmHalVendorPluginTest, ReleaseAllSecureStops) { 691 RETURN_IF_SKIPPED; 692 Status status = drmPlugin->releaseAllSecureStops(); 693 EXPECT_TRUE(status == Status::OK || 694 status == Status::ERROR_DRM_CANNOT_HANDLE); 695 } 696 697 /** 698 * Releasing a secure stop without first getting one and sending it to the 699 * server to get a valid SSID should return ERROR_DRM_INVALID_STATE. 700 * This is an optional API so it can also return CANNOT_HANDLE. 701 */ 702 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopSequenceError) { 703 RETURN_IF_SKIPPED; 704 SecureStopId ssid = {1, 2, 3, 4}; 705 Status status = drmPlugin->releaseSecureStop(ssid); 706 EXPECT_TRUE(status == Status::ERROR_DRM_INVALID_STATE || 707 status == Status::ERROR_DRM_CANNOT_HANDLE); 708 } 709 710 /** 711 * Test that releasing a specific secure stop with an empty ssid 712 * return BAD_VALUE. This is an optional API so it can also return 713 * CANNOT_HANDLE. 714 */ 715 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopEmptySSID) { 716 RETURN_IF_SKIPPED; 717 SecureStopId ssid; 718 Status status = drmPlugin->releaseSecureStop(ssid); 719 EXPECT_TRUE(status == Status::BAD_VALUE || 720 status == Status::ERROR_DRM_CANNOT_HANDLE); 721 } 722 723 /** 724 * The following five tests verify that the properties 725 * defined in the MediaDrm API are supported by 726 * the plugin. 727 */ 728 TEST_P(DrmHalVendorPluginTest, GetVendorProperty) { 729 RETURN_IF_SKIPPED; 730 auto res = drmPlugin->getPropertyString( 731 "vendor", [&](Status status, const hidl_string& value) { 732 EXPECT_EQ(Status::OK, status); 733 EXPECT_NE(value.size(), 0u); 734 }); 735 EXPECT_OK(res); 736 } 737 738 TEST_P(DrmHalVendorPluginTest, GetVersionProperty) { 739 RETURN_IF_SKIPPED; 740 auto res = drmPlugin->getPropertyString( 741 "version", [&](Status status, const hidl_string& value) { 742 EXPECT_EQ(Status::OK, status); 743 EXPECT_NE(value.size(), 0u); 744 }); 745 EXPECT_OK(res); 746 } 747 748 TEST_P(DrmHalVendorPluginTest, GetDescriptionProperty) { 749 RETURN_IF_SKIPPED; 750 auto res = drmPlugin->getPropertyString( 751 "description", [&](Status status, const hidl_string& value) { 752 EXPECT_EQ(Status::OK, status); 753 EXPECT_NE(value.size(), 0u); 754 }); 755 EXPECT_OK(res); 756 } 757 758 TEST_P(DrmHalVendorPluginTest, GetAlgorithmsProperty) { 759 RETURN_IF_SKIPPED; 760 auto res = drmPlugin->getPropertyString( 761 "algorithms", [&](Status status, const hidl_string& value) { 762 if (status == Status::OK) { 763 EXPECT_NE(value.size(), 0u); 764 } else { 765 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 766 } 767 }); 768 EXPECT_OK(res); 769 } 770 771 TEST_P(DrmHalVendorPluginTest, GetPropertyUniqueDeviceID) { 772 RETURN_IF_SKIPPED; 773 auto res = drmPlugin->getPropertyByteArray( 774 "deviceUniqueId", 775 [&](Status status, const hidl_vec<uint8_t>& value) { 776 if (status == Status::OK) { 777 EXPECT_NE(value.size(), 0u); 778 } else { 779 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 780 } 781 }); 782 EXPECT_OK(res); 783 } 784 785 /** 786 * Test that attempting to read invalid string and byte array 787 * properties returns the documented error code. 788 */ 789 TEST_P(DrmHalVendorPluginTest, GetInvalidStringProperty) { 790 RETURN_IF_SKIPPED; 791 auto res = drmPlugin->getPropertyString( 792 "invalid", [&](Status status, const hidl_string&) { 793 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 794 }); 795 EXPECT_OK(res); 796 } 797 798 TEST_P(DrmHalVendorPluginTest, GetInvalidByteArrayProperty) { 799 RETURN_IF_SKIPPED; 800 auto res = drmPlugin->getPropertyByteArray( 801 "invalid", [&](Status status, const hidl_vec<uint8_t>&) { 802 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status); 803 }); 804 EXPECT_OK(res); 805 } 806 807 /** 808 * Test that setting invalid string and byte array properties returns 809 * the expected status value. 810 */ 811 TEST_P(DrmHalVendorPluginTest, SetStringPropertyNotSupported) { 812 RETURN_IF_SKIPPED; 813 EXPECT_EQ(drmPlugin->setPropertyString("awefijaeflijwef", "value"), 814 Status::ERROR_DRM_CANNOT_HANDLE); 815 } 816 817 TEST_P(DrmHalVendorPluginTest, SetByteArrayPropertyNotSupported) { 818 RETURN_IF_SKIPPED; 819 hidl_vec<uint8_t> value; 820 EXPECT_EQ(drmPlugin->setPropertyByteArray("awefijaeflijwef", value), 821 Status::ERROR_DRM_CANNOT_HANDLE); 822 } 823 824 /** 825 * Test that setting an invalid cipher algorithm returns 826 * the expected status value. 827 */ 828 TEST_P(DrmHalVendorPluginTest, SetCipherInvalidAlgorithm) { 829 RETURN_IF_SKIPPED; 830 SessionId session = openSession(); 831 hidl_string algorithm; 832 Status status = drmPlugin->setCipherAlgorithm(session, algorithm); 833 EXPECT_EQ(Status::BAD_VALUE, status); 834 closeSession(session); 835 } 836 837 /** 838 * Test that setting a cipher algorithm with no session returns 839 * the expected status value. 840 */ 841 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithmNoSession) { 842 RETURN_IF_SKIPPED; 843 SessionId session; 844 hidl_string algorithm = "AES/CBC/NoPadding"; 845 Status status = drmPlugin->setCipherAlgorithm(session, algorithm); 846 EXPECT_EQ(Status::BAD_VALUE, status); 847 } 848 849 /** 850 * Test that setting a valid cipher algorithm returns 851 * the expected status value. It is not required that all 852 * vendor modules support this algorithm, but they must 853 * either accept it or return ERROR_DRM_CANNOT_HANDLE 854 */ 855 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithm) { 856 RETURN_IF_SKIPPED; 857 SessionId session = openSession(); 858 ; 859 hidl_string algorithm = "AES/CBC/NoPadding"; 860 Status status = drmPlugin->setCipherAlgorithm(session, algorithm); 861 EXPECT_TRUE(status == Status::OK || 862 status == Status::ERROR_DRM_CANNOT_HANDLE); 863 closeSession(session); 864 } 865 866 /** 867 * Test that setting an invalid mac algorithm returns 868 * the expected status value. 869 */ 870 TEST_P(DrmHalVendorPluginTest, SetMacInvalidAlgorithm) { 871 RETURN_IF_SKIPPED; 872 SessionId session = openSession(); 873 hidl_string algorithm; 874 Status status = drmPlugin->setMacAlgorithm(session, algorithm); 875 EXPECT_EQ(Status::BAD_VALUE, status); 876 closeSession(session); 877 } 878 879 /** 880 * Test that setting a mac algorithm with no session returns 881 * the expected status value. 882 */ 883 TEST_P(DrmHalVendorPluginTest, SetMacNullAlgorithmNoSession) { 884 RETURN_IF_SKIPPED; 885 SessionId session; 886 hidl_string algorithm = "HmacSHA256"; 887 Status status = drmPlugin->setMacAlgorithm(session, algorithm); 888 EXPECT_EQ(Status::BAD_VALUE, status); 889 } 890 891 /** 892 * Test that setting a valid mac algorithm returns 893 * the expected status value. It is not required that all 894 * vendor modules support this algorithm, but they must 895 * either accept it or return ERROR_DRM_CANNOT_HANDLE 896 */ 897 TEST_P(DrmHalVendorPluginTest, SetMacAlgorithm) { 898 RETURN_IF_SKIPPED; 899 SessionId session = openSession(); 900 hidl_string algorithm = "HmacSHA256"; 901 Status status = drmPlugin->setMacAlgorithm(session, algorithm); 902 EXPECT_TRUE(status == Status::OK || 903 status == Status::ERROR_DRM_CANNOT_HANDLE); 904 closeSession(session); 905 } 906 907 /** 908 * The Generic* methods provide general purpose crypto operations 909 * that may be used for applications other than DRM. They leverage 910 * the hardware root of trust and secure key distribution mechanisms 911 * of a DRM system to enable app-specific crypto functionality where 912 * the crypto keys are not exposed outside of the trusted execution 913 * environment. 914 * 915 * Generic encrypt/decrypt/sign/verify should fail on invalid 916 * inputs, e.g. empty sessionId 917 */ 918 TEST_P(DrmHalVendorPluginTest, GenericEncryptNoSession) { 919 RETURN_IF_SKIPPED; 920 SessionId session; 921 hidl_vec<uint8_t> keyId, input, iv; 922 auto res = drmPlugin->encrypt( 923 session, keyId, input, iv, 924 [&](Status status, const hidl_vec<uint8_t>&) { 925 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 926 }); 927 EXPECT_OK(res); 928 } 929 930 TEST_P(DrmHalVendorPluginTest, GenericDecryptNoSession) { 931 RETURN_IF_SKIPPED; 932 SessionId session; 933 hidl_vec<uint8_t> keyId, input, iv; 934 auto res = drmPlugin->decrypt( 935 session, keyId, input, iv, 936 [&](Status status, const hidl_vec<uint8_t>&) { 937 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 938 }); 939 EXPECT_OK(res); 940 } 941 942 TEST_P(DrmHalVendorPluginTest, GenericSignNoSession) { 943 RETURN_IF_SKIPPED; 944 SessionId session; 945 hidl_vec<uint8_t> keyId, message; 946 auto res = drmPlugin->sign( 947 session, keyId, message, 948 [&](Status status, const hidl_vec<uint8_t>&) { 949 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 950 }); 951 EXPECT_OK(res); 952 } 953 954 TEST_P(DrmHalVendorPluginTest, GenericVerifyNoSession) { 955 RETURN_IF_SKIPPED; 956 SessionId session; 957 hidl_vec<uint8_t> keyId, message, signature; 958 auto res = drmPlugin->verify( 959 session, keyId, message, signature, [&](Status status, bool) { 960 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 961 }); 962 EXPECT_OK(res); 963 } 964 965 TEST_P(DrmHalVendorPluginTest, GenericSignRSANoSession) { 966 RETURN_IF_SKIPPED; 967 SessionId session; 968 hidl_string algorithm; 969 hidl_vec<uint8_t> message, wrappedKey; 970 auto res = drmPlugin->signRSA(session, algorithm, message, wrappedKey, 971 [&](Status status, const hidl_vec<uint8_t>&) { 972 EXPECT_EQ(Status::BAD_VALUE, status); 973 }); 974 EXPECT_OK(res); 975 } 976 977 /** 978 * Exercise the requiresSecureDecoderComponent method. Additional tests 979 * will verify positive cases with specific vendor content configurations. 980 * Below we just test the negative cases. 981 */ 982 983 /** 984 * Verify that requiresSecureDecoderComponent handles empty mimetype. 985 */ 986 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderEmptyMimeType) { 987 RETURN_IF_SKIPPED; 988 EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("")); 989 } 990 991 /** 992 * Verify that requiresSecureDecoderComponent handles invalid mimetype. 993 */ 994 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderInvalidMimeType) { 995 RETURN_IF_SKIPPED; 996 EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("bad")); 997 } 998 999 /** 1000 * Verify that requiresSecureDecoderComponent returns true for secure 1001 * configurations 1002 */ 1003 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderConfig) { 1004 RETURN_IF_SKIPPED; 1005 for (auto config : contentConfigurations) { 1006 for (auto key : config.keys) { 1007 if (key.isSecure) { 1008 EXPECT_TRUE(cryptoPlugin->requiresSecureDecoderComponent(config.mimeType)); 1009 break; 1010 } 1011 } 1012 } 1013 } 1014 1015 /** 1016 * Event Handling tests 1017 */ 1018 struct ListenerEventArgs { 1019 EventType eventType; 1020 SessionId sessionId; 1021 hidl_vec<uint8_t> data; 1022 int64_t expiryTimeInMS; 1023 hidl_vec<KeyStatus> keyStatusList; 1024 bool hasNewUsableKey; 1025 }; 1026 1027 const char *kCallbackEvent = "SendEvent"; 1028 const char *kCallbackExpirationUpdate = "SendExpirationUpdate"; 1029 const char *kCallbackKeysChange = "SendKeysChange"; 1030 1031 class TestDrmPluginListener 1032 : public ::testing::VtsHalHidlTargetCallbackBase<ListenerEventArgs>, 1033 public IDrmPluginListener { 1034 public: 1035 TestDrmPluginListener() { 1036 SetWaitTimeoutDefault(std::chrono::milliseconds(500)); 1037 } 1038 virtual ~TestDrmPluginListener() {} 1039 1040 virtual Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId, 1041 const hidl_vec<uint8_t>& data) override { 1042 ListenerEventArgs args; 1043 args.eventType = eventType; 1044 args.sessionId = sessionId; 1045 args.data = data; 1046 NotifyFromCallback(kCallbackEvent, args); 1047 return Void(); 1048 } 1049 1050 virtual Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, 1051 int64_t expiryTimeInMS) override { 1052 ListenerEventArgs args; 1053 args.sessionId = sessionId; 1054 args.expiryTimeInMS = expiryTimeInMS; 1055 NotifyFromCallback(kCallbackExpirationUpdate, args); 1056 return Void(); 1057 } 1058 1059 virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId, 1060 const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) override { 1061 ListenerEventArgs args; 1062 args.sessionId = sessionId; 1063 args.keyStatusList = keyStatusList; 1064 args.hasNewUsableKey = hasNewUsableKey; 1065 NotifyFromCallback(kCallbackKeysChange, args); 1066 return Void(); 1067 } 1068 }; 1069 1070 1071 /** 1072 * Simulate the plugin sending events. Make sure the listener 1073 * gets them. 1074 */ 1075 TEST_P(DrmHalVendorPluginTest, ListenerEvents) { 1076 RETURN_IF_SKIPPED; 1077 sp<TestDrmPluginListener> listener = new TestDrmPluginListener(); 1078 drmPlugin->setListener(listener); 1079 auto sessionId = openSession(); 1080 hidl_vec<uint8_t> data = {0, 1, 2}; 1081 EventType eventTypes[] = {EventType::PROVISION_REQUIRED, 1082 EventType::KEY_NEEDED, 1083 EventType::KEY_EXPIRED, 1084 EventType::VENDOR_DEFINED, 1085 EventType::SESSION_RECLAIMED}; 1086 for (auto eventType : eventTypes) { 1087 drmPlugin->sendEvent(eventType, sessionId, data); 1088 auto result = listener->WaitForCallback(kCallbackEvent); 1089 EXPECT_TRUE(result.no_timeout); 1090 EXPECT_TRUE(result.args); 1091 EXPECT_EQ(eventType, result.args->eventType); 1092 EXPECT_EQ(sessionId, result.args->sessionId); 1093 EXPECT_EQ(data, result.args->data); 1094 } 1095 closeSession(sessionId); 1096 } 1097 1098 /** 1099 * Simulate the plugin sending expiration updates and make sure 1100 * the listener gets them. 1101 */ 1102 TEST_P(DrmHalVendorPluginTest, ListenerExpirationUpdate) { 1103 RETURN_IF_SKIPPED; 1104 sp<TestDrmPluginListener> listener = new TestDrmPluginListener(); 1105 drmPlugin->setListener(listener); 1106 auto sessionId = openSession(); 1107 drmPlugin->sendExpirationUpdate(sessionId, 100); 1108 auto result = listener->WaitForCallback(kCallbackExpirationUpdate); 1109 EXPECT_TRUE(result.no_timeout); 1110 EXPECT_TRUE(result.args); 1111 EXPECT_EQ(sessionId, result.args->sessionId); 1112 EXPECT_EQ(100, result.args->expiryTimeInMS); 1113 closeSession(sessionId); 1114 } 1115 1116 /** 1117 * Simulate the plugin sending keys change and make sure 1118 * the listener gets them. 1119 */ 1120 TEST_P(DrmHalVendorPluginTest, ListenerKeysChange) { 1121 RETURN_IF_SKIPPED; 1122 sp<TestDrmPluginListener> listener = new TestDrmPluginListener(); 1123 drmPlugin->setListener(listener); 1124 auto sessionId = openSession(); 1125 const hidl_vec<KeyStatus> keyStatusList = { 1126 {{1}, KeyStatusType::USABLE}, 1127 {{2}, KeyStatusType::EXPIRED}, 1128 {{3}, KeyStatusType::OUTPUTNOTALLOWED}, 1129 {{4}, KeyStatusType::STATUSPENDING}, 1130 {{5}, KeyStatusType::INTERNALERROR}, 1131 }; 1132 1133 drmPlugin->sendKeysChange(sessionId, keyStatusList, true); 1134 auto result = listener->WaitForCallback(kCallbackKeysChange); 1135 EXPECT_TRUE(result.no_timeout); 1136 EXPECT_TRUE(result.args); 1137 EXPECT_EQ(sessionId, result.args->sessionId); 1138 EXPECT_EQ(keyStatusList, result.args->keyStatusList); 1139 closeSession(sessionId); 1140 } 1141 1142 /** 1143 * Negative listener tests. Call send methods with no 1144 * listener set. 1145 */ 1146 TEST_P(DrmHalVendorPluginTest, NotListening) { 1147 RETURN_IF_SKIPPED; 1148 sp<TestDrmPluginListener> listener = new TestDrmPluginListener(); 1149 drmPlugin->setListener(listener); 1150 drmPlugin->setListener(nullptr); 1151 1152 SessionId sessionId; 1153 hidl_vec<uint8_t> data; 1154 hidl_vec<KeyStatus> keyStatusList; 1155 drmPlugin->sendEvent(EventType::PROVISION_REQUIRED, sessionId, data); 1156 drmPlugin->sendExpirationUpdate(sessionId, 100); 1157 drmPlugin->sendKeysChange(sessionId, keyStatusList, true); 1158 auto result = listener->WaitForCallbackAny( 1159 {kCallbackEvent, kCallbackExpirationUpdate, kCallbackKeysChange}); 1160 EXPECT_FALSE(result.no_timeout); 1161 } 1162 1163 1164 /** 1165 * CryptoPlugin tests 1166 */ 1167 1168 /** 1169 * Exercise the NotifyResolution API. There is no observable result, 1170 * just call the method for coverage. 1171 */ 1172 TEST_P(DrmHalVendorPluginTest, NotifyResolution) { 1173 RETURN_IF_SKIPPED; 1174 cryptoPlugin->notifyResolution(1920, 1080); 1175 } 1176 1177 /** 1178 * getDecryptMemory allocates memory for decryption, then sets it 1179 * as a shared buffer base in the crypto hal. The allocated and 1180 * mapped IMemory is returned. 1181 * 1182 * @param size the size of the memory segment to allocate 1183 * @param the index of the memory segment which will be used 1184 * to refer to it for decryption. 1185 */ 1186 sp<IMemory> DrmHalVendorPluginTest::getDecryptMemory(size_t size, 1187 size_t index) { 1188 sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem"); 1189 EXPECT_NE(ashmemAllocator, nullptr); 1190 1191 hidl_memory hidlMemory; 1192 auto res = ashmemAllocator->allocate( 1193 size, [&](bool success, const hidl_memory& memory) { 1194 EXPECT_EQ(success, true); 1195 EXPECT_EQ(memory.size(), size); 1196 hidlMemory = memory; 1197 }); 1198 1199 EXPECT_OK(res); 1200 1201 sp<IMemory> mappedMemory = mapMemory(hidlMemory); 1202 EXPECT_NE(mappedMemory, nullptr); 1203 res = cryptoPlugin->setSharedBufferBase(hidlMemory, index); 1204 EXPECT_OK(res); 1205 return mappedMemory; 1206 } 1207 1208 /** 1209 * Exercise the setMediaDrmSession method. setMediaDrmSession 1210 * is used to associate a drm session with a crypto session. 1211 */ 1212 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSession) { 1213 RETURN_IF_SKIPPED; 1214 auto sessionId = openSession(); 1215 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1216 EXPECT_EQ(Status::OK, status); 1217 closeSession(sessionId); 1218 } 1219 1220 /** 1221 * setMediaDrmSession with a closed session id 1222 */ 1223 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionClosedSession) { 1224 RETURN_IF_SKIPPED; 1225 auto sessionId = openSession(); 1226 closeSession(sessionId); 1227 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1228 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status); 1229 } 1230 1231 /** 1232 * setMediaDrmSession with a empty session id: BAD_VALUE 1233 */ 1234 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionEmptySession) { 1235 RETURN_IF_SKIPPED; 1236 SessionId sessionId; 1237 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1238 EXPECT_EQ(Status::BAD_VALUE, status); 1239 } 1240 1241 /** 1242 * Decrypt tests 1243 */ 1244 1245 class DrmHalVendorDecryptTest : public DrmHalVendorPluginTest { 1246 public: 1247 DrmHalVendorDecryptTest() = default; 1248 virtual ~DrmHalVendorDecryptTest() {} 1249 1250 protected: 1251 void fillRandom(const sp<IMemory>& memory); 1252 hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) { 1253 EXPECT_EQ(vec.size(), 16u); 1254 return hidl_array<uint8_t, 16>(&vec[0]); 1255 } 1256 hidl_vec<KeyValue> queryKeyStatus(SessionId sessionId); 1257 void removeKeys(SessionId sessionId); 1258 uint32_t decrypt(Mode mode, bool isSecure, 1259 const hidl_array<uint8_t, 16>& keyId, uint8_t* iv, 1260 const hidl_vec<SubSample>& subSamples, const Pattern& pattern, 1261 const vector<uint8_t>& key, Status expectedStatus); 1262 void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, 1263 const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key); 1264 void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, 1265 const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key); 1266 }; 1267 1268 void DrmHalVendorDecryptTest::fillRandom(const sp<IMemory>& memory) { 1269 random_device rd; 1270 mt19937 rand(rd()); 1271 for (size_t i = 0; i < memory->getSize() / sizeof(uint32_t); i++) { 1272 auto p = static_cast<uint32_t*>( 1273 static_cast<void*>(memory->getPointer())); 1274 p[i] = rand(); 1275 } 1276 } 1277 1278 hidl_vec<KeyValue> DrmHalVendorDecryptTest::queryKeyStatus(SessionId sessionId) { 1279 hidl_vec<KeyValue> keyStatus; 1280 auto res = drmPlugin->queryKeyStatus(sessionId, 1281 [&](Status status, KeyedVector info) { 1282 EXPECT_EQ(Status::OK, status); 1283 keyStatus = info; 1284 }); 1285 EXPECT_OK(res); 1286 return keyStatus; 1287 } 1288 1289 void DrmHalVendorDecryptTest::removeKeys(SessionId sessionId) { 1290 auto res = drmPlugin->removeKeys(sessionId); 1291 EXPECT_OK(res); 1292 } 1293 1294 uint32_t DrmHalVendorDecryptTest::decrypt(Mode mode, bool isSecure, 1295 const hidl_array<uint8_t, 16>& keyId, uint8_t* iv, 1296 const hidl_vec<SubSample>& subSamples, const Pattern& pattern, 1297 const vector<uint8_t>& key, Status expectedStatus) { 1298 const size_t kSegmentIndex = 0; 1299 1300 uint8_t localIv[AES_BLOCK_SIZE]; 1301 memcpy(localIv, iv, AES_BLOCK_SIZE); 1302 1303 size_t totalSize = 0; 1304 for (size_t i = 0; i < subSamples.size(); i++) { 1305 totalSize += subSamples[i].numBytesOfClearData; 1306 totalSize += subSamples[i].numBytesOfEncryptedData; 1307 } 1308 1309 // The first totalSize bytes of shared memory is the encrypted 1310 // input, the second totalSize bytes is the decrypted output. 1311 sp<IMemory> sharedMemory = 1312 getDecryptMemory(totalSize * 2, kSegmentIndex); 1313 1314 SharedBuffer sourceBuffer = { 1315 .bufferId = kSegmentIndex, .offset = 0, .size = totalSize}; 1316 fillRandom(sharedMemory); 1317 1318 DestinationBuffer destBuffer = {.type = BufferType::SHARED_MEMORY, 1319 {.bufferId = kSegmentIndex, 1320 .offset = totalSize, 1321 .size = totalSize}, 1322 .secureMemory = nullptr}; 1323 uint64_t offset = 0; 1324 uint32_t bytesWritten = 0; 1325 auto res = cryptoPlugin->decrypt(isSecure, keyId, localIv, mode, pattern, 1326 subSamples, sourceBuffer, offset, destBuffer, 1327 [&](Status status, uint32_t count, string detailedError) { 1328 EXPECT_EQ(expectedStatus, status) << "Unexpected decrypt status " << 1329 detailedError; 1330 bytesWritten = count; 1331 }); 1332 EXPECT_OK(res); 1333 1334 if (bytesWritten != totalSize) { 1335 return bytesWritten; 1336 } 1337 uint8_t* base = static_cast<uint8_t*>( 1338 static_cast<void*>(sharedMemory->getPointer())); 1339 1340 // generate reference vector 1341 vector<uint8_t> reference(totalSize); 1342 1343 memcpy(localIv, iv, AES_BLOCK_SIZE); 1344 switch (mode) { 1345 case Mode::UNENCRYPTED: 1346 memcpy(&reference[0], base, totalSize); 1347 break; 1348 case Mode::AES_CTR: 1349 aes_ctr_decrypt(&reference[0], base, localIv, subSamples, key); 1350 break; 1351 case Mode::AES_CBC: 1352 aes_cbc_decrypt(&reference[0], base, localIv, subSamples, key); 1353 break; 1354 case Mode::AES_CBC_CTS: 1355 EXPECT_TRUE(false) << "AES_CBC_CTS mode not supported"; 1356 break; 1357 } 1358 1359 // compare reference to decrypted data which is at base + total size 1360 EXPECT_EQ(0, memcmp(static_cast<void*>(&reference[0]), 1361 static_cast<void*>(base + totalSize), totalSize)) 1362 << "decrypt data mismatch"; 1363 return totalSize; 1364 } 1365 1366 /** 1367 * Decrypt a list of clear+encrypted subsamples using the specified key 1368 * in AES-CTR mode 1369 */ 1370 void DrmHalVendorDecryptTest::aes_ctr_decrypt(uint8_t* dest, uint8_t* src, 1371 uint8_t* iv, const hidl_vec<SubSample>& subSamples, 1372 const vector<uint8_t>& key) { 1373 1374 AES_KEY decryptionKey; 1375 AES_set_encrypt_key(&key[0], 128, &decryptionKey); 1376 1377 size_t offset = 0; 1378 unsigned blockOffset = 0; 1379 uint8_t previousEncryptedCounter[AES_BLOCK_SIZE]; 1380 memset(previousEncryptedCounter, 0, AES_BLOCK_SIZE); 1381 1382 for (size_t i = 0; i < subSamples.size(); i++) { 1383 const SubSample& subSample = subSamples[i]; 1384 1385 if (subSample.numBytesOfClearData > 0) { 1386 memcpy(dest + offset, src + offset, subSample.numBytesOfClearData); 1387 offset += subSample.numBytesOfClearData; 1388 } 1389 1390 if (subSample.numBytesOfEncryptedData > 0) { 1391 AES_ctr128_encrypt(src + offset, dest + offset, 1392 subSample.numBytesOfEncryptedData, &decryptionKey, 1393 iv, previousEncryptedCounter, &blockOffset); 1394 offset += subSample.numBytesOfEncryptedData; 1395 } 1396 } 1397 } 1398 1399 /** 1400 * Decrypt a list of clear+encrypted subsamples using the specified key 1401 * in AES-CBC mode 1402 */ 1403 void DrmHalVendorDecryptTest::aes_cbc_decrypt(uint8_t* dest, uint8_t* src, 1404 uint8_t* iv, const hidl_vec<SubSample>& subSamples, 1405 const vector<uint8_t>& key) { 1406 AES_KEY decryptionKey; 1407 AES_set_encrypt_key(&key[0], 128, &decryptionKey); 1408 1409 size_t offset = 0; 1410 size_t num = 0; 1411 size_t ecount_buf = 0; 1412 for (size_t i = 0; i < subSamples.size(); i++) { 1413 const SubSample& subSample = subSamples[i]; 1414 1415 memcpy(dest + offset, src + offset, subSample.numBytesOfClearData); 1416 offset += subSample.numBytesOfClearData; 1417 1418 AES_cbc_encrypt(src + offset, dest + offset, subSample.numBytesOfEncryptedData, 1419 &decryptionKey, iv, 0 /* decrypt */); 1420 offset += subSample.numBytesOfEncryptedData; 1421 } 1422 } 1423 1424 1425 /** 1426 * Test key status with empty session id, should return BAD_VALUE 1427 */ 1428 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusInvalidSession) { 1429 RETURN_IF_SKIPPED; 1430 SessionId sessionId; 1431 auto res = drmPlugin->queryKeyStatus(sessionId, 1432 [&](Status status, KeyedVector /* info */) { 1433 EXPECT_EQ(Status::BAD_VALUE, status); 1434 }); 1435 EXPECT_OK(res); 1436 } 1437 1438 1439 /** 1440 * Test key status. There should be no key status prior to loading keys 1441 */ 1442 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusWithNoKeys) { 1443 RETURN_IF_SKIPPED; 1444 auto sessionId = openSession(); 1445 auto keyStatus = queryKeyStatus(sessionId); 1446 EXPECT_EQ(0u, keyStatus.size()); 1447 closeSession(sessionId); 1448 } 1449 1450 1451 /** 1452 * Test key status. There should be key status after loading keys. 1453 */ 1454 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatus) { 1455 RETURN_IF_SKIPPED; 1456 for (auto config : contentConfigurations) { 1457 auto sessionId = openSession(); 1458 loadKeys(sessionId, config); 1459 auto keyStatus = queryKeyStatus(sessionId); 1460 EXPECT_NE(0u, keyStatus.size()); 1461 closeSession(sessionId); 1462 } 1463 } 1464 1465 /** 1466 * Positive decrypt test. "Decrypt" a single clear segment and verify. 1467 */ 1468 TEST_P(DrmHalVendorDecryptTest, ClearSegmentTest) { 1469 RETURN_IF_SKIPPED; 1470 for (auto config : contentConfigurations) { 1471 for (auto key : config.keys) { 1472 const size_t kSegmentSize = 1024; 1473 vector<uint8_t> iv(AES_BLOCK_SIZE, 0); 1474 const Pattern noPattern = {0, 0}; 1475 const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize, 1476 .numBytesOfEncryptedData = 0}}; 1477 auto sessionId = openSession(); 1478 loadKeys(sessionId, config); 1479 1480 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1481 EXPECT_EQ(Status::OK, status); 1482 1483 uint32_t byteCount = decrypt(Mode::UNENCRYPTED, key.isSecure, toHidlArray(key.keyId), 1484 &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK); 1485 EXPECT_EQ(kSegmentSize, byteCount); 1486 1487 closeSession(sessionId); 1488 } 1489 } 1490 } 1491 1492 /** 1493 * Positive decrypt test. Decrypt a single segment using aes_ctr. 1494 * Verify data matches. 1495 */ 1496 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTest) { 1497 RETURN_IF_SKIPPED; 1498 for (auto config : contentConfigurations) { 1499 for (auto key : config.keys) { 1500 const size_t kSegmentSize = 1024; 1501 vector<uint8_t> iv(AES_BLOCK_SIZE, 0); 1502 const Pattern noPattern = {0, 0}; 1503 const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize, 1504 .numBytesOfEncryptedData = 0}}; 1505 auto sessionId = openSession(); 1506 loadKeys(sessionId, config); 1507 1508 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1509 EXPECT_EQ(Status::OK, status); 1510 1511 uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, toHidlArray(key.keyId), 1512 &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK); 1513 EXPECT_EQ(kSegmentSize, byteCount); 1514 1515 closeSession(sessionId); 1516 } 1517 } 1518 } 1519 1520 /** 1521 * Negative decrypt test. Decrypt without loading keys. 1522 */ 1523 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTestNoKeys) { 1524 RETURN_IF_SKIPPED; 1525 for (auto config : contentConfigurations) { 1526 for (auto key : config.keys) { 1527 vector<uint8_t> iv(AES_BLOCK_SIZE, 0); 1528 const Pattern noPattern = {0, 0}; 1529 const vector<SubSample> subSamples = {{.numBytesOfClearData = 256, 1530 .numBytesOfEncryptedData = 256}}; 1531 auto sessionId = openSession(); 1532 1533 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1534 EXPECT_EQ(Status::OK, status); 1535 1536 uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, 1537 toHidlArray(key.keyId), &iv[0], subSamples, noPattern, 1538 key.clearContentKey, Status::ERROR_DRM_NO_LICENSE); 1539 EXPECT_EQ(0u, byteCount); 1540 1541 closeSession(sessionId); 1542 } 1543 } 1544 } 1545 1546 /** 1547 * Test key removal. Load keys then remove them and verify that 1548 * decryption can't be performed. 1549 */ 1550 TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) { 1551 RETURN_IF_SKIPPED; 1552 for (auto config : contentConfigurations) { 1553 for (auto key : config.keys) { 1554 vector<uint8_t> iv(AES_BLOCK_SIZE, 0); 1555 const Pattern noPattern = {0, 0}; 1556 const vector<SubSample> subSamples = {{.numBytesOfClearData = 256, 1557 .numBytesOfEncryptedData = 256}}; 1558 auto sessionId = openSession(); 1559 1560 Status status = cryptoPlugin->setMediaDrmSession(sessionId); 1561 EXPECT_EQ(Status::OK, status); 1562 1563 loadKeys(sessionId, config); 1564 removeKeys(sessionId); 1565 1566 uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, 1567 toHidlArray(key.keyId), &iv[0], subSamples, noPattern, 1568 key.clearContentKey, Status::ERROR_DRM_NO_LICENSE); 1569 EXPECT_EQ(0u, byteCount); 1570 1571 closeSession(sessionId); 1572 } 1573 } 1574 } 1575 1576 1577 /** 1578 * Instantiate the set of test cases for each vendor module 1579 */ 1580 1581 INSTANTIATE_TEST_CASE_P( 1582 DrmHalVendorFactoryTestCases, DrmHalVendorFactoryTest, 1583 testing::ValuesIn(gVendorModules->getPathList())); 1584 1585 INSTANTIATE_TEST_CASE_P( 1586 DrmHalVendorPluginTestCases, DrmHalVendorPluginTest, 1587 testing::ValuesIn(gVendorModules->getPathList())); 1588 1589 INSTANTIATE_TEST_CASE_P( 1590 DrmHalVendorDecryptTestCases, DrmHalVendorDecryptTest, 1591 testing::ValuesIn(gVendorModules->getPathList())); 1592 1593 int main(int argc, char** argv) { 1594 #if defined(__LP64__) 1595 const char* kModulePath = "/data/local/tmp/64/lib"; 1596 #else 1597 const char* kModulePath = "/data/local/tmp/32/lib"; 1598 #endif 1599 gVendorModules = new drm_vts::VendorModules(kModulePath); 1600 if (gVendorModules->getPathList().size() == 0) { 1601 std::cerr << "No vendor modules found in " << kModulePath << 1602 ", exiting" << std::endl; 1603 exit(-1); 1604 } 1605 ::testing::InitGoogleTest(&argc, argv); 1606 return RUN_ALL_TESTS(); 1607 } 1608