1 /*
2  * Copyright (C) 2020 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 #ifndef DRM_HAL_VENDOR_TEST_H
18 #define DRM_HAL_VENDOR_TEST_H
19 
20 #include <android/hardware/drm/1.0/ICryptoFactory.h>
21 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
22 #include <android/hardware/drm/1.0/IDrmFactory.h>
23 #include <android/hardware/drm/1.0/IDrmPlugin.h>
24 #include <android/hardware/drm/1.0/IDrmPluginListener.h>
25 #include <android/hardware/drm/1.0/types.h>
26 #include <android/hidl/allocator/1.0/IAllocator.h>
27 
28 #include <gtest/gtest.h>
29 #include <hidl/HidlSupport.h>
30 #include <hidl/ServiceManagement.h>
31 #include <hidlmemory/mapping.h>
32 #include <log/log.h>
33 
34 #include <memory>
35 #include <set>
36 #include <vector>
37 
38 #include "drm_hal_vendor_module_api.h"
39 #include "drm_vts_helper.h"
40 #include "vendor_modules.h"
41 #include <VtsHalHidlTargetCallbackBase.h>
42 
43 using ::android::hidl::allocator::V1_0::IAllocator;
44 using ::android::hidl::memory::V1_0::IMemory;
45 
46 using ::drm_vts::DrmHalTestParam;
47 using ::drm_vts::PrintParamInstanceToString;
48 
49 using std::string;
50 using std::unique_ptr;
51 using std::map;
52 using std::vector;
53 
54 using ContentConfiguration = ::DrmHalVTSVendorModule_V1::ContentConfiguration;
55 using Key = ::DrmHalVTSVendorModule_V1::ContentConfiguration::Key;
56 
57 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
58 #define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
59 
60 #define RETURN_IF_SKIPPED                                                                  \
61     if (vendorModule == nullptr || !vendorModule->isInstalled()) {                         \
62         GTEST_SKIP() << "This drm scheme not supported."                                   \
63                      << " library:" << GetParam() << " service-name:"                      \
64                      << (vendorModule == nullptr ? "N/A" : vendorModule->getServiceName()) \
65                      << std::endl;                                                         \
66         return;                                                                            \
67     }
68 
69 namespace android {
70 namespace hardware {
71 namespace drm {
72 namespace V1_0 {
73 namespace vts {
74 
75 class DrmHalVendorFactoryTest : public testing::TestWithParam<DrmHalTestParam> {
76    public:
77      DrmHalVendorFactoryTest();
~DrmHalVendorFactoryTest()78      virtual ~DrmHalVendorFactoryTest() {}
79 
SetUp()80      virtual void SetUp() {
81          const ::testing::TestInfo* const test_info =
82                  ::testing::UnitTest::GetInstance()->current_test_info();
83          ALOGD("Running test %s.%s from vendor module %s", test_info->test_case_name(),
84                test_info->name(), GetParam().instance_.c_str());
85 
86          const std::string instance = GetParam().instance_;
87          if (instance == "widevine") {
88              ASSERT_NE(nullptr, vendorModule.get());
89          }
90 
91          if (vendorModule == nullptr) {
92              GTEST_SKIP() << "No vendor module available";
93          } else {
94              ASSERT_EQ(instance, vendorModule->getServiceName());
95              contentConfigurations = vendorModule->getContentConfigurations();
96          }
97 
98          drmFactory = IDrmFactory::getService(instance);
99          ASSERT_NE(nullptr, drmFactory.get());
100          cryptoFactory = ICryptoFactory::getService(instance);
101          ASSERT_NE(nullptr, cryptoFactory.get());
102 
103          // If drm scheme not installed skip subsequent tests
104          if (!drmFactory->isCryptoSchemeSupported(getUUID())) {
105              // no GTEST_SKIP since only some tests require the module
106              vendorModule->setInstalled(false);
107              hidl_array<uint8_t, 16> noUUID;
108              ASSERT_EQ(GetParamUUID(), noUUID) << "param uuid unsupported";
109          }
110      }
111 
112    protected:
getUUID()113     hidl_array<uint8_t, 16> getUUID() {
114         if (GetParamUUID() == hidl_array<uint8_t, 16>()) {
115             return getVendorUUID();
116         }
117         return GetParamUUID();
118     }
119 
getVendorUUID()120     hidl_array<uint8_t, 16> getVendorUUID() {
121         if (vendorModule == nullptr) return {};
122         vector<uint8_t> uuid = vendorModule->getUUID();
123         return hidl_array<uint8_t, 16>(&uuid[0]);
124     }
125 
GetParamUUID()126     hidl_array<uint8_t, 16> GetParamUUID() {
127         return GetParam().scheme_;
128     }
129 
130     sp<IDrmFactory> drmFactory;
131     sp<ICryptoFactory> cryptoFactory;
132     unique_ptr<DrmHalVTSVendorModule_V1> vendorModule;
133     vector<ContentConfiguration> contentConfigurations;
134 };
135 
136 class DrmHalVendorPluginTest : public DrmHalVendorFactoryTest {
137    public:
~DrmHalVendorPluginTest()138     virtual ~DrmHalVendorPluginTest() {}
SetUp()139     virtual void SetUp() override {
140         // Create factories
141         DrmHalVendorFactoryTest::SetUp();
142         RETURN_IF_SKIPPED;
143 
144         hidl_string packageName("android.hardware.drm.test");
145         auto res = drmFactory->createPlugin(
146                 getVendorUUID(), packageName,
147                 [this](Status status, const sp<IDrmPlugin>& plugin) {
148                     EXPECT_EQ(Status::OK, status);
149                     ASSERT_NE(nullptr, plugin.get());
150                     drmPlugin = plugin;
151                 });
152         ASSERT_OK(res);
153 
154         hidl_vec<uint8_t> initVec;
155         res = cryptoFactory->createPlugin(
156                 getVendorUUID(), initVec,
157                 [this](Status status, const sp<ICryptoPlugin>& plugin) {
158                     EXPECT_EQ(Status::OK, status);
159                     ASSERT_NE(nullptr, plugin.get());
160                     cryptoPlugin = plugin;
161                 });
162         ASSERT_OK(res);
163     }
164 
TearDown()165     virtual void TearDown() override {}
166 
167     SessionId openSession();
168     void closeSession(const SessionId& sessionId);
169     sp<IMemory> getDecryptMemory(size_t size, size_t index);
170     KeyedVector toHidlKeyedVector(const map<string, string>& params);
171     hidl_vec<uint8_t> loadKeys(const SessionId& sessionId,
172                                const ContentConfiguration& configuration,
173                                const KeyType& type);
174 
175    protected:
176     sp<IDrmPlugin> drmPlugin;
177     sp<ICryptoPlugin> cryptoPlugin;
178 };
179 
180 class DrmHalVendorDecryptTest : public DrmHalVendorPluginTest {
181    public:
182     DrmHalVendorDecryptTest() = default;
~DrmHalVendorDecryptTest()183     virtual ~DrmHalVendorDecryptTest() {}
184 
185    protected:
186     void fillRandom(const sp<IMemory>& memory);
toHidlArray(const vector<uint8_t> & vec)187     hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) {
188         EXPECT_EQ(vec.size(), 16u);
189         return hidl_array<uint8_t, 16>(&vec[0]);
190     }
191     hidl_vec<KeyValue> queryKeyStatus(SessionId sessionId);
192     void removeKeys(SessionId sessionId);
193     uint32_t decrypt(Mode mode, bool isSecure,
194             const hidl_array<uint8_t, 16>& keyId, uint8_t* iv,
195             const hidl_vec<SubSample>& subSamples, const Pattern& pattern,
196             const vector<uint8_t>& key, Status expectedStatus);
197     void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
198             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
199     void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
200             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
201 };
202 
203 }  // namespace vts
204 }  // namespace V1_0
205 }  // namespace drm
206 }  // namespace hardware
207 }  // namespace android
208 
209 #endif  // DRM_HAL_VENDOR_TEST_H
210