blob: 8dea7e9324a8f7d69b983c753811fb88ba5bcd36 [file] [log] [blame]
Jeff Tinkerb075caa2016-12-06 23:15:20 -08001/*
2 * Copyright (C) 2016 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 */
Jeff Tinker972a3e32017-01-23 14:02:50 -080016#define LOG_TAG "android.hardware.drm@1.0-impl"
Jeff Tinkerb075caa2016-12-06 23:15:20 -080017
18#include "CryptoPlugin.h"
19#include "TypeConvert.h"
20
Jeff Tinkerb075caa2016-12-06 23:15:20 -080021#include <android/hidl/memory/1.0/IMemory.h>
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080022#include <hidlmemory/mapping.h>
Steven Moreland3eb7df72017-04-06 12:15:23 -070023#include <log/log.h>
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080024#include <media/stagefright/foundation/AString.h>
Jeff Tinkerb075caa2016-12-06 23:15:20 -080025
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080026using android::hardware::hidl_memory;
Jeff Tinkerb075caa2016-12-06 23:15:20 -080027using android::hidl::memory::V1_0::IMemory;
28
Jeff Tinkerb075caa2016-12-06 23:15:20 -080029namespace android {
30namespace hardware {
31namespace drm {
Jeff Tinkerb075caa2016-12-06 23:15:20 -080032namespace V1_0 {
33namespace implementation {
34
Jeff Tinkerda002fe2017-01-19 14:41:11 -080035 // Methods from ::android::hardware::drm::V1_0::ICryptoPlugin follow
Jeff Tinkerb075caa2016-12-06 23:15:20 -080036 Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
37 const hidl_string& mime) {
Scott Randolph89978802017-04-03 14:06:19 -070038 return mLegacyPlugin->requiresSecureDecoderComponent(mime.c_str());
Jeff Tinkerb075caa2016-12-06 23:15:20 -080039 }
40
41 Return<void> CryptoPlugin::notifyResolution(uint32_t width,
42 uint32_t height) {
43 mLegacyPlugin->notifyResolution(width, height);
44 return Void();
45 }
46
47 Return<Status> CryptoPlugin::setMediaDrmSession(
48 const hidl_vec<uint8_t>& sessionId) {
49 return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
50 }
51
Jeff Tinker0b3f41e2017-02-16 12:20:30 -080052 Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
53 uint32_t bufferId) {
Edwin Wong3b8a9ed2017-07-17 09:53:31 -070054 sp<IMemory> hidlMemory = mapMemory(base);
Edwin Wong3b8a9ed2017-07-17 09:53:31 -070055
Edwin Wong989975e2021-03-08 18:46:42 -080056 std::lock_guard<std::mutex> shared_buffer_lock(mSharedBufferLock);
57
Edwin Wong3b8a9ed2017-07-17 09:53:31 -070058 // allow mapMemory to return nullptr
59 mSharedBufferMap[bufferId] = hidlMemory;
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080060 return Void();
61 }
62
Jeff Tinkerb075caa2016-12-06 23:15:20 -080063 Return<void> CryptoPlugin::decrypt(bool secure,
64 const hidl_array<uint8_t, 16>& keyId,
65 const hidl_array<uint8_t, 16>& iv, Mode mode,
66 const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
Jeff Tinkerda002fe2017-01-19 14:41:11 -080067 const SharedBuffer& source, uint64_t offset,
Jeff Tinker6fdbe862017-01-11 19:45:23 -080068 const DestinationBuffer& destination,
Jeff Tinkerb075caa2016-12-06 23:15:20 -080069 decrypt_cb _hidl_cb) {
Edwin Wong989975e2021-03-08 18:46:42 -080070 std::unique_lock<std::mutex> shared_buffer_lock(mSharedBufferLock);
Jeff Tinker0b3f41e2017-02-16 12:20:30 -080071 if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
72 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set");
Jeff Tinkerdc8e2d02017-01-23 14:24:12 -080073 return Void();
74 }
75
Jeff Tinker0b3f41e2017-02-16 12:20:30 -080076 if (destination.type == BufferType::SHARED_MEMORY) {
77 const SharedBuffer& dest = destination.nonsecureMemory;
78 if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
79 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set");
80 return Void();
81 }
82 }
83
Edwin Wonge55db242021-02-02 22:28:41 -080084 android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted;
Jeff Tinkerb075caa2016-12-06 23:15:20 -080085 switch(mode) {
86 case Mode::UNENCRYPTED:
87 legacyMode = android::CryptoPlugin::kMode_Unencrypted;
88 break;
89 case Mode::AES_CTR:
90 legacyMode = android::CryptoPlugin::kMode_AES_CTR;
91 break;
92 case Mode::AES_CBC_CTS:
93 legacyMode = android::CryptoPlugin::kMode_AES_WV;
94 break;
95 case Mode::AES_CBC:
96 legacyMode = android::CryptoPlugin::kMode_AES_CBC;
97 break;
98 }
99 android::CryptoPlugin::Pattern legacyPattern;
100 legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
101 legacyPattern.mSkipBlocks = pattern.skipBlocks;
102
Jeff Tinker5fee1822018-01-05 11:18:00 -0800103 std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples =
104 std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size());
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800105
Robert Shih1e188832019-09-11 14:10:14 -0700106 size_t destSize = 0;
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800107 for (size_t i = 0; i < subSamples.size(); i++) {
Robert Shih1e188832019-09-11 14:10:14 -0700108 uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData;
109 legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData;
110 uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData;
111 legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData;
112 if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) {
113 _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
114 return Void();
115 }
116 if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) {
117 _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
118 return Void();
119 }
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800120 }
121
122 AString detailMessage;
Jeff Tinker0b3f41e2017-02-16 12:20:30 -0800123 sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
Edwin Wong3b8a9ed2017-07-17 09:53:31 -0700124 if (sourceBase == nullptr) {
125 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
126 return Void();
127 }
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800128
Edwin Wongc14f2622021-01-26 20:29:25 -0800129 size_t totalSize = 0;
130 if (__builtin_add_overflow(source.offset, offset, &totalSize) ||
131 __builtin_add_overflow(totalSize, source.size, &totalSize) ||
132 totalSize > sourceBase->getSize()) {
133 android_errorWriteLog(0x534e4554, "176496160");
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800134 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
135 return Void();
136 }
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800137
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800138 uint8_t *base = static_cast<uint8_t *>
Jeff Tinker0b3f41e2017-02-16 12:20:30 -0800139 (static_cast<void *>(sourceBase->getPointer()));
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800140 void *srcPtr = static_cast<void *>(base + source.offset + offset);
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800141
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800142 void *destPtr = NULL;
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800143 if (destination.type == BufferType::SHARED_MEMORY) {
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800144 const SharedBuffer& destBuffer = destination.nonsecureMemory;
Jeff Tinker0b3f41e2017-02-16 12:20:30 -0800145 sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
Edwin Wong3b8a9ed2017-07-17 09:53:31 -0700146 if (destBase == nullptr) {
147 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
148 return Void();
149 }
150
Edwin Wonge55db242021-02-02 22:28:41 -0800151 size_t totalSize = 0;
152 if (__builtin_add_overflow(destBuffer.offset, destBuffer.size, &totalSize) ||
153 totalSize > destBase->getSize()) {
154 android_errorWriteLog(0x534e4554, "176496353");
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800155 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
156 return Void();
157 }
Robert Shih1e188832019-09-11 14:10:14 -0700158
159 if (destSize > destBuffer.size) {
160 _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
161 return Void();
162 }
163
Robert Shihd79abbb2019-11-17 23:54:21 -0800164 base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer()));
Edwin Wonge55db242021-02-02 22:28:41 -0800165 destPtr = static_cast<void*>(base + destination.nonsecureMemory.offset);
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800166 } else if (destination.type == BufferType::NATIVE_HANDLE) {
Robert Shih1e188832019-09-11 14:10:14 -0700167 if (!secure) {
168 _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure");
169 return Void();
170 }
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800171 native_handle_t *handle = const_cast<native_handle_t *>(
172 destination.secureMemory.getNativeHandle());
173 destPtr = static_cast<void *>(handle);
Robert Shih1e188832019-09-11 14:10:14 -0700174 } else {
175 _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type");
176 return Void();
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800177 }
Edwin Wong989975e2021-03-08 18:46:42 -0800178
179 // release mSharedBufferLock
180 shared_buffer_lock.unlock();
181
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800182 ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
Jeff Tinker5fee1822018-01-05 11:18:00 -0800183 legacyMode, legacyPattern, srcPtr, legacySubSamples.get(),
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800184 subSamples.size(), destPtr, &detailMessage);
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800185
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800186 uint32_t status;
187 uint32_t bytesWritten;
188
189 if (result >= 0) {
190 status = android::OK;
191 bytesWritten = result;
192 } else {
Rahul Friasabd4e112017-02-27 19:17:30 -0800193 status = result;
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800194 bytesWritten = 0;
195 }
196
Jeff Tinker01f0a5a2017-01-12 09:22:18 -0800197 _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800198 return Void();
199 }
200
201} // namespace implementation
202} // namespace V1_0
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800203} // namespace drm
204} // namespace hardware
205} // namespace android