Home | History | Annotate | Download | only in functional
      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