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