1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "codec_drm_decrypt.h"
17 #include "avcodec_errors.h"
18 #include "avcodec_log.h"
19 #include "securec.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "CodecServer"};
23 } // namespace
24
25 namespace OHOS {
26 namespace MediaAVCodec {
27
28 #define DRM_VIDEO_FRAME_ARR_LEN 3
29 #define DRM_AMBIGUITY_ARR_LEN 3
30 constexpr uint32_t DRM_LEGACY_LEN = 3;
31 constexpr uint32_t DRM_AES_BLOCK_SIZE = 16;
32 constexpr uint8_t DRM_AMBIGUITY_START_NUM = 0x00;
33 constexpr uint8_t DRM_AMBIGUITY_END_NUM = 0x03;
34 constexpr uint32_t DRM_TS_FLAG_CRYPT_BYTE_BLOCK = 2;
35 constexpr uint32_t DRM_CRYPT_BYTE_BLOCK = 3; // 3:(1 + 2) 2: DRM_TS_FLAG_CRYPT_BYTE_BLOCK
36 constexpr uint32_t DRM_SKIP_BYTE_BLOCK = 9;
37 constexpr uint32_t DRM_H264_VIDEO_SKIP_BYTES = 35; // 35:(32 + 3) 32: bytes 3:3bytes
38 constexpr uint32_t DRM_H265_VIDEO_SKIP_BYTES = 68; // 68:(65 + 3) // 65: bytes 3:3bytes
39 constexpr uint8_t DRM_SHIFT_LEFT_NUM = 1;
40 constexpr uint8_t DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM = 0x1f;
41 constexpr uint8_t DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM = 0x3f;
42 constexpr uint8_t DRM_H265_VIDEO_START_NAL_TYPE = 0;
43 constexpr uint8_t DRM_H265_VIDEO_END_NAL_TYPE = 31;
44 constexpr uint32_t DRM_TS_SUB_SAMPLE_NUM = 2;
45 constexpr uint8_t DRM_H264_VIDEO_START_NAL_TYPE = 1;
46 constexpr uint8_t DRM_H264_VIDEO_END_NAL_TYPE = 5;
47 constexpr uint32_t DRM_MAX_STREAM_DATA_SIZE = 20971520; // 20971520:(20 * 1024 * 1024) 20MB, 1024:1024 bytes = 1kb
48
49 static const uint8_t VIDEO_FRAME_ARR[DRM_VIDEO_FRAME_ARR_LEN] = { 0x00, 0x00, 0x01 };
50 static const uint8_t AMBIGUITY_ARR[DRM_AMBIGUITY_ARR_LEN] = { 0x00, 0x00, 0x03 };
51
52 typedef enum {
53 DRM_ARR_SUBSCRIPT_ZERO = 0,
54 DRM_ARR_SUBSCRIPT_ONE,
55 DRM_ARR_SUBSCRIPT_TWO,
56 DRM_ARR_SUBSCRIPT_THREE,
57 } DRM_ArrSubscriptCollection;
58
59 typedef enum {
60 DRM_VIDEO_AVC = 0x1,
61 DRM_VIDEO_HEVC,
62 DRM_VIDEO_NONE,
63 } DRM_CodecType;
64
DrmGetSkipClearBytes(uint32_t & skipBytes) const65 void CodecDrmDecrypt::DrmGetSkipClearBytes(uint32_t &skipBytes) const
66 {
67 if (codingType_ == DRM_VIDEO_AVC) {
68 skipBytes = DRM_H264_VIDEO_SKIP_BYTES;
69 } else if (codingType_ == DRM_VIDEO_HEVC) {
70 skipBytes = DRM_H265_VIDEO_SKIP_BYTES;
71 }
72 return;
73 }
74
DrmGetNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint8_t & nalType,uint32_t & posIndex) const75 int32_t CodecDrmDecrypt::DrmGetNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
76 uint8_t &nalType, uint32_t &posIndex) const
77 {
78 uint32_t i;
79 nalType = 0;
80 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
81 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
82 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
83 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
84 continue;
85 }
86 if (codingType_ == DRM_VIDEO_AVC) {
87 nalType = data[i + DRM_ARR_SUBSCRIPT_THREE] & DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM;
88 if ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
89 (nalType == DRM_H264_VIDEO_END_NAL_TYPE)) {
90 posIndex = i;
91 return 0;
92 }
93 } else if (codingType_ == DRM_VIDEO_HEVC) {
94 nalType = (data[i + DRM_ARR_SUBSCRIPT_THREE] >> DRM_SHIFT_LEFT_NUM) & DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM;
95 if ((nalType >= DRM_H265_VIDEO_START_NAL_TYPE) &&
96 (nalType <= DRM_H265_VIDEO_END_NAL_TYPE)) {
97 posIndex = i;
98 return 0;
99 }
100 } else {
101 nalType = 0;
102 }
103 }
104 posIndex = i;
105 return -1;
106 }
107
DrmGetSyncHeaderIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posIndex)108 void CodecDrmDecrypt::DrmGetSyncHeaderIndex(const uint8_t *data, uint32_t dataSize, uint32_t &posIndex)
109 {
110 uint32_t i;
111 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
112 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
113 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
114 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
115 continue;
116 }
117 posIndex = i;
118 return;
119 }
120 posIndex = dataSize;
121 return;
122 }
123
DrmGetFinalNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posStartIndex,uint32_t & posEndIndex) const124 uint8_t CodecDrmDecrypt::DrmGetFinalNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
125 uint32_t &posStartIndex, uint32_t &posEndIndex) const
126 {
127 uint32_t skipBytes = 0;
128 uint8_t tmpNalType = 0;
129 uint32_t tmpPosIndex = 0;
130 uint8_t nalType = 0;
131 posStartIndex = 0;
132 posEndIndex = dataSize;
133 DrmGetSkipClearBytes(skipBytes);
134 while (1) { // 1 true
135 int32_t ret = DrmGetNalTypeAndIndex(data, dataSize, tmpNalType, tmpPosIndex);
136 if (ret == 0) {
137 nalType = tmpNalType;
138 posStartIndex = tmpPosIndex;
139 tmpPosIndex += DRM_LEGACY_LEN;
140 DrmGetSyncHeaderIndex(data, dataSize, tmpPosIndex);
141 posEndIndex = tmpPosIndex;
142 if (tmpPosIndex > posStartIndex + skipBytes + DRM_AES_BLOCK_SIZE) {
143 break;
144 } else {
145 nalType = 0;
146 posStartIndex = dataSize;
147 posEndIndex = dataSize;
148 }
149 } else {
150 nalType = 0;
151 posStartIndex = dataSize;
152 posEndIndex = dataSize;
153 break;
154 }
155 }
156 return nalType;
157 }
158
DrmRemoveAmbiguityBytes(uint8_t * data,uint32_t & posEndIndex,uint32_t offset,uint32_t & dataSize)159 void CodecDrmDecrypt::DrmRemoveAmbiguityBytes(uint8_t *data, uint32_t &posEndIndex, uint32_t offset,
160 uint32_t &dataSize)
161 {
162 uint32_t len = posEndIndex;
163 uint32_t i;
164 for (i = offset; (i + DRM_LEGACY_LEN) < len; i++) {
165 if ((data[i] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ZERO]) &&
166 (data[i + DRM_ARR_SUBSCRIPT_ONE] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ONE]) &&
167 (data[i + DRM_ARR_SUBSCRIPT_TWO] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
168 if (data[i + DRM_ARR_SUBSCRIPT_THREE] >= DRM_AMBIGUITY_START_NUM &&
169 data[i + DRM_ARR_SUBSCRIPT_THREE] <= DRM_AMBIGUITY_END_NUM) {
170 errno_t res = memmove_s(data + i + DRM_ARR_SUBSCRIPT_TWO, len - (i + DRM_ARR_SUBSCRIPT_TWO),
171 data + i + DRM_ARR_SUBSCRIPT_THREE, len - (i + DRM_ARR_SUBSCRIPT_THREE));
172 CHECK_AND_RETURN_LOG(res == EOK, "memmove data err");
173 len -= 1;
174 i++;
175 }
176 }
177 }
178 dataSize = dataSize - (posEndIndex - len);
179 posEndIndex = len;
180 return;
181 }
182
DrmModifyCencInfo(uint8_t * data,uint32_t & dataSize,MetaDrmCencInfo * cencInfo) const183 void CodecDrmDecrypt::DrmModifyCencInfo(uint8_t *data, uint32_t &dataSize, MetaDrmCencInfo *cencInfo) const
184 {
185 uint8_t nalType;
186 uint32_t posStartIndex;
187 uint32_t posEndIndex;
188 uint32_t skipBytes = 0;
189 uint32_t delLen = 0;
190 uint32_t i;
191 if (dataSize > DRM_MAX_STREAM_DATA_SIZE) {
192 AVCODEC_LOGE("data size too large");
193 return;
194 }
195 DrmGetSkipClearBytes(skipBytes);
196 nalType = DrmGetFinalNalTypeAndIndex(data, dataSize, posStartIndex, posEndIndex);
197 if (cencInfo->isAmbiguity == 1) {
198 DrmRemoveAmbiguityBytes(data, posEndIndex, posStartIndex, dataSize);
199 }
200 for (i = posEndIndex - 1; i > 0; i--) {
201 if (data[i] != 0) {
202 break;
203 }
204 delLen++;
205 }
206
207 cencInfo->subSample[0].clearHeaderLen = dataSize;
208 cencInfo->subSample[0].payLoadLen = 0;
209 cencInfo->subSample[1].clearHeaderLen = 0;
210 cencInfo->subSample[1].payLoadLen = 0;
211 if (((codingType_ == DRM_VIDEO_AVC) && ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
212 (nalType == DRM_H264_VIDEO_END_NAL_TYPE))) ||
213 ((codingType_ == DRM_VIDEO_HEVC) &&
214 (nalType >= DRM_H265_VIDEO_START_NAL_TYPE) && (nalType <= DRM_H265_VIDEO_END_NAL_TYPE))) {
215 uint32_t clearHeaderLen = posStartIndex + skipBytes;
216 uint32_t payLoadLen =
217 (posEndIndex > (clearHeaderLen + delLen)) ? (posEndIndex - clearHeaderLen - delLen) : 0;
218 if (payLoadLen > 0) {
219 uint32_t lastClearLen = (payLoadLen % DRM_AES_BLOCK_SIZE == 0) ? DRM_AES_BLOCK_SIZE
220 : (payLoadLen % DRM_AES_BLOCK_SIZE);
221 payLoadLen = payLoadLen - lastClearLen;
222 cencInfo->subSample[0].clearHeaderLen = clearHeaderLen;
223 cencInfo->subSample[0].payLoadLen = payLoadLen;
224 cencInfo->subSample[1].clearHeaderLen = lastClearLen + delLen + (dataSize - posEndIndex);
225 cencInfo->subSample[1].payLoadLen = 0;
226 }
227 }
228 return;
229 }
230
DrmCencDecrypt(std::shared_ptr<AVBuffer> inBuf,std::shared_ptr<AVBuffer> outBuf,uint32_t & dataSize)231 void CodecDrmDecrypt::DrmCencDecrypt(std::shared_ptr<AVBuffer> inBuf, std::shared_ptr<AVBuffer> outBuf,
232 uint32_t &dataSize)
233 {
234 CHECK_AND_RETURN_LOG((inBuf != nullptr && outBuf != nullptr), "DrmCencDecrypt parameter err");
235 GetCodingType();
236 if (inBuf->meta_ != nullptr) {
237 std::vector<uint8_t> drmCencVec;
238 MetaDrmCencInfo *cencInfo = nullptr;
239 MetaDrmCencInfo clearCencInfo;
240 bool ret = inBuf->meta_->GetData(Media::Tag::DRM_CENC_INFO, drmCencVec);
241 if (ret) {
242 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&drmCencVec[0]);
243 if (cencInfo->encryptBlocks > DRM_CRYPT_BYTE_BLOCK || cencInfo->skipBlocks > DRM_SKIP_BYTE_BLOCK) {
244 AVCODEC_LOGE("DrmCencDecrypt parameter err");
245 return;
246 }
247 uint32_t sumBlocks = cencInfo->encryptBlocks + cencInfo->skipBlocks;
248 if ((sumBlocks == DRM_TS_FLAG_CRYPT_BYTE_BLOCK) ||
249 (sumBlocks == (DRM_CRYPT_BYTE_BLOCK + DRM_SKIP_BYTE_BLOCK))) {
250 DrmModifyCencInfo(inBuf->memory_->GetAddr(), dataSize, cencInfo);
251 cencInfo->subSampleNum = DRM_TS_SUB_SAMPLE_NUM;
252 cencInfo->encryptBlocks = (cencInfo->encryptBlocks >= DRM_TS_FLAG_CRYPT_BYTE_BLOCK) ?
253 (cencInfo->encryptBlocks - DRM_TS_FLAG_CRYPT_BYTE_BLOCK) : (cencInfo->encryptBlocks);
254 }
255 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED) {
256 cencInfo->subSampleNum = 1;
257 cencInfo->subSample[0].clearHeaderLen = dataSize;
258 cencInfo->subSample[0].payLoadLen = 0;
259 }
260 } else {
261 errno_t res = memset_s(&clearCencInfo, sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
262 CHECK_AND_RETURN_LOG(res == EOK, "memset cenc info err");
263 clearCencInfo.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
264 clearCencInfo.subSampleNum = 1;
265 clearCencInfo.subSample[0].clearHeaderLen = dataSize;
266 clearCencInfo.subSample[0].payLoadLen = 0;
267 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&clearCencInfo);
268 }
269 DecryptMediaData(cencInfo, inBuf, outBuf);
270 }
271 }
272
SetCodecName(const std::string & codecName)273 void CodecDrmDecrypt::SetCodecName(const std::string &codecName)
274 {
275 codecName_ = codecName;
276 }
277
GetCodingType()278 void CodecDrmDecrypt::GetCodingType()
279 {
280 if (codecName_.find("avc") != codecName_.npos) {
281 codingType_ = DRM_VIDEO_AVC;
282 } else if (codecName_.find("hevc") != codecName_.npos) {
283 codingType_ = DRM_VIDEO_HEVC;
284 } else {
285 codingType_ = DRM_VIDEO_NONE;
286 }
287 }
288
SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)289 void CodecDrmDecrypt::SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
290 const bool svpFlag)
291 {
292 AVCODEC_LOGI("CodecDrmDecrypt SetDecryptConfig");
293 std::lock_guard<std::mutex> drmLock(configMutex_);
294 CHECK_AND_RETURN_LOG((keySession != nullptr), "SetDecryptConfig keySession nullptr");
295 keySessionServiceProxy_ = keySession;
296 CHECK_AND_RETURN_LOG((keySession != nullptr), "SetDecryptConfig keySessionServiceProxy nullptr");
297 keySessionServiceProxy_->CreateMediaDecryptModule(decryptModuleProxy_);
298 CHECK_AND_RETURN_LOG((decryptModuleProxy_ != nullptr), "SetDecryptConfig decryptModuleProxy_ nullptr");
299 if (svpFlag) {
300 svpFlag_ = SVP_TRUE;
301 } else {
302 svpFlag_ = SVP_FALSE;
303 }
304 }
305
SetDrmBuffer(const std::shared_ptr<AVBuffer> & inBuf,const std::shared_ptr<AVBuffer> & outBuf,DrmBuffer & inDrmBuffer,DrmBuffer & outDrmBuffer)306 int32_t CodecDrmDecrypt::SetDrmBuffer(const std::shared_ptr<AVBuffer> &inBuf,
307 const std::shared_ptr<AVBuffer> &outBuf, DrmBuffer &inDrmBuffer, DrmBuffer &outDrmBuffer)
308 {
309 AVCODEC_LOGD("CodecDrmDecrypt SetDrmBuffer");
310 inDrmBuffer.bufferType = static_cast<uint32_t>(inBuf->memory_->GetMemoryType());
311 inDrmBuffer.fd = inBuf->memory_->GetFileDescriptor();
312 inDrmBuffer.bufferLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
313 if (inBuf->memory_->GetCapacity() < 0) {
314 AVCODEC_LOGE("CodecDrmDecrypt SetDrmBuffer input buffer failed due to GetCapacity() return -1");
315 return AVCS_ERR_NO_MEMORY;
316 }
317 inDrmBuffer.allocLen = static_cast<uint32_t>(inBuf->memory_->GetCapacity());
318 inDrmBuffer.filledLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
319 inDrmBuffer.offset = static_cast<uint32_t>(inBuf->memory_->GetOffset());
320 inDrmBuffer.sharedMemType = static_cast<uint32_t>(inBuf->memory_->GetMemoryFlag());
321
322 outDrmBuffer.bufferType = static_cast<uint32_t>(outBuf->memory_->GetMemoryType());
323 outDrmBuffer.fd = outBuf->memory_->GetFileDescriptor();
324 outDrmBuffer.bufferLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
325 if (outBuf->memory_->GetCapacity() < 0) {
326 AVCODEC_LOGE("CodecDrmDecrypt SetDrmBuffer output buffer failed due to GetCapacity() return -1");
327 return AVCS_ERR_NO_MEMORY;
328 }
329 outDrmBuffer.allocLen = static_cast<uint32_t>(outBuf->memory_->GetCapacity());
330 outDrmBuffer.filledLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
331 outDrmBuffer.offset = static_cast<uint32_t>(outBuf->memory_->GetOffset());
332 outDrmBuffer.sharedMemType = static_cast<uint32_t>(outBuf->memory_->GetMemoryFlag());
333 return AVCS_ERR_OK;
334 }
335
DecryptMediaData(const MetaDrmCencInfo * const cencInfo,std::shared_ptr<AVBuffer> inBuf,std::shared_ptr<AVBuffer> outBuf)336 int32_t CodecDrmDecrypt::DecryptMediaData(const MetaDrmCencInfo * const cencInfo, std::shared_ptr<AVBuffer> inBuf,
337 std::shared_ptr<AVBuffer> outBuf)
338 {
339 AVCODEC_LOGI("CodecDrmDecrypt DecryptMediaData");
340 #ifdef SUPPORT_DRM
341 std::lock_guard<std::mutex> drmLock(configMutex_);
342 int32_t retCode = AVCS_ERR_INVALID_VAL;
343 DrmStandard::IMediaDecryptModuleService::CryptInfo cryptInfo;
344 cryptInfo.type = static_cast<DrmStandard::IMediaDecryptModuleService::CryptAlgorithmType>(cencInfo->algo);
345 std::vector<uint8_t> keyIdVector(cencInfo->keyId, cencInfo->keyId + cencInfo->keyIdLen);
346 cryptInfo.keyId = keyIdVector;
347 std::vector<uint8_t> ivVector(cencInfo->iv, cencInfo->iv + cencInfo->ivLen);
348 cryptInfo.iv = ivVector;
349
350 cryptInfo.pattern.encryptBlocks = cencInfo->encryptBlocks;
351 cryptInfo.pattern.skipBlocks = cencInfo->skipBlocks;
352
353 for (uint32_t i = 0; i < cencInfo->subSampleNum; i++) {
354 DrmStandard::IMediaDecryptModuleService::SubSample temp({ cencInfo->subSample[i].clearHeaderLen,
355 cencInfo->subSample[i].payLoadLen });
356 cryptInfo.subSample.emplace_back(temp);
357 }
358
359 DrmBuffer inDrmBuffer;
360 DrmBuffer outDrmBuffer;
361 retCode = SetDrmBuffer(inBuf, outBuf, inDrmBuffer, outDrmBuffer);
362 CHECK_AND_RETURN_RET_LOG((retCode == AVCS_ERR_OK), retCode, "SetDecryptConfig failed cause SetDrmBuffer failed");
363
364 CHECK_AND_RETURN_RET_LOG((decryptModuleProxy_ != nullptr), retCode,
365 "SetDecryptConfig decryptModuleProxy_ nullptr");
366 retCode = decryptModuleProxy_->DecryptMediaData(svpFlag_, cryptInfo, inDrmBuffer, outDrmBuffer);
367 if (retCode != 0) {
368 return AVCS_ERR_UNKNOWN;
369 }
370 return AVCS_ERR_OK;
371 #else
372 (void)cencInfo;
373 (void)inBuf;
374 (void)outBuf;
375 return AVCS_ERR_OK;
376 #endif
377 }
378
379 } // namespace MediaAVCodec
380 } // namespace OHOS
381