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