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_CLEARKEY_TEST_H 18 #define DRM_HAL_CLEARKEY_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/types.h> 25 #include <android/hidl/allocator/1.0/IAllocator.h> 26 27 #include <gtest/gtest.h> 28 #include <hidl/HidlSupport.h> 29 #include <hidl/ServiceManagement.h> 30 #include <hidlmemory/mapping.h> 31 #include <log/log.h> 32 33 #include "drm_vts_helper.h" 34 35 using ::android::hidl::allocator::V1_0::IAllocator; 36 using ::android::hidl::memory::V1_0::IMemory; 37 38 using ::drm_vts::DrmHalTestParam; 39 using ::drm_vts::PrintParamInstanceToString; 40 41 using std::string; 42 using std::map; 43 using std::vector; 44 45 /** 46 * These clearkey tests use white box knowledge of the legacy clearkey 47 * plugin to verify that the HIDL HAL services and interfaces are working. 48 * It is not intended to verify any vendor's HAL implementation. If you 49 * are looking for vendor HAL tests, see drm_hal_vendor_test.cpp 50 */ 51 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) 52 #define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) 53 54 namespace android { 55 namespace hardware { 56 namespace drm { 57 namespace V1_0 { 58 namespace vts { 59 60 class DrmHalClearkeyFactoryTest : public ::testing::TestWithParam<DrmHalTestParam> { 61 public: SetUp()62 void SetUp() override { 63 const ::testing::TestInfo* const test_info = 64 ::testing::UnitTest::GetInstance()->current_test_info(); 65 ALOGD("Running test %s.%s", test_info->test_case_name(), 66 test_info->name()); 67 68 const std::string instanceName = GetParam().instance_; 69 drmFactory = IDrmFactory::getService(instanceName); 70 ASSERT_NE(nullptr, drmFactory.get()); 71 cryptoFactory = ICryptoFactory::getService(instanceName); 72 ASSERT_NE(nullptr, cryptoFactory.get()); 73 74 const bool drmClearKey = drmFactory->isCryptoSchemeSupported(kClearKeyUUID); 75 const bool cryptoClearKey = cryptoFactory->isCryptoSchemeSupported(kClearKeyUUID); 76 EXPECT_EQ(drmClearKey, cryptoClearKey); 77 const bool supportsClearKey = drmClearKey && cryptoClearKey; 78 79 const bool drmCommonPsshBox = drmFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); 80 const bool cryptoCommonPsshBox = cryptoFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID); 81 EXPECT_EQ(drmCommonPsshBox, cryptoCommonPsshBox); 82 const bool supportsCommonPsshBox = drmCommonPsshBox && cryptoCommonPsshBox; 83 84 EXPECT_EQ(supportsClearKey, supportsCommonPsshBox); 85 correspondsToThisTest = supportsClearKey && supportsCommonPsshBox; 86 87 if (instanceName == "clearkey") { 88 EXPECT_TRUE(correspondsToThisTest); 89 90 // TODO(b/147449315) 91 // Only the clearkey plugged into the "default" instance supports 92 // this test. Currently the "clearkey" instance fails some tests 93 // here. 94 GTEST_SKIP() << "Clearkey tests don't work with 'clearkey' instance yet."; 95 } 96 97 if (!correspondsToThisTest) { 98 GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; 99 } 100 } 101 102 protected: 103 static constexpr uint8_t kCommonPsshBoxUUID[16] = { 104 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, 105 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B}; 106 107 // To be used in mpd to specify drm scheme for players 108 static constexpr uint8_t kClearKeyUUID[16] = { 109 0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9, 110 0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E}; 111 112 sp<IDrmFactory> drmFactory; 113 sp<ICryptoFactory> cryptoFactory; 114 115 bool correspondsToThisTest; 116 }; 117 118 class DrmHalClearkeyPluginTest : public DrmHalClearkeyFactoryTest { 119 public: SetUp()120 virtual void SetUp() override { 121 // Create factories 122 DrmHalClearkeyFactoryTest::SetUp(); 123 124 if (!correspondsToThisTest) { 125 GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; 126 } 127 128 ASSERT_NE(nullptr, drmFactory.get()); 129 hidl_string packageName("android.hardware.drm.test"); 130 auto res = drmFactory->createPlugin( 131 getUUID(), packageName, 132 [this](Status status, const sp<IDrmPlugin>& plugin) { 133 EXPECT_EQ(Status::OK, status); 134 ASSERT_NE(nullptr, plugin.get()); 135 drmPlugin = plugin; 136 }); 137 ASSERT_OK(res); 138 139 hidl_vec<uint8_t> initVec; 140 res = cryptoFactory->createPlugin( 141 getUUID(), initVec, 142 [this](Status status, const sp<ICryptoPlugin>& plugin) { 143 EXPECT_EQ(Status::OK, status); 144 ASSERT_NE(nullptr, plugin.get()); 145 cryptoPlugin = plugin; 146 }); 147 ASSERT_OK(res); 148 } 149 150 SessionId openSession(); 151 void closeSession(const SessionId& sessionId); 152 hidl_vec<uint8_t> loadKeys(const SessionId& sessionId, const KeyType& type); 153 sp<IMemory> getDecryptMemory(size_t size, size_t index); 154 155 protected: getUUID()156 hidl_array<uint8_t, 16> getUUID() { 157 if (GetParamUUID() == hidl_array<uint8_t, 16>()) { 158 return kClearKeyUUID; 159 } 160 return GetParamUUID(); 161 } 162 GetParamUUID()163 hidl_array<uint8_t, 16> GetParamUUID() { 164 return GetParam().scheme_; 165 } 166 167 sp<IDrmPlugin> drmPlugin; 168 sp<ICryptoPlugin> cryptoPlugin; 169 }; 170 171 class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest { 172 public: SetUp()173 void SetUp() override { 174 DrmHalClearkeyPluginTest::SetUp(); 175 176 if (!correspondsToThisTest) { 177 GTEST_SKIP() << "Cannot test clearkey features on non-clearkey DRM modules"; 178 } 179 } 180 void fillRandom(const sp<IMemory>& memory); toHidlArray(const vector<uint8_t> & vec)181 hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) { 182 EXPECT_EQ(16u, vec.size()); 183 return hidl_array<uint8_t, 16>(&vec[0]); 184 } 185 uint32_t decrypt(Mode mode, uint8_t* iv, const hidl_vec<SubSample>& subSamples, 186 const Pattern& pattern, Status status); 187 void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, 188 const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key); 189 void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv, 190 const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key); 191 void decryptWithInvalidKeys(hidl_vec<uint8_t>& invalidResponse, 192 vector<uint8_t>& iv, const Pattern& noPattern, const vector<SubSample>& subSamples); 193 }; 194 195 } // namespace vts 196 } // namespace V1_0 197 } // namespace drm 198 } // namespace hardware 199 } // namespace android 200 201 #endif // DRM_HAL_CLEARKEY_TEST_H 202