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