1 /*
2 * Copyright 2022 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 "CryptoAsync"
19
20 #include <log/log.h>
21
22 #include "hidl/HidlSupport.h"
23 #include <media/stagefright/foundation/AMessage.h>
24 #include <media/stagefright/foundation/ABuffer.h>
25 #include <media/stagefright/foundation/ADebug.h>
26
27 #include <media/MediaCodecBuffer.h>
28 #include <media/stagefright/MediaCodec.h>
29 #include <media/stagefright/CryptoAsync.h>
30
31 namespace android {
32
CryptoAsyncInfo(const std::unique_ptr<CodecCryptoInfo> & info)33 CryptoAsync::CryptoAsyncInfo::CryptoAsyncInfo(const std::unique_ptr<CodecCryptoInfo> &info) {
34 if (info == nullptr) {
35 return;
36 }
37 size_t key_len = (info->mKey != nullptr)? 16 : 0;
38 size_t iv_len = (info->mIv != nullptr)? 16 : 0;
39 mNumSubSamples = info->mNumSubSamples;
40 mMode = info->mMode;
41 mPattern = info->mPattern;
42 if (key_len > 0) {
43 mKeyBuffer = ABuffer::CreateAsCopy((void*)info->mKey, key_len);
44 mKey = (uint8_t*)(mKeyBuffer.get() != nullptr ? mKeyBuffer.get()->data() : nullptr);
45 }
46 if (iv_len > 0) {
47 mIvBuffer = ABuffer::CreateAsCopy((void*)info->mIv, iv_len);
48 mIv = (uint8_t*)(mIvBuffer.get() != nullptr ? mIvBuffer.get()->data() : nullptr);
49 }
50 mSubSamplesBuffer =
51 new ABuffer(sizeof(CryptoPlugin::SubSample) * mNumSubSamples);
52 if (mSubSamplesBuffer.get()) {
53 CryptoPlugin::SubSample * samples =
54 (CryptoPlugin::SubSample *)(mSubSamplesBuffer.get()->data());
55 for (int s = 0 ; s < mNumSubSamples ; s++) {
56 samples[s].mNumBytesOfClearData = info->mSubSamples[s].mNumBytesOfClearData;
57 samples[s].mNumBytesOfEncryptedData = info->mSubSamples[s].mNumBytesOfEncryptedData;
58 }
59 mSubSamples = (CryptoPlugin::SubSample *)mSubSamplesBuffer.get()->data();
60 }
61 }
62
~CryptoAsync()63 CryptoAsync::~CryptoAsync() {
64 }
65
decrypt(sp<AMessage> & msg)66 status_t CryptoAsync::decrypt(sp<AMessage> &msg) {
67 int32_t decryptAction;
68 CHECK(msg->findInt32("action", &decryptAction));
69 if (mCallback == nullptr) {
70 ALOGE("Crypto callback channel is not set");
71 return -ENOSYS;
72 }
73 bool shouldPost = false;
74 Mutexed<std::list<sp<AMessage>>>::Locked pendingBuffers(mPendingBuffers);
75 if (mState != kCryptoAsyncActive) {
76 ALOGE("Cannot decrypt in errored state");
77 return -ENOSYS;
78 }
79 shouldPost = pendingBuffers->size() == 0 ? true : false;
80 pendingBuffers->push_back(std::move(msg));
81 if (shouldPost) {
82 sp<AMessage> decryptMsg = new AMessage(kWhatDecrypt, this);
83 decryptMsg->post();
84 }
85 return OK;
86 }
87
stop(std::list<sp<AMessage>> * const buffers)88 void CryptoAsync::stop(std::list<sp<AMessage>> * const buffers) {
89 sp<AMessage> stopMsg = new AMessage(kWhatStop, this);
90 stopMsg->setPointer("remaining", static_cast<void*>(buffers));
91 sp<AMessage> response;
92 status_t err = stopMsg->postAndAwaitResponse(&response);
93 if (err == OK && response != NULL) {
94 CHECK(response->findInt32("err", &err));
95 } else {
96 ALOGE("Error handling stop in CryptoAsync");
97 //TODO: handle the error here.
98 }
99 }
100
decryptAndQueue(sp<AMessage> & msg)101 status_t CryptoAsync::decryptAndQueue(sp<AMessage> & msg) {
102 std::shared_ptr<BufferChannelBase> channel = mBufferChannel.lock();
103 status_t err = OK;
104 sp<RefBase> obj;
105 size_t numSubSamples = 0;
106 int32_t secure = 0;
107 CryptoPlugin::Mode mode;
108 CryptoPlugin::Pattern pattern;
109 sp<ABuffer> keyBuffer;
110 sp<ABuffer> ivBuffer;
111 sp<ABuffer> subSamplesBuffer;
112 AString errorDetailMsg;
113 msg->findObject("buffer", &obj);
114 msg->findInt32("secure", &secure);
115 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
116 if (buffer->meta()->findObject("cryptoInfos", &obj)) {
117 err = channel->queueSecureInputBuffers(buffer, secure, &errorDetailMsg);
118 } else {
119 msg->findInt32("encryptBlocks", (int32_t*)&pattern.mEncryptBlocks);
120 msg->findInt32("skipBlocks", (int32_t*)&pattern.mSkipBlocks);
121 msg->findBuffer("key", &keyBuffer);
122 msg->findBuffer("iv", &ivBuffer);
123 msg->findBuffer("subSamples", &subSamplesBuffer);
124 msg->findSize("numSubSamples", &numSubSamples);
125 msg->findInt32("mode", (int32_t*)&mode);
126 const uint8_t * key = keyBuffer.get() != nullptr ? keyBuffer.get()->data() : nullptr;
127 const uint8_t * iv = ivBuffer.get() != nullptr ? ivBuffer.get()->data() : nullptr;
128 const CryptoPlugin::SubSample * subSamples =
129 (CryptoPlugin::SubSample *)(subSamplesBuffer.get()->data());
130 err = channel->queueSecureInputBuffer(buffer, secure, key, iv, mode,
131 pattern, subSamples, numSubSamples, &errorDetailMsg);
132 }
133 if (err != OK) {
134 std::list<sp<AMessage>> errorList;
135 msg->removeEntryByName("buffer");
136 msg->setInt32("err", err);
137 msg->setInt32("actionCode", ACTION_CODE_FATAL);
138 msg->setString("errorDetail", errorDetailMsg);
139 errorList.push_back(std::move(msg));
140 mCallback->onDecryptError(errorList);
141 }
142 return err;
143 }
144
attachEncryptedBufferAndQueue(sp<AMessage> & msg)145 status_t CryptoAsync::attachEncryptedBufferAndQueue(sp<AMessage> & msg) {
146 std::shared_ptr<BufferChannelBase> channel = mBufferChannel.lock();
147 status_t err = OK;
148 sp<RefBase> obj;
149 sp<RefBase> mem_obj;
150 sp<hardware::HidlMemory> memory;
151 size_t numSubSamples = 0;
152 int32_t secure = 0;
153 size_t offset;
154 size_t size;
155 CryptoPlugin::Mode mode;
156 CryptoPlugin::Pattern pattern;
157 sp<ABuffer> keyBuffer;
158 sp<ABuffer> ivBuffer;
159 sp<ABuffer> subSamplesBuffer;
160 msg->findInt32("encryptBlocks", (int32_t*)&pattern.mEncryptBlocks);
161 msg->findInt32("skipBlocks", (int32_t*)&pattern.mSkipBlocks);
162 msg->findBuffer("key", &keyBuffer);
163 msg->findBuffer("iv", &ivBuffer);
164 msg->findBuffer("subSamples", &subSamplesBuffer);
165 msg->findInt32("secure", &secure);
166 msg->findSize("numSubSamples", &numSubSamples);
167 msg->findObject("buffer", &obj);
168 msg->findInt32("mode", (int32_t*)&mode);
169 CHECK(msg->findObject("memory", &mem_obj));
170 CHECK(msg->findSize("offset", (size_t*)&offset));
171 AString errorDetailMsg;
172 // get key info
173 const uint8_t * key = keyBuffer.get() != nullptr ? keyBuffer.get()->data() : nullptr;
174 // get iv info
175 const uint8_t * iv = ivBuffer.get() != nullptr ? ivBuffer.get()->data() : nullptr;
176
177 const CryptoPlugin::SubSample * subSamples =
178 (CryptoPlugin::SubSample *)(subSamplesBuffer.get()->data());
179
180 // get MediaCodecBuffer
181 sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
182
183 // get HidlMemory
184 memory = static_cast<MediaCodec::WrapperObject<sp<hardware::HidlMemory>> *>
185 (mem_obj.get())->value;
186
187 // attach buffer
188 err = channel->attachEncryptedBuffer(
189 memory, secure, key, iv, mode, pattern,
190 offset, subSamples, numSubSamples, buffer, &errorDetailMsg);
191
192 // a generic error
193 auto handleError = [this, &err, &msg]() {
194 std::list<sp<AMessage>> errorList;
195 msg->removeEntryByName("buffer");
196 msg->setInt32("err", err);
197 msg->setInt32("actionCode", ACTION_CODE_FATAL);
198 errorList.push_back(std::move(msg));
199 mCallback->onDecryptError(errorList);
200 };
201 if (err != OK) {
202 handleError();
203 return err;
204 }
205 offset = buffer->offset();
206 size = buffer->size();
207
208 if (offset + size > buffer->capacity()) {
209 err = -ENOSYS;
210 handleError();
211 return err;
212 }
213 buffer->setRange(offset, size);
214 err = channel->queueInputBuffer(buffer);
215 if (err != OK) {
216 handleError();
217 return err;
218 }
219 return err;
220 }
221
onMessageReceived(const sp<AMessage> & msg)222 void CryptoAsync::onMessageReceived(const sp<AMessage> & msg) {
223 status_t err = OK;
224 auto getCurrentAndNextTask =
225 [this](sp<AMessage> * const current, uint32_t & nextTask) -> status_t {
226 sp<AMessage> obj;
227 Mutexed<std::list<sp<AMessage>>>::Locked pendingBuffers(mPendingBuffers);
228 if ((pendingBuffers->size() == 0) || (mState != kCryptoAsyncActive)) {
229 return -ENOMSG;
230 }
231 *current = std::move(*(pendingBuffers->begin()));
232 pendingBuffers->pop_front();
233 //Try to see if we will be able to process next buffer
234 while((nextTask == kWhatDoNothing) && pendingBuffers->size() > 0)
235 {
236 sp<AMessage> & nextBuffer = pendingBuffers->front();
237 if (nextBuffer == nullptr) {
238 pendingBuffers->pop_front();
239 continue;
240 }
241 nextTask = kWhatDecrypt;
242 }
243 return OK;
244 };
245 switch(msg->what()) {
246 case kWhatDecrypt:
247 {
248 sp<AMessage> thisMsg;
249 uint32_t nextTask = kWhatDoNothing;
250 if(OK != getCurrentAndNextTask(&thisMsg, nextTask)) {
251 return;
252 }
253 if (thisMsg != nullptr) {
254 int32_t action;
255 err = OK;
256 CHECK(thisMsg->findInt32("action", &action));
257 switch(action) {
258 case kActionDecrypt:
259 {
260 err = decryptAndQueue(thisMsg);
261 break;
262 }
263
264 case kActionAttachEncryptedBuffer:
265 {
266 err = attachEncryptedBufferAndQueue(thisMsg);
267 break;
268 }
269
270 default:
271 {
272 ALOGE("Unrecognized action in decrypt");
273 }
274 }
275 if (err != OK) {
276 Mutexed<std::list<sp<AMessage>>>::Locked pendingBuffers(mPendingBuffers);
277 mState = kCryptoAsyncError;
278 }
279 }
280 // we won't take next buffers if buffer caused
281 // an error. We want the caller to deal with the error first
282 // Expected behahiour is that the caller acknowledge the error
283 // with a call to stop() which clear the queues.
284 // Then move forward with processing of next set of buffers.
285 if (mState == kCryptoAsyncActive && nextTask != kWhatDoNothing) {
286 sp<AMessage> nextMsg = new AMessage(nextTask,this);
287 nextMsg->post();
288 }
289 break;
290 }
291
292 case kWhatStop:
293 {
294 typedef std::list<sp<AMessage>> ReturnListType;
295 ReturnListType * returnList = nullptr;
296 sp<AReplyToken> replyID;
297 CHECK(msg->senderAwaitsResponse(&replyID));
298 sp<AMessage> response = new AMessage;
299 msg->findPointer("remaining", (void**)(&returnList));
300 Mutexed<std::list<sp<AMessage>>>::Locked pendingBuffers(mPendingBuffers);
301 if (returnList) {
302 returnList->clear();
303 returnList->splice(returnList->end(), std::move(*pendingBuffers));
304 }
305 pendingBuffers->clear();
306 mState = kCryptoAsyncActive;
307 response->setInt32("err", OK);
308 response->postReply(replyID);
309
310 break;
311 }
312
313 default:
314 {
315 status_t err = OK;
316 //TODO: do something with error here.
317 (void)err;
318 break;
319 }
320 }
321 }
322
323 } // namespace android
324