xref: /aosp_15_r20/frameworks/av/drm/libmediadrm/CryptoHalHidl.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "CryptoHalHidl"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <android/hardware/drm/1.0/types.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <android/hidl/manager/1.2/IServiceManager.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <hidlmemory/FrameworkUtils.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/hardware/CryptoAPI.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/MediaErrors.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/hexdump.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/CryptoHalHidl.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <mediadrm/DrmUtils.h>
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::BufferType;
34*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::DestinationBuffer;
35*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::ICryptoFactory;
36*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::ICryptoPlugin;
37*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::Mode;
38*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::Pattern;
39*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::SharedBuffer;
40*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::Status;
41*ec779b8eSAndroid Build Coastguard Worker using drm::V1_0::SubSample;
42*ec779b8eSAndroid Build Coastguard Worker 
43*ec779b8eSAndroid Build Coastguard Worker using ::android::sp;
44*ec779b8eSAndroid Build Coastguard Worker using ::android::DrmUtils::toStatusT;
45*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_array;
46*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_handle;
47*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_memory;
48*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_string;
49*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::hidl_vec;
50*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::HidlMemory;
51*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::Return;
52*ec779b8eSAndroid Build Coastguard Worker using ::android::hardware::Void;
53*ec779b8eSAndroid Build Coastguard Worker 
54*ec779b8eSAndroid Build Coastguard Worker typedef drm::V1_2::Status Status_V1_2;
55*ec779b8eSAndroid Build Coastguard Worker 
56*ec779b8eSAndroid Build Coastguard Worker namespace android {
57*ec779b8eSAndroid Build Coastguard Worker 
toHidlVec(const Vector<uint8_t> & vector)58*ec779b8eSAndroid Build Coastguard Worker static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t>& vector) {
59*ec779b8eSAndroid Build Coastguard Worker     hidl_vec<uint8_t> vec;
60*ec779b8eSAndroid Build Coastguard Worker     vec.setToExternal(const_cast<uint8_t*>(vector.array()), vector.size());
61*ec779b8eSAndroid Build Coastguard Worker     return vec;
62*ec779b8eSAndroid Build Coastguard Worker }
63*ec779b8eSAndroid Build Coastguard Worker 
toHidlVec(const void * ptr,size_t size)64*ec779b8eSAndroid Build Coastguard Worker static hidl_vec<uint8_t> toHidlVec(const void* ptr, size_t size) {
65*ec779b8eSAndroid Build Coastguard Worker     hidl_vec<uint8_t> vec;
66*ec779b8eSAndroid Build Coastguard Worker     vec.resize(size);
67*ec779b8eSAndroid Build Coastguard Worker     memcpy(vec.data(), ptr, size);
68*ec779b8eSAndroid Build Coastguard Worker     return vec;
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker 
toHidlArray16(const uint8_t * ptr)71*ec779b8eSAndroid Build Coastguard Worker static hidl_array<uint8_t, 16> toHidlArray16(const uint8_t* ptr) {
72*ec779b8eSAndroid Build Coastguard Worker     if (!ptr) {
73*ec779b8eSAndroid Build Coastguard Worker         return hidl_array<uint8_t, 16>();
74*ec779b8eSAndroid Build Coastguard Worker     }
75*ec779b8eSAndroid Build Coastguard Worker     return hidl_array<uint8_t, 16>(ptr);
76*ec779b8eSAndroid Build Coastguard Worker }
77*ec779b8eSAndroid Build Coastguard Worker 
toString8(hidl_string hString)78*ec779b8eSAndroid Build Coastguard Worker static String8 toString8(hidl_string hString) {
79*ec779b8eSAndroid Build Coastguard Worker     return String8(hString.c_str());
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker 
CryptoHalHidl()82*ec779b8eSAndroid Build Coastguard Worker CryptoHalHidl::CryptoHalHidl()
83*ec779b8eSAndroid Build Coastguard Worker     : mFactories(makeCryptoFactories()),
84*ec779b8eSAndroid Build Coastguard Worker       mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
85*ec779b8eSAndroid Build Coastguard Worker       mHeapSeqNum(0) {}
86*ec779b8eSAndroid Build Coastguard Worker 
~CryptoHalHidl()87*ec779b8eSAndroid Build Coastguard Worker CryptoHalHidl::~CryptoHalHidl() {}
88*ec779b8eSAndroid Build Coastguard Worker 
makeCryptoFactories()89*ec779b8eSAndroid Build Coastguard Worker Vector<sp<ICryptoFactory>> CryptoHalHidl::makeCryptoFactories() {
90*ec779b8eSAndroid Build Coastguard Worker     Vector<sp<ICryptoFactory>> factories;
91*ec779b8eSAndroid Build Coastguard Worker 
92*ec779b8eSAndroid Build Coastguard Worker     auto manager = hardware::defaultServiceManager1_2();
93*ec779b8eSAndroid Build Coastguard Worker     if (manager != NULL) {
94*ec779b8eSAndroid Build Coastguard Worker         manager->listManifestByInterface(
95*ec779b8eSAndroid Build Coastguard Worker                 drm::V1_0::ICryptoFactory::descriptor,
96*ec779b8eSAndroid Build Coastguard Worker                 [&factories](const hidl_vec<hidl_string>& registered) {
97*ec779b8eSAndroid Build Coastguard Worker                     for (const auto& instance : registered) {
98*ec779b8eSAndroid Build Coastguard Worker                         auto factory = drm::V1_0::ICryptoFactory::getService(instance);
99*ec779b8eSAndroid Build Coastguard Worker                         if (factory != NULL) {
100*ec779b8eSAndroid Build Coastguard Worker                             ALOGD("found [email protected] ICryptoFactory %s", instance.c_str());
101*ec779b8eSAndroid Build Coastguard Worker                             factories.push_back(factory);
102*ec779b8eSAndroid Build Coastguard Worker                         }
103*ec779b8eSAndroid Build Coastguard Worker                     }
104*ec779b8eSAndroid Build Coastguard Worker                 });
105*ec779b8eSAndroid Build Coastguard Worker         manager->listManifestByInterface(
106*ec779b8eSAndroid Build Coastguard Worker                 drm::V1_1::ICryptoFactory::descriptor,
107*ec779b8eSAndroid Build Coastguard Worker                 [&factories](const hidl_vec<hidl_string>& registered) {
108*ec779b8eSAndroid Build Coastguard Worker                     for (const auto& instance : registered) {
109*ec779b8eSAndroid Build Coastguard Worker                         auto factory = drm::V1_1::ICryptoFactory::getService(instance);
110*ec779b8eSAndroid Build Coastguard Worker                         if (factory != NULL) {
111*ec779b8eSAndroid Build Coastguard Worker                             ALOGD("found [email protected] ICryptoFactory %s", instance.c_str());
112*ec779b8eSAndroid Build Coastguard Worker                             factories.push_back(factory);
113*ec779b8eSAndroid Build Coastguard Worker                         }
114*ec779b8eSAndroid Build Coastguard Worker                     }
115*ec779b8eSAndroid Build Coastguard Worker                 });
116*ec779b8eSAndroid Build Coastguard Worker     }
117*ec779b8eSAndroid Build Coastguard Worker 
118*ec779b8eSAndroid Build Coastguard Worker     if (factories.size() == 0) {
119*ec779b8eSAndroid Build Coastguard Worker         // must be in passthrough mode, load the default passthrough service
120*ec779b8eSAndroid Build Coastguard Worker         auto passthrough = ICryptoFactory::getService();
121*ec779b8eSAndroid Build Coastguard Worker         if (passthrough != NULL) {
122*ec779b8eSAndroid Build Coastguard Worker             ALOGI("makeCryptoFactories: using default passthrough crypto instance");
123*ec779b8eSAndroid Build Coastguard Worker             factories.push_back(passthrough);
124*ec779b8eSAndroid Build Coastguard Worker         } else {
125*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Failed to find any crypto factories");
126*ec779b8eSAndroid Build Coastguard Worker         }
127*ec779b8eSAndroid Build Coastguard Worker     }
128*ec779b8eSAndroid Build Coastguard Worker     return factories;
129*ec779b8eSAndroid Build Coastguard Worker }
130*ec779b8eSAndroid Build Coastguard Worker 
makeCryptoPlugin(const sp<ICryptoFactory> & factory,const uint8_t uuid[16],const void * initData,size_t initDataSize)131*ec779b8eSAndroid Build Coastguard Worker sp<ICryptoPlugin> CryptoHalHidl::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
132*ec779b8eSAndroid Build Coastguard Worker                                                   const uint8_t uuid[16], const void* initData,
133*ec779b8eSAndroid Build Coastguard Worker                                                   size_t initDataSize) {
134*ec779b8eSAndroid Build Coastguard Worker     sp<ICryptoPlugin> plugin;
135*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult =
136*ec779b8eSAndroid Build Coastguard Worker             factory->createPlugin(toHidlArray16(uuid), toHidlVec(initData, initDataSize),
137*ec779b8eSAndroid Build Coastguard Worker                                   [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
138*ec779b8eSAndroid Build Coastguard Worker                                       if (status != Status::OK) {
139*ec779b8eSAndroid Build Coastguard Worker                                           ALOGE("Failed to make crypto plugin");
140*ec779b8eSAndroid Build Coastguard Worker                                           return;
141*ec779b8eSAndroid Build Coastguard Worker                                       }
142*ec779b8eSAndroid Build Coastguard Worker                                       plugin = hPlugin;
143*ec779b8eSAndroid Build Coastguard Worker                                   });
144*ec779b8eSAndroid Build Coastguard Worker     if (!hResult.isOk()) {
145*ec779b8eSAndroid Build Coastguard Worker         mInitCheck = DEAD_OBJECT;
146*ec779b8eSAndroid Build Coastguard Worker     }
147*ec779b8eSAndroid Build Coastguard Worker     return plugin;
148*ec779b8eSAndroid Build Coastguard Worker }
149*ec779b8eSAndroid Build Coastguard Worker 
initCheck() const150*ec779b8eSAndroid Build Coastguard Worker status_t CryptoHalHidl::initCheck() const {
151*ec779b8eSAndroid Build Coastguard Worker     return mInitCheck;
152*ec779b8eSAndroid Build Coastguard Worker }
153*ec779b8eSAndroid Build Coastguard Worker 
isCryptoSchemeSupported(const uint8_t uuid[16])154*ec779b8eSAndroid Build Coastguard Worker bool CryptoHalHidl::isCryptoSchemeSupported(const uint8_t uuid[16]) {
155*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
156*ec779b8eSAndroid Build Coastguard Worker 
157*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mFactories.size(); i++) {
158*ec779b8eSAndroid Build Coastguard Worker         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
159*ec779b8eSAndroid Build Coastguard Worker             return true;
160*ec779b8eSAndroid Build Coastguard Worker         }
161*ec779b8eSAndroid Build Coastguard Worker     }
162*ec779b8eSAndroid Build Coastguard Worker     return false;
163*ec779b8eSAndroid Build Coastguard Worker }
164*ec779b8eSAndroid Build Coastguard Worker 
createPlugin(const uint8_t uuid[16],const void * data,size_t size)165*ec779b8eSAndroid Build Coastguard Worker status_t CryptoHalHidl::createPlugin(const uint8_t uuid[16], const void* data, size_t size) {
166*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
167*ec779b8eSAndroid Build Coastguard Worker 
168*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < mFactories.size(); i++) {
169*ec779b8eSAndroid Build Coastguard Worker         if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
170*ec779b8eSAndroid Build Coastguard Worker             mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
171*ec779b8eSAndroid Build Coastguard Worker             if (mPlugin != NULL) {
172*ec779b8eSAndroid Build Coastguard Worker                 mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin);
173*ec779b8eSAndroid Build Coastguard Worker             }
174*ec779b8eSAndroid Build Coastguard Worker         }
175*ec779b8eSAndroid Build Coastguard Worker     }
176*ec779b8eSAndroid Build Coastguard Worker 
177*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck == NO_INIT) {
178*ec779b8eSAndroid Build Coastguard Worker         mInitCheck = mPlugin == NULL ? ERROR_UNSUPPORTED : OK;
179*ec779b8eSAndroid Build Coastguard Worker     }
180*ec779b8eSAndroid Build Coastguard Worker 
181*ec779b8eSAndroid Build Coastguard Worker     return mInitCheck;
182*ec779b8eSAndroid Build Coastguard Worker }
183*ec779b8eSAndroid Build Coastguard Worker 
destroyPlugin()184*ec779b8eSAndroid Build Coastguard Worker status_t CryptoHalHidl::destroyPlugin() {
185*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
186*ec779b8eSAndroid Build Coastguard Worker 
187*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
188*ec779b8eSAndroid Build Coastguard Worker         return mInitCheck;
189*ec779b8eSAndroid Build Coastguard Worker     }
190*ec779b8eSAndroid Build Coastguard Worker 
191*ec779b8eSAndroid Build Coastguard Worker     mPlugin.clear();
192*ec779b8eSAndroid Build Coastguard Worker     mPluginV1_2.clear();
193*ec779b8eSAndroid Build Coastguard Worker     mInitCheck = NO_INIT;
194*ec779b8eSAndroid Build Coastguard Worker     return OK;
195*ec779b8eSAndroid Build Coastguard Worker }
196*ec779b8eSAndroid Build Coastguard Worker 
requiresSecureDecoderComponent(const char * mime) const197*ec779b8eSAndroid Build Coastguard Worker bool CryptoHalHidl::requiresSecureDecoderComponent(const char* mime) const {
198*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
199*ec779b8eSAndroid Build Coastguard Worker 
200*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
201*ec779b8eSAndroid Build Coastguard Worker         return false;
202*ec779b8eSAndroid Build Coastguard Worker     }
203*ec779b8eSAndroid Build Coastguard Worker 
204*ec779b8eSAndroid Build Coastguard Worker     Return<bool> hResult = mPlugin->requiresSecureDecoderComponent(hidl_string(mime));
205*ec779b8eSAndroid Build Coastguard Worker     if (!hResult.isOk()) {
206*ec779b8eSAndroid Build Coastguard Worker         return false;
207*ec779b8eSAndroid Build Coastguard Worker     }
208*ec779b8eSAndroid Build Coastguard Worker     return hResult;
209*ec779b8eSAndroid Build Coastguard Worker }
210*ec779b8eSAndroid Build Coastguard Worker 
211*ec779b8eSAndroid Build Coastguard Worker /**
212*ec779b8eSAndroid Build Coastguard Worker  * If the heap base isn't set, get the heap base from the HidlMemory
213*ec779b8eSAndroid Build Coastguard Worker  * and send it to the HAL so it can map a remote heap of the same
214*ec779b8eSAndroid Build Coastguard Worker  * size.  Once the heap base is established, shared memory buffers
215*ec779b8eSAndroid Build Coastguard Worker  * are sent by providing an offset into the heap and a buffer size.
216*ec779b8eSAndroid Build Coastguard Worker  */
setHeapBase(const sp<HidlMemory> & heap)217*ec779b8eSAndroid Build Coastguard Worker int32_t CryptoHalHidl::setHeapBase(const sp<HidlMemory>& heap) {
218*ec779b8eSAndroid Build Coastguard Worker     if (heap == NULL || mHeapSeqNum < 0) {
219*ec779b8eSAndroid Build Coastguard Worker         ALOGE("setHeapBase(): heap %p mHeapSeqNum %d", heap.get(), mHeapSeqNum);
220*ec779b8eSAndroid Build Coastguard Worker         return -1;
221*ec779b8eSAndroid Build Coastguard Worker     }
222*ec779b8eSAndroid Build Coastguard Worker 
223*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
224*ec779b8eSAndroid Build Coastguard Worker 
225*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
226*ec779b8eSAndroid Build Coastguard Worker         return -1;
227*ec779b8eSAndroid Build Coastguard Worker     }
228*ec779b8eSAndroid Build Coastguard Worker 
229*ec779b8eSAndroid Build Coastguard Worker     int32_t seqNum = mHeapSeqNum++;
230*ec779b8eSAndroid Build Coastguard Worker     uint32_t bufferId = static_cast<uint32_t>(seqNum);
231*ec779b8eSAndroid Build Coastguard Worker     mHeapSizes.add(seqNum, heap->size());
232*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult = mPlugin->setSharedBufferBase(*heap, bufferId);
233*ec779b8eSAndroid Build Coastguard Worker     ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
234*ec779b8eSAndroid Build Coastguard Worker     return seqNum;
235*ec779b8eSAndroid Build Coastguard Worker }
236*ec779b8eSAndroid Build Coastguard Worker 
clearHeapBase(int32_t seqNum)237*ec779b8eSAndroid Build Coastguard Worker void CryptoHalHidl::clearHeapBase(int32_t seqNum) {
238*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
239*ec779b8eSAndroid Build Coastguard Worker 
240*ec779b8eSAndroid Build Coastguard Worker     /*
241*ec779b8eSAndroid Build Coastguard Worker      * Clear the remote shared memory mapping by setting the shared
242*ec779b8eSAndroid Build Coastguard Worker      * buffer base to a null hidl_memory.
243*ec779b8eSAndroid Build Coastguard Worker      *
244*ec779b8eSAndroid Build Coastguard Worker      * TODO: Add a releaseSharedBuffer method in a future DRM HAL
245*ec779b8eSAndroid Build Coastguard Worker      * API version to make this explicit.
246*ec779b8eSAndroid Build Coastguard Worker      */
247*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mHeapSizes.indexOfKey(seqNum);
248*ec779b8eSAndroid Build Coastguard Worker     if (index >= 0) {
249*ec779b8eSAndroid Build Coastguard Worker         if (mPlugin != NULL) {
250*ec779b8eSAndroid Build Coastguard Worker             uint32_t bufferId = static_cast<uint32_t>(seqNum);
251*ec779b8eSAndroid Build Coastguard Worker             Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId);
252*ec779b8eSAndroid Build Coastguard Worker             ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
253*ec779b8eSAndroid Build Coastguard Worker         }
254*ec779b8eSAndroid Build Coastguard Worker         mHeapSizes.removeItem(seqNum);
255*ec779b8eSAndroid Build Coastguard Worker     }
256*ec779b8eSAndroid Build Coastguard Worker }
257*ec779b8eSAndroid Build Coastguard Worker 
checkSharedBuffer(const::SharedBuffer & buffer)258*ec779b8eSAndroid Build Coastguard Worker status_t CryptoHalHidl::checkSharedBuffer(const ::SharedBuffer& buffer) {
259*ec779b8eSAndroid Build Coastguard Worker     int32_t seqNum = static_cast<int32_t>(buffer.bufferId);
260*ec779b8eSAndroid Build Coastguard Worker     // memory must be in one of the heaps that have been set
261*ec779b8eSAndroid Build Coastguard Worker     if (mHeapSizes.indexOfKey(seqNum) < 0) {
262*ec779b8eSAndroid Build Coastguard Worker         return UNKNOWN_ERROR;
263*ec779b8eSAndroid Build Coastguard Worker     }
264*ec779b8eSAndroid Build Coastguard Worker 
265*ec779b8eSAndroid Build Coastguard Worker     // memory must be within the address space of the heap
266*ec779b8eSAndroid Build Coastguard Worker     size_t heapSize = mHeapSizes.valueFor(seqNum);
267*ec779b8eSAndroid Build Coastguard Worker     if (heapSize < buffer.offset + buffer.size || SIZE_MAX - buffer.offset < buffer.size) {
268*ec779b8eSAndroid Build Coastguard Worker         android_errorWriteLog(0x534e4554, "76221123");
269*ec779b8eSAndroid Build Coastguard Worker         return UNKNOWN_ERROR;
270*ec779b8eSAndroid Build Coastguard Worker     }
271*ec779b8eSAndroid Build Coastguard Worker 
272*ec779b8eSAndroid Build Coastguard Worker     return OK;
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker 
decrypt(const uint8_t keyId[16],const uint8_t iv[16],CryptoPlugin::Mode mode,const CryptoPlugin::Pattern & pattern,const drm::V1_0::SharedBuffer & hSource,size_t offset,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,const drm::V1_0::DestinationBuffer & hDestination,AString * errorDetailMsg)275*ec779b8eSAndroid Build Coastguard Worker ssize_t CryptoHalHidl::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
276*ec779b8eSAndroid Build Coastguard Worker                                CryptoPlugin::Mode mode, const CryptoPlugin::Pattern& pattern,
277*ec779b8eSAndroid Build Coastguard Worker                                const drm::V1_0::SharedBuffer& hSource, size_t offset,
278*ec779b8eSAndroid Build Coastguard Worker                                const CryptoPlugin::SubSample* subSamples, size_t numSubSamples,
279*ec779b8eSAndroid Build Coastguard Worker                                const drm::V1_0::DestinationBuffer& hDestination,
280*ec779b8eSAndroid Build Coastguard Worker                                AString* errorDetailMsg) {
281*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
282*ec779b8eSAndroid Build Coastguard Worker 
283*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
284*ec779b8eSAndroid Build Coastguard Worker         return mInitCheck;
285*ec779b8eSAndroid Build Coastguard Worker     }
286*ec779b8eSAndroid Build Coastguard Worker 
287*ec779b8eSAndroid Build Coastguard Worker     Mode hMode;
288*ec779b8eSAndroid Build Coastguard Worker     switch (mode) {
289*ec779b8eSAndroid Build Coastguard Worker         case CryptoPlugin::kMode_Unencrypted:
290*ec779b8eSAndroid Build Coastguard Worker             hMode = Mode::UNENCRYPTED;
291*ec779b8eSAndroid Build Coastguard Worker             break;
292*ec779b8eSAndroid Build Coastguard Worker         case CryptoPlugin::kMode_AES_CTR:
293*ec779b8eSAndroid Build Coastguard Worker             hMode = Mode::AES_CTR;
294*ec779b8eSAndroid Build Coastguard Worker             break;
295*ec779b8eSAndroid Build Coastguard Worker         case CryptoPlugin::kMode_AES_WV:
296*ec779b8eSAndroid Build Coastguard Worker             hMode = Mode::AES_CBC_CTS;
297*ec779b8eSAndroid Build Coastguard Worker             break;
298*ec779b8eSAndroid Build Coastguard Worker         case CryptoPlugin::kMode_AES_CBC:
299*ec779b8eSAndroid Build Coastguard Worker             hMode = Mode::AES_CBC;
300*ec779b8eSAndroid Build Coastguard Worker             break;
301*ec779b8eSAndroid Build Coastguard Worker         default:
302*ec779b8eSAndroid Build Coastguard Worker             return UNKNOWN_ERROR;
303*ec779b8eSAndroid Build Coastguard Worker     }
304*ec779b8eSAndroid Build Coastguard Worker 
305*ec779b8eSAndroid Build Coastguard Worker     Pattern hPattern;
306*ec779b8eSAndroid Build Coastguard Worker     hPattern.encryptBlocks = pattern.mEncryptBlocks;
307*ec779b8eSAndroid Build Coastguard Worker     hPattern.skipBlocks = pattern.mSkipBlocks;
308*ec779b8eSAndroid Build Coastguard Worker 
309*ec779b8eSAndroid Build Coastguard Worker     std::vector<SubSample> stdSubSamples;
310*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < numSubSamples; i++) {
311*ec779b8eSAndroid Build Coastguard Worker         SubSample subSample;
312*ec779b8eSAndroid Build Coastguard Worker         subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
313*ec779b8eSAndroid Build Coastguard Worker         subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
314*ec779b8eSAndroid Build Coastguard Worker         stdSubSamples.push_back(subSample);
315*ec779b8eSAndroid Build Coastguard Worker     }
316*ec779b8eSAndroid Build Coastguard Worker     auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
317*ec779b8eSAndroid Build Coastguard Worker 
318*ec779b8eSAndroid Build Coastguard Worker     bool secure;
319*ec779b8eSAndroid Build Coastguard Worker     if (hDestination.type == BufferType::SHARED_MEMORY) {
320*ec779b8eSAndroid Build Coastguard Worker         status_t status = checkSharedBuffer(hDestination.nonsecureMemory);
321*ec779b8eSAndroid Build Coastguard Worker         if (status != OK) {
322*ec779b8eSAndroid Build Coastguard Worker             return status;
323*ec779b8eSAndroid Build Coastguard Worker         }
324*ec779b8eSAndroid Build Coastguard Worker         secure = false;
325*ec779b8eSAndroid Build Coastguard Worker     } else if (hDestination.type == BufferType::NATIVE_HANDLE) {
326*ec779b8eSAndroid Build Coastguard Worker         secure = true;
327*ec779b8eSAndroid Build Coastguard Worker     } else {
328*ec779b8eSAndroid Build Coastguard Worker         android_errorWriteLog(0x534e4554, "70526702");
329*ec779b8eSAndroid Build Coastguard Worker         return UNKNOWN_ERROR;
330*ec779b8eSAndroid Build Coastguard Worker     }
331*ec779b8eSAndroid Build Coastguard Worker 
332*ec779b8eSAndroid Build Coastguard Worker     status_t status = checkSharedBuffer(hSource);
333*ec779b8eSAndroid Build Coastguard Worker     if (status != OK) {
334*ec779b8eSAndroid Build Coastguard Worker         return status;
335*ec779b8eSAndroid Build Coastguard Worker     }
336*ec779b8eSAndroid Build Coastguard Worker 
337*ec779b8eSAndroid Build Coastguard Worker     status_t err = UNKNOWN_ERROR;
338*ec779b8eSAndroid Build Coastguard Worker     uint32_t bytesWritten = 0;
339*ec779b8eSAndroid Build Coastguard Worker 
340*ec779b8eSAndroid Build Coastguard Worker     Return<void> hResult;
341*ec779b8eSAndroid Build Coastguard Worker 
342*ec779b8eSAndroid Build Coastguard Worker     mLock.unlock();
343*ec779b8eSAndroid Build Coastguard Worker     if (mPluginV1_2 != NULL) {
344*ec779b8eSAndroid Build Coastguard Worker         hResult = mPluginV1_2->decrypt_1_2(
345*ec779b8eSAndroid Build Coastguard Worker                 secure, toHidlArray16(keyId), toHidlArray16(iv), hMode, hPattern, hSubSamples,
346*ec779b8eSAndroid Build Coastguard Worker                 hSource, offset, hDestination,
347*ec779b8eSAndroid Build Coastguard Worker                 [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) {
348*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status_V1_2::OK) {
349*ec779b8eSAndroid Build Coastguard Worker                         bytesWritten = hBytesWritten;
350*ec779b8eSAndroid Build Coastguard Worker                         if (errorDetailMsg != nullptr) {
351*ec779b8eSAndroid Build Coastguard Worker                             *errorDetailMsg = toString8(hDetailedError);
352*ec779b8eSAndroid Build Coastguard Worker                         }
353*ec779b8eSAndroid Build Coastguard Worker                     }
354*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
355*ec779b8eSAndroid Build Coastguard Worker                 });
356*ec779b8eSAndroid Build Coastguard Worker     } else {
357*ec779b8eSAndroid Build Coastguard Worker         hResult = mPlugin->decrypt(
358*ec779b8eSAndroid Build Coastguard Worker                 secure, toHidlArray16(keyId), toHidlArray16(iv), hMode, hPattern, hSubSamples,
359*ec779b8eSAndroid Build Coastguard Worker                 hSource, offset, hDestination,
360*ec779b8eSAndroid Build Coastguard Worker                 [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
361*ec779b8eSAndroid Build Coastguard Worker                     if (status == Status::OK) {
362*ec779b8eSAndroid Build Coastguard Worker                         bytesWritten = hBytesWritten;
363*ec779b8eSAndroid Build Coastguard Worker                         if (errorDetailMsg != nullptr) {
364*ec779b8eSAndroid Build Coastguard Worker                             *errorDetailMsg = toString8(hDetailedError);
365*ec779b8eSAndroid Build Coastguard Worker                         }
366*ec779b8eSAndroid Build Coastguard Worker                     }
367*ec779b8eSAndroid Build Coastguard Worker                     err = toStatusT(status);
368*ec779b8eSAndroid Build Coastguard Worker                 });
369*ec779b8eSAndroid Build Coastguard Worker     }
370*ec779b8eSAndroid Build Coastguard Worker 
371*ec779b8eSAndroid Build Coastguard Worker     err = hResult.isOk() ? err : DEAD_OBJECT;
372*ec779b8eSAndroid Build Coastguard Worker     if (err == OK) {
373*ec779b8eSAndroid Build Coastguard Worker         return bytesWritten;
374*ec779b8eSAndroid Build Coastguard Worker     }
375*ec779b8eSAndroid Build Coastguard Worker     return err;
376*ec779b8eSAndroid Build Coastguard Worker }
377*ec779b8eSAndroid Build Coastguard Worker 
notifyResolution(uint32_t width,uint32_t height)378*ec779b8eSAndroid Build Coastguard Worker void CryptoHalHidl::notifyResolution(uint32_t width, uint32_t height) {
379*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
380*ec779b8eSAndroid Build Coastguard Worker 
381*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
382*ec779b8eSAndroid Build Coastguard Worker         return;
383*ec779b8eSAndroid Build Coastguard Worker     }
384*ec779b8eSAndroid Build Coastguard Worker 
385*ec779b8eSAndroid Build Coastguard Worker     auto hResult = mPlugin->notifyResolution(width, height);
386*ec779b8eSAndroid Build Coastguard Worker     ALOGE_IF(!hResult.isOk(), "notifyResolution txn failed %s", hResult.description().c_str());
387*ec779b8eSAndroid Build Coastguard Worker }
388*ec779b8eSAndroid Build Coastguard Worker 
setMediaDrmSession(const Vector<uint8_t> & sessionId)389*ec779b8eSAndroid Build Coastguard Worker DrmStatus CryptoHalHidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
390*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
391*ec779b8eSAndroid Build Coastguard Worker 
392*ec779b8eSAndroid Build Coastguard Worker     if (mInitCheck != OK) {
393*ec779b8eSAndroid Build Coastguard Worker         return mInitCheck;
394*ec779b8eSAndroid Build Coastguard Worker     }
395*ec779b8eSAndroid Build Coastguard Worker 
396*ec779b8eSAndroid Build Coastguard Worker     auto err = mPlugin->setMediaDrmSession(toHidlVec(sessionId));
397*ec779b8eSAndroid Build Coastguard Worker     return err.isOk() ? toStatusT(err) : DEAD_OBJECT;
398*ec779b8eSAndroid Build Coastguard Worker }
399*ec779b8eSAndroid Build Coastguard Worker 
getLogMessages(Vector<drm::V1_4::LogMessage> & logs) const400*ec779b8eSAndroid Build Coastguard Worker status_t CryptoHalHidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
401*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock autoLock(mLock);
402*ec779b8eSAndroid Build Coastguard Worker     return DrmUtils::GetLogMessages<drm::V1_4::ICryptoPlugin>(mPlugin, logs);
403*ec779b8eSAndroid Build Coastguard Worker }
404*ec779b8eSAndroid Build Coastguard Worker }  // namespace android
405