blob: f01ecb3568954ecae32c4c36f8ca41d3890f9304 [file] [log] [blame]
Kyle Zhang6605add2022-01-13 17:51:23 +00001/*
2 * Copyright (C) 2021 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_NDEBUG 0
18#define LOG_TAG "CryptoHalAidl"
19
20#include <aidlcommonsupport/NativeHandle.h>
21#include <android/binder_auto_utils.h>
22#include <android/binder_manager.h>
23#include <media/hardware/CryptoAPI.h>
24#include <media/stagefright/MediaErrors.h>
25#include <media/stagefright/foundation/ADebug.h>
26#include <media/stagefright/foundation/AString.h>
27#include <media/stagefright/foundation/hexdump.h>
28#include <mediadrm/CryptoHalAidl.h>
29#include <mediadrm/DrmUtils.h>
30
Kyle Zhang994023a2022-02-09 05:32:12 +000031using ::aidl::android::hardware::drm::CryptoSchemes;
Kyle Zhang6605add2022-01-13 17:51:23 +000032using DestinationBufferAidl = ::aidl::android::hardware::drm::DestinationBuffer;
33using ::aidl::android::hardware::drm::Mode;
34using ::aidl::android::hardware::drm::Pattern;
35using SharedBufferAidl = ::aidl::android::hardware::drm::SharedBuffer;
36using ::aidl::android::hardware::drm::Status;
37using ::aidl::android::hardware::drm::SubSample;
38using ::aidl::android::hardware::drm::Uuid;
Kyle Zhang994023a2022-02-09 05:32:12 +000039using ::aidl::android::hardware::drm::SecurityLevel;
40using NativeHandleAidlCommon = ::aidl::android::hardware::common::NativeHandle;
41using ::aidl::android::hardware::drm::DecryptArgs;
Kyle Zhang6605add2022-01-13 17:51:23 +000042
43using ::android::sp;
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +053044using ::android::DrmUtils::statusAidlToDrmStatus;
Kyle Zhang6605add2022-01-13 17:51:23 +000045using ::android::hardware::hidl_array;
46using ::android::hardware::hidl_handle;
47using ::android::hardware::hidl_memory;
48using ::android::hardware::hidl_string;
49using ::android::hardware::hidl_vec;
50using ::android::hardware::HidlMemory;
51using ::android::hardware::Return;
52using ::android::hardware::Void;
53
54using ::aidl::android::hardware::drm::Uuid;
55// -------Hidl interface related-----------------
56// TODO: replace before removing hidl interface
57
58using BufferTypeHidl = ::android::hardware::drm::V1_0::BufferType;
59using SharedBufferHidl = ::android::hardware::drm::V1_0::SharedBuffer;
60using DestinationBufferHidl = ::android::hardware::drm::V1_0::DestinationBuffer;
61
62// -------Hidl interface related end-------------
63
64namespace android {
65
Kyle Zhang6605add2022-01-13 17:51:23 +000066template <typename Byte = uint8_t>
67static std::vector<Byte> toStdVec(const Vector<uint8_t>& vector) {
68 auto v = reinterpret_cast<const Byte*>(vector.array());
69 std::vector<Byte> vec(v, v + vector.size());
70 return vec;
71}
72
73// -------Hidl interface related-----------------
74// TODO: replace before removing hidl interface
75status_t CryptoHalAidl::checkSharedBuffer(const SharedBufferHidl& buffer) {
76 int32_t seqNum = static_cast<int32_t>(buffer.bufferId);
77 // memory must be in one of the heaps that have been set
78 if (mHeapSizes.indexOfKey(seqNum) < 0) {
79 return UNKNOWN_ERROR;
80 }
81
82 // memory must be within the address space of the heap
83 size_t heapSize = mHeapSizes.valueFor(seqNum);
84 if (heapSize < buffer.offset + buffer.size || SIZE_MAX - buffer.offset < buffer.size) {
85 android_errorWriteLog(0x534e4554, "76221123");
86 return UNKNOWN_ERROR;
87 }
88
89 return OK;
90}
91
92static SharedBufferAidl hidlSharedBufferToAidlSharedBuffer(const SharedBufferHidl& buffer) {
93 SharedBufferAidl aidlsb;
94 aidlsb.bufferId = buffer.bufferId;
95 aidlsb.offset = buffer.offset;
96 aidlsb.size = buffer.size;
97 return aidlsb;
98}
99
100static DestinationBufferAidl hidlDestinationBufferToAidlDestinationBuffer(
101 const DestinationBufferHidl& buffer) {
102 DestinationBufferAidl aidldb;
103 // skip negative convert check as count of enum elements are 2
Kyle Zhang994023a2022-02-09 05:32:12 +0000104 switch(buffer.type) {
105 case BufferTypeHidl::SHARED_MEMORY:
106 aidldb.set<DestinationBufferAidl::Tag::nonsecureMemory>(
107 hidlSharedBufferToAidlSharedBuffer(buffer.nonsecureMemory));
108 break;
109 default:
110 auto handle = buffer.secureMemory.getNativeHandle();
111 if (handle) {
112 aidldb.set<DestinationBufferAidl::Tag::secureMemory>(
Robert Shihfc5d61d2022-02-15 23:06:48 -0800113 ::android::dupToAidl(handle));
Kyle Zhang994023a2022-02-09 05:32:12 +0000114 } else {
115 NativeHandleAidlCommon emptyhandle;
116 aidldb.set<DestinationBufferAidl::Tag::secureMemory>(
117 std::move(emptyhandle));
118 }
119 break;
Robert Shihcc4a2ce2022-02-03 08:27:08 -0800120 }
Kyle Zhang994023a2022-02-09 05:32:12 +0000121
Kyle Zhang6605add2022-01-13 17:51:23 +0000122 return aidldb;
123}
124
125static hidl_vec<uint8_t> toHidlVec(const void* ptr, size_t size) {
126 hidl_vec<uint8_t> vec;
127 vec.resize(size);
128 memcpy(vec.data(), ptr, size);
129 return vec;
130}
131
132static const Vector<uint8_t> toVector(const std::vector<uint8_t>& vec) {
133 Vector<uint8_t> vector;
134 vector.appendArray(vec.data(), vec.size());
135 return *const_cast<const Vector<uint8_t>*>(&vector);
136}
137
138static String8 toString8(const std::string& string) {
139 return String8(string.c_str());
140}
141
Robert Shihcc4a2ce2022-02-03 08:27:08 -0800142static std::vector<uint8_t> toStdVec(const uint8_t* ptr, size_t n) {
143 if (!ptr) {
144 return std::vector<uint8_t>();
145 }
146 return std::vector<uint8_t>(ptr, ptr + n);
147}
148
Kyle Zhang6605add2022-01-13 17:51:23 +0000149// -------Hidl interface related end--------------
150
Kyle Zhang994023a2022-02-09 05:32:12 +0000151bool CryptoHalAidl::isCryptoSchemeSupportedInternal(const uint8_t uuid[16], int* factoryIdx) {
152 Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
153 for (size_t i = 0; i < mFactories.size(); i++) {
154 CryptoSchemes schemes{};
155 if (mFactories[i]->getSupportedCryptoSchemes(&schemes).isOk()) {
156 if (std::count(schemes.uuids.begin(), schemes.uuids.end(), uuidAidl)) {
157 if (factoryIdx != NULL) *factoryIdx = i;
158 return true;
159 }
160 }
161 }
162
163 return false;
164}
165
Kyle Zhang6605add2022-01-13 17:51:23 +0000166CryptoHalAidl::CryptoHalAidl()
Kyle Zhang994023a2022-02-09 05:32:12 +0000167 : mFactories(DrmUtils::makeDrmFactoriesAidl()),
Kyle Zhang6605add2022-01-13 17:51:23 +0000168 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
169 mHeapSeqNum(0) {}
170
171CryptoHalAidl::~CryptoHalAidl() {}
172
Kyle Zhang6605add2022-01-13 17:51:23 +0000173status_t CryptoHalAidl::initCheck() const {
174 return mInitCheck;
175}
176
177bool CryptoHalAidl::isCryptoSchemeSupported(const uint8_t uuid[16]) {
178 Mutex::Autolock autoLock(mLock);
179
Kyle Zhang994023a2022-02-09 05:32:12 +0000180 return isCryptoSchemeSupportedInternal(uuid, NULL);
Kyle Zhang6605add2022-01-13 17:51:23 +0000181}
182
183status_t CryptoHalAidl::createPlugin(const uint8_t uuid[16], const void* data, size_t size) {
184 Mutex::Autolock autoLock(mLock);
185
Kyle Zhang994023a2022-02-09 05:32:12 +0000186 Uuid uuidAidl = DrmUtils::toAidlUuid(uuid);
Kyle Zhang6605add2022-01-13 17:51:23 +0000187 std::vector<uint8_t> dataAidl = toStdVec(toVector(toHidlVec(data, size)));
Kyle Zhang994023a2022-02-09 05:32:12 +0000188 int i = 0;
189 if (isCryptoSchemeSupportedInternal(uuid, &i)) {
190 mPlugin = makeCryptoPlugin(mFactories[i], uuidAidl, dataAidl);
Kyle Zhang6605add2022-01-13 17:51:23 +0000191 }
192
193 if (mInitCheck == NO_INIT) {
194 mInitCheck = mPlugin == NULL ? ERROR_UNSUPPORTED : OK;
195 }
196
197 return mInitCheck;
198}
199
200std::shared_ptr<ICryptoPluginAidl> CryptoHalAidl::makeCryptoPlugin(
Kyle Zhang994023a2022-02-09 05:32:12 +0000201 const std::shared_ptr<IDrmFactoryAidl>& factory, const Uuid& uuidAidl,
Kyle Zhang6605add2022-01-13 17:51:23 +0000202 const std::vector<uint8_t> initData) {
203 std::shared_ptr<ICryptoPluginAidl> pluginAidl;
Kyle Zhang994023a2022-02-09 05:32:12 +0000204 if (factory->createCryptoPlugin(uuidAidl, initData, &pluginAidl).isOk()) {
Kyle Zhang6605add2022-01-13 17:51:23 +0000205 ALOGI("Create ICryptoPluginAidl. UUID:[%s]", uuidAidl.toString().c_str());
206 } else {
207 mInitCheck = DEAD_OBJECT;
208 ALOGE("Failed to create ICryptoPluginAidl. UUID:[%s]", uuidAidl.toString().c_str());
209 }
210
211 return pluginAidl;
212}
213
214status_t CryptoHalAidl::destroyPlugin() {
215 Mutex::Autolock autoLock(mLock);
216
217 if (mInitCheck != OK) {
218 return mInitCheck;
219 }
220
221 mPlugin.reset();
Kyle Zhang337b9152022-05-16 22:39:33 +0000222 mInitCheck = NO_INIT;
Kyle Zhang6605add2022-01-13 17:51:23 +0000223 return OK;
224}
225
226bool CryptoHalAidl::requiresSecureDecoderComponent(const char* mime) const {
227 Mutex::Autolock autoLock(mLock);
228
229 if (mInitCheck != OK) {
230 return false;
231 }
232
233 std::string mimeStr = std::string(mime);
234 bool result;
235 if (!mPlugin->requiresSecureDecoderComponent(mimeStr, &result).isOk()) {
236 ALOGE("Failed to requiresSecureDecoderComponent. mime:[%s]", mime);
237 return false;
238 }
239
240 return result;
241}
242
243void CryptoHalAidl::notifyResolution(uint32_t width, uint32_t height) {
244 Mutex::Autolock autoLock(mLock);
245
246 if (mInitCheck != OK) {
247 return;
248 }
249
250 // Check negative width and height after type conversion
251 // Log error and return if any is negative
252 if ((int32_t)width < 0 || (int32_t)height < 0) {
253 ALOGE("Negative width: %d or height %d in notifyResolution", width, height);
254 return;
255 }
256
257 ::ndk::ScopedAStatus status = mPlugin->notifyResolution(width, height);
258 if (!status.isOk()) {
259 ALOGE("notifyResolution txn failed status code: %d", status.getServiceSpecificError());
260 }
261}
262
263status_t CryptoHalAidl::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
264 Mutex::Autolock autoLock(mLock);
265
266 if (mInitCheck != OK) {
267 return mInitCheck;
268 }
269
270 auto err = mPlugin->setMediaDrmSession(toStdVec(sessionId));
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530271 return statusAidlToDrmStatus(err);
Kyle Zhang6605add2022-01-13 17:51:23 +0000272}
273
274ssize_t CryptoHalAidl::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
275 CryptoPlugin::Mode mode, const CryptoPlugin::Pattern& pattern,
276 const SharedBufferHidl& hSource, size_t offset,
277 const CryptoPlugin::SubSample* subSamples, size_t numSubSamples,
278 const DestinationBufferHidl& hDestination, AString* errorDetailMsg) {
279 Mutex::Autolock autoLock(mLock);
280
281 if (mInitCheck != OK) {
282 return mInitCheck;
283 }
284
285 Mode aMode;
286 switch (mode) {
287 case CryptoPlugin::kMode_Unencrypted:
288 aMode = Mode::UNENCRYPTED;
289 break;
290 case CryptoPlugin::kMode_AES_CTR:
291 aMode = Mode::AES_CTR;
292 break;
293 case CryptoPlugin::kMode_AES_WV:
294 aMode = Mode::AES_CBC_CTS;
295 break;
296 case CryptoPlugin::kMode_AES_CBC:
297 aMode = Mode::AES_CBC;
298 break;
299 default:
300 return UNKNOWN_ERROR;
301 }
302
303 Pattern aPattern;
304 aPattern.encryptBlocks = pattern.mEncryptBlocks;
305 aPattern.skipBlocks = pattern.mSkipBlocks;
306
307 std::vector<SubSample> stdSubSamples;
308 for (size_t i = 0; i < numSubSamples; i++) {
309 SubSample subSample;
310 subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
311 subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
312 stdSubSamples.push_back(subSample);
313 }
314
315 bool secure;
316 if (hDestination.type == BufferTypeHidl::SHARED_MEMORY) {
317 status_t status = checkSharedBuffer(hDestination.nonsecureMemory);
318 if (status != OK) {
319 return status;
320 }
321 secure = false;
322 } else if (hDestination.type == BufferTypeHidl::NATIVE_HANDLE) {
323 secure = true;
324 } else {
325 android_errorWriteLog(0x534e4554, "70526702");
326 return UNKNOWN_ERROR;
327 }
328
329 status_t status = checkSharedBuffer(hSource);
330 if (status != OK) {
331 return status;
332 }
333
334 status_t err = UNKNOWN_ERROR;
335 mLock.unlock();
336
Robert Shihcc4a2ce2022-02-03 08:27:08 -0800337 std::vector<uint8_t> keyIdAidl(toStdVec(keyId, 16));
338 std::vector<uint8_t> ivAidl(toStdVec(iv, 16));
Kyle Zhang994023a2022-02-09 05:32:12 +0000339
340 DecryptArgs args;
341 args.secure = secure;
342 args.keyId = keyIdAidl;
343 args.iv = ivAidl;
344 args.mode = aMode;
345 args.pattern = aPattern;
346 args.subSamples = std::move(stdSubSamples);
347 args.source = hidlSharedBufferToAidlSharedBuffer(hSource);
348 args.offset = offset;
349 args.destination = hidlDestinationBufferToAidlDestinationBuffer(hDestination);
350
351
352 int32_t result = 0;
353 ::ndk::ScopedAStatus statusAidl = mPlugin->decrypt(args, &result);
Kyle Zhang6605add2022-01-13 17:51:23 +0000354
Sohail Nagaraj0cc3da82022-11-30 10:22:37 +0530355 err = statusAidlToDrmStatus(statusAidl);
Kyle Zhang994023a2022-02-09 05:32:12 +0000356 std::string msgStr(statusAidl.getMessage());
Ray Essickca0ee602022-03-09 14:14:58 -0800357 if (errorDetailMsg != nullptr) {
358 *errorDetailMsg = toString8(msgStr);
359 }
Kyle Zhang6605add2022-01-13 17:51:23 +0000360 if (err != OK) {
Robert Shih06a2bab2022-02-14 14:07:41 -0800361 ALOGE("Failed on decrypt, error description:%s", statusAidl.getDescription().c_str());
Kyle Zhang6605add2022-01-13 17:51:23 +0000362 return err;
363 }
364
Kyle Zhang994023a2022-02-09 05:32:12 +0000365 return result;
Kyle Zhang6605add2022-01-13 17:51:23 +0000366}
367
368int32_t CryptoHalAidl::setHeap(const sp<HidlMemory>& heap) {
369 if (heap == NULL || mHeapSeqNum < 0) {
370 ALOGE("setHeap(): heap %p mHeapSeqNum %d", heap.get(), mHeapSeqNum);
371 return -1;
372 }
373
374 Mutex::Autolock autoLock(mLock);
375
Kyle Zhang337b9152022-05-16 22:39:33 +0000376 if (mInitCheck != OK) {
377 return -1;
378 }
379
Kyle Zhang6605add2022-01-13 17:51:23 +0000380 int32_t seqNum = mHeapSeqNum++;
381 uint32_t bufferId = static_cast<uint32_t>(seqNum);
382 mHeapSizes.add(seqNum, heap->size());
383
Kyle Zhang994023a2022-02-09 05:32:12 +0000384 SharedBufferAidl memAidl;
Robert Shiha7799d22022-02-17 22:22:56 +0000385 memAidl.handle = ::android::dupToAidl(heap->handle());
Kyle Zhang6605add2022-01-13 17:51:23 +0000386 memAidl.size = heap->size();
Kyle Zhang994023a2022-02-09 05:32:12 +0000387 memAidl.bufferId = bufferId;
Kyle Zhang6605add2022-01-13 17:51:23 +0000388
Kyle Zhang994023a2022-02-09 05:32:12 +0000389 auto status = mPlugin->setSharedBufferBase(memAidl);
390 ALOGE_IF(!status.isOk(),
Kyle Zhang6605add2022-01-13 17:51:23 +0000391 "setSharedBufferBase(): remote call failed");
392 return seqNum;
393}
394
395void CryptoHalAidl::unsetHeap(int32_t seqNum) {
396 Mutex::Autolock autoLock(mLock);
397
398 /*
399 * Clear the remote shared memory mapping by setting the shared
400 * buffer base to a null hidl_memory.
401 *
402 * TODO: Add a releaseSharedBuffer method in a future DRM HAL
403 * API version to make this explicit.
404 */
405 ssize_t index = mHeapSizes.indexOfKey(seqNum);
406 if (index >= 0) {
407 if (mPlugin != NULL) {
408 uint32_t bufferId = static_cast<uint32_t>(seqNum);
Kyle Zhang994023a2022-02-09 05:32:12 +0000409 SharedBufferAidl memAidl{};
410 memAidl.bufferId = bufferId;
411 auto status = mPlugin->setSharedBufferBase(memAidl);
412 ALOGE_IF(!status.isOk(),
Kyle Zhang6605add2022-01-13 17:51:23 +0000413 "setSharedBufferBase(): remote call failed");
414 }
415 mHeapSizes.removeItem(seqNum);
416 }
417}
418
419status_t CryptoHalAidl::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
420 Mutex::Autolock autoLock(mLock);
421 // Need to convert logmessage
422
Kyle Zhang96af9572022-02-05 06:38:53 +0000423 return DrmUtils::GetLogMessagesAidl<ICryptoPluginAidl>(mPlugin, logs);
Kyle Zhang6605add2022-01-13 17:51:23 +0000424}
Ray Essickca0ee602022-03-09 14:14:58 -0800425} // namespace android