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