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_FRAMEWORK, "CodecDrmDecrypt"};
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 #define DRM_USER_DATA_REGISTERED_UUID_SIZE 16
31 constexpr uint32_t DRM_LEGACY_LEN = 3;
32 constexpr uint32_t DRM_AES_BLOCK_SIZE = 16;
33 constexpr uint8_t DRM_AMBIGUITY_START_NUM = 0x00;
34 constexpr uint8_t DRM_AMBIGUITY_END_NUM = 0x03;
35 constexpr uint32_t DRM_CRYPT_BYTE_BLOCK = 1;
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 uint32_t DRM_AVS3_VIDEO_SKIP_BYTES = 4; // 4:(1 + 3) // 1: bytes 3:3bytes
40 constexpr uint8_t DRM_SHIFT_LEFT_NUM = 1;
41 constexpr uint8_t DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM = 0x1f;
42 constexpr uint8_t DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM = 0x3f;
43 constexpr uint8_t DRM_H265_VIDEO_START_NAL_TYPE = 0;
44 constexpr uint8_t DRM_H265_VIDEO_END_NAL_TYPE = 31;
45 constexpr uint32_t DRM_TS_SUB_SAMPLE_NUM = 2;
46 constexpr uint8_t DRM_H264_VIDEO_START_NAL_TYPE = 1;
47 constexpr uint8_t DRM_H264_VIDEO_END_NAL_TYPE = 5;
48 constexpr uint32_t DRM_MAX_STREAM_DATA_SIZE = 20971520; // 20971520:(20 * 1024 * 1024) 20MB, 1024:1024 bytes = 1kb
49 constexpr uint32_t DRM_H265_PAYLOAD_TYPE_OFFSET = 5;
50 constexpr uint8_t DRM_AVS_FLAG = 0xb5;
51 constexpr uint8_t DRM_USER_DATA_UNREGISTERED_TAG = 0x05;
52 constexpr uint32_t DRM_MIN_DRM_INFO_LEN = 2;
53 constexpr uint32_t DRM_INVALID_START_POS = 0xffffffff;
54
55 static const uint8_t VIDEO_FRAME_ARR[DRM_VIDEO_FRAME_ARR_LEN] = { 0x00, 0x00, 0x01 };
56 static const uint8_t AMBIGUITY_ARR[DRM_AMBIGUITY_ARR_LEN] = { 0x00, 0x00, 0x03 };
57 static const uint8_t USER_REGISTERED_UUID[DRM_USER_DATA_REGISTERED_UUID_SIZE] = {
58 0x70, 0xc1, 0xdb, 0x9f, 0x66, 0xae, 0x41, 0x27, 0xbf, 0xc0, 0xbb, 0x19, 0x81, 0x69, 0x4b, 0x66
59 };
60
61 typedef enum {
62 DRM_ARR_SUBSCRIPT_ZERO = 0,
63 DRM_ARR_SUBSCRIPT_ONE,
64 DRM_ARR_SUBSCRIPT_TWO,
65 DRM_ARR_SUBSCRIPT_THREE,
66 } DRM_ArrSubscriptCollection;
67
68 typedef enum {
69 DRM_VIDEO_AVC = 0x1,
70 DRM_VIDEO_HEVC,
71 DRM_VIDEO_AVS,
72 DRM_VIDEO_NONE,
73 } DRM_CodecType;
74
DrmGetSkipClearBytes(uint32_t & skipBytes) const75 void CodecDrmDecrypt::DrmGetSkipClearBytes(uint32_t &skipBytes) const
76 {
77 if (codingType_ == DRM_VIDEO_AVC) {
78 skipBytes = DRM_H264_VIDEO_SKIP_BYTES;
79 } else if (codingType_ == DRM_VIDEO_HEVC) {
80 skipBytes = DRM_H265_VIDEO_SKIP_BYTES;
81 } else if (codingType_ == DRM_VIDEO_AVS) {
82 skipBytes = DRM_AVS3_VIDEO_SKIP_BYTES;
83 }
84 return;
85 }
86
DrmGetNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint8_t & nalType,uint32_t & posIndex) const87 int32_t CodecDrmDecrypt::DrmGetNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
88 uint8_t &nalType, uint32_t &posIndex) const
89 {
90 uint32_t i;
91 nalType = 0;
92 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
93 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
94 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
95 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
96 continue;
97 }
98 if (codingType_ == DRM_VIDEO_AVC) {
99 nalType = data[i + DRM_ARR_SUBSCRIPT_THREE] & DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM;
100 if ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
101 (nalType == DRM_H264_VIDEO_END_NAL_TYPE)) {
102 posIndex = i;
103 return 0;
104 }
105 } else if (codingType_ == DRM_VIDEO_HEVC) {
106 nalType = (data[i + DRM_ARR_SUBSCRIPT_THREE] >> DRM_SHIFT_LEFT_NUM) & DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM;
107 if ((nalType >= DRM_H265_VIDEO_START_NAL_TYPE) &&
108 (nalType <= DRM_H265_VIDEO_END_NAL_TYPE)) {
109 posIndex = i;
110 return 0;
111 }
112 } else if (codingType_ == DRM_VIDEO_AVS) {
113 nalType = data[i + DRM_ARR_SUBSCRIPT_THREE];
114 if (nalType == 0) {
115 posIndex = i;
116 return 0;
117 }
118 }
119 }
120 posIndex = i;
121 return -1;
122 }
123
DrmGetSyncHeaderIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posIndex)124 void CodecDrmDecrypt::DrmGetSyncHeaderIndex(const uint8_t *data, uint32_t dataSize, uint32_t &posIndex)
125 {
126 uint32_t i;
127 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
128 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
129 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
130 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
131 continue;
132 }
133 posIndex = i;
134 return;
135 }
136 posIndex = dataSize;
137 return;
138 }
139
DrmGetFinalNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posStartIndex,uint32_t & posEndIndex) const140 uint8_t CodecDrmDecrypt::DrmGetFinalNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
141 uint32_t &posStartIndex, uint32_t &posEndIndex) const
142 {
143 uint32_t skipBytes = 0;
144 uint8_t tmpNalType = 0;
145 uint32_t tmpPosIndex = 0;
146 uint8_t nalType = 0;
147 posStartIndex = 0;
148 posEndIndex = dataSize;
149 DrmGetSkipClearBytes(skipBytes);
150 while (1) { // 1 true
151 int32_t ret = DrmGetNalTypeAndIndex(data, dataSize, tmpNalType, tmpPosIndex);
152 if (ret == 0) {
153 nalType = tmpNalType;
154 posStartIndex = tmpPosIndex;
155 tmpPosIndex += DRM_LEGACY_LEN;
156 DrmGetSyncHeaderIndex(data, dataSize, tmpPosIndex);
157 posEndIndex = tmpPosIndex;
158 if (tmpPosIndex > posStartIndex + skipBytes + DRM_AES_BLOCK_SIZE) {
159 break;
160 } else {
161 nalType = 0;
162 posStartIndex = dataSize;
163 posEndIndex = dataSize;
164 }
165 } else {
166 nalType = 0;
167 posStartIndex = dataSize;
168 posEndIndex = dataSize;
169 break;
170 }
171 }
172 return nalType;
173 }
174
DrmRemoveAmbiguityBytes(uint8_t * data,uint32_t & posEndIndex,uint32_t offset,uint32_t & dataSize)175 void CodecDrmDecrypt::DrmRemoveAmbiguityBytes(uint8_t *data, uint32_t &posEndIndex, uint32_t offset,
176 uint32_t &dataSize)
177 {
178 uint32_t len = posEndIndex;
179 uint32_t i;
180 for (i = offset; (i + DRM_LEGACY_LEN) < len; i++) {
181 if ((data[i] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ZERO]) &&
182 (data[i + DRM_ARR_SUBSCRIPT_ONE] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ONE]) &&
183 (data[i + DRM_ARR_SUBSCRIPT_TWO] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
184 if (data[i + DRM_ARR_SUBSCRIPT_THREE] >= DRM_AMBIGUITY_START_NUM &&
185 data[i + DRM_ARR_SUBSCRIPT_THREE] <= DRM_AMBIGUITY_END_NUM) {
186 errno_t res = memmove_s(data + i + DRM_ARR_SUBSCRIPT_TWO, len - (i + DRM_ARR_SUBSCRIPT_TWO),
187 data + i + DRM_ARR_SUBSCRIPT_THREE, len - (i + DRM_ARR_SUBSCRIPT_THREE));
188 CHECK_AND_RETURN_LOG(res == EOK, "memmove data err");
189 len -= 1;
190 i++;
191 }
192 }
193 }
194 dataSize = dataSize - (posEndIndex - len);
195 posEndIndex = len;
196 return;
197 }
198
DrmModifyCencInfo(std::shared_ptr<AVBuffer> inBuf,uint32_t & dataSize,uint8_t isAmbiguity,MetaDrmCencInfo * cencInfo) const199 void CodecDrmDecrypt::DrmModifyCencInfo(std::shared_ptr<AVBuffer> inBuf, uint32_t &dataSize, uint8_t isAmbiguity,
200 MetaDrmCencInfo *cencInfo) const
201 {
202 uint8_t nalType;
203 uint32_t posStartIndex;
204 uint32_t posEndIndex;
205 uint32_t skipBytes = 0;
206 uint32_t delLen = 0;
207 uint32_t i;
208 if (inBuf->memory_ == nullptr || inBuf->memory_->GetAddr() == nullptr || dataSize == 0 ||
209 dataSize > DRM_MAX_STREAM_DATA_SIZE) {
210 return;
211 }
212 uint8_t *data = inBuf->memory_->GetAddr();
213 DrmGetSkipClearBytes(skipBytes);
214 nalType = DrmGetFinalNalTypeAndIndex(data, dataSize, posStartIndex, posEndIndex);
215 if (isAmbiguity == 1) {
216 DrmRemoveAmbiguityBytes(data, posEndIndex, posStartIndex, dataSize);
217 }
218 CHECK_AND_RETURN_LOG((posEndIndex >= 1), "posEndIndex err"); // 1:index
219 for (i = posEndIndex - 1; i > 0; i--) {
220 if (data[i] != 0) {
221 break;
222 }
223 delLen++;
224 }
225
226 cencInfo->subSamples[0].clearHeaderLen = dataSize;
227 cencInfo->subSamples[0].payLoadLen = 0;
228 cencInfo->subSamples[1].clearHeaderLen = 0;
229 cencInfo->subSamples[1].payLoadLen = 0;
230 if (((codingType_ == DRM_VIDEO_AVC) && ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
231 (nalType == DRM_H264_VIDEO_END_NAL_TYPE))) ||
232 ((codingType_ == DRM_VIDEO_HEVC) &&
233 (nalType >= DRM_H265_VIDEO_START_NAL_TYPE) && (nalType <= DRM_H265_VIDEO_END_NAL_TYPE)) ||
234 ((codingType_ == DRM_VIDEO_AVS) && (nalType == 0))) {
235 uint32_t clearHeaderLen = posStartIndex + skipBytes;
236 uint32_t payLoadLen =
237 (posEndIndex > (clearHeaderLen + delLen)) ? (posEndIndex - clearHeaderLen - delLen) : 0;
238 if (payLoadLen > 0) {
239 uint32_t lastClearLen = (payLoadLen % DRM_AES_BLOCK_SIZE == 0) ? DRM_AES_BLOCK_SIZE
240 : (payLoadLen % DRM_AES_BLOCK_SIZE);
241 payLoadLen = payLoadLen - lastClearLen;
242 cencInfo->subSamples[0].clearHeaderLen = clearHeaderLen;
243 cencInfo->subSamples[0].payLoadLen = payLoadLen;
244 cencInfo->subSamples[1].clearHeaderLen = lastClearLen + delLen + (dataSize - posEndIndex);
245 cencInfo->subSamples[1].payLoadLen = 0;
246 }
247 }
248 return;
249 }
250
SetDrmAlgoAndBlocks(uint8_t algo,MetaDrmCencInfo * cencInfo)251 void CodecDrmDecrypt::SetDrmAlgoAndBlocks(uint8_t algo, MetaDrmCencInfo *cencInfo)
252 {
253 if (algo == 0x1) { // 0x1:SM4-SAMPL SM4S
254 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC;
255 cencInfo->encryptBlocks = DRM_CRYPT_BYTE_BLOCK;
256 cencInfo->skipBlocks = DRM_SKIP_BYTE_BLOCK;
257 } else if (algo == 0x2) { // 0x2:AES CBCS
258 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC;
259 cencInfo->encryptBlocks = DRM_CRYPT_BYTE_BLOCK;
260 cencInfo->skipBlocks = DRM_SKIP_BYTE_BLOCK;
261 } else if (algo == 0x5) { // 0x5:AES CBC1
262 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC;
263 cencInfo->encryptBlocks = 0;
264 cencInfo->skipBlocks = 0;
265 } else if (algo == 0x3) { // 0x3:SM4-CBC SM4C
266 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC;
267 cencInfo->encryptBlocks = 0;
268 cencInfo->skipBlocks = 0;
269 } else if (algo == 0x0) { // 0x0:NONE
270 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
271 cencInfo->encryptBlocks = 0;
272 cencInfo->skipBlocks = 0;
273 }
274 return;
275 }
276
DrmFindAvsCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)277 int CodecDrmDecrypt::DrmFindAvsCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
278 uint32_t index)
279 {
280 uint32_t i = index;
281 /*
282 * only squence_header allowed, cei is in first extension_and_user_data after squence_header.
283 * data[i + DRM_LEGACY_LEN] is the nal unit header(00~b8),
284 * 0xb0 means Squence header, 0xb5 means video extension, 0xb1 undefined, others are frames
285 */
286 if (((data[i + DRM_LEGACY_LEN] > 0) && (data[i + DRM_LEGACY_LEN] < 0xb8)) &&
287 (data[i + DRM_LEGACY_LEN] != 0xb0) && (data[i + DRM_LEGACY_LEN] != 0xb5) &&
288 (data[i + DRM_LEGACY_LEN] != 0xb1)) {
289 AVCODEC_LOGD("avs frame found");
290 return 0;
291 }
292 if ((data[i + DRM_LEGACY_LEN] == 0xb5) && (i + DRM_LEGACY_LEN + 1 < dataSize)) {
293 /* extension_and_user_data found, 0xd0: extension user data tag, 0xf0: the higher 4 bits */
294 if ((data[i + DRM_LEGACY_LEN + 1] & 0xf0) == 0xd0) {
295 ceiStartPos = i;
296 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
297 }
298 }
299 return -1;
300 }
301
DrmFindHevcCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)302 int CodecDrmDecrypt::DrmFindHevcCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
303 uint32_t index)
304 {
305 uint32_t i = index;
306 uint8_t nalType = (data[i + DRM_LEGACY_LEN] >> DRM_SHIFT_LEFT_NUM) & DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM;
307 AVCODEC_LOGD("nal type=%{public}x", nalType);
308 if (nalType <= DRM_H265_VIDEO_END_NAL_TYPE) { // nal type: 0 ~ 31 are slice nal units and reserved units
309 /* sei is not after frame data. */
310 AVCODEC_LOGD("h265 frame found");
311 return 0;
312 } else if ((nalType == 39) && (i + DRM_H265_PAYLOAD_TYPE_OFFSET < dataSize)) { // 39: SEI nal unit
313 if (data[i + DRM_H265_PAYLOAD_TYPE_OFFSET] == DRM_USER_DATA_UNREGISTERED_TAG) {
314 ceiStartPos = i;
315 }
316 }
317 if (ceiStartPos != DRM_INVALID_START_POS) {
318 uint32_t startPos = i + DRM_H265_PAYLOAD_TYPE_OFFSET;
319 uint32_t endPos = i + DRM_H265_PAYLOAD_TYPE_OFFSET;
320 ceiStartPos = DRM_INVALID_START_POS;
321 DrmGetSyncHeaderIndex(data, dataSize, endPos);
322 for (; (startPos + DRM_USER_DATA_REGISTERED_UUID_SIZE < endPos); startPos++) {
323 if (memcmp(data + startPos, USER_REGISTERED_UUID,
324 DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
325 ceiStartPos = i;
326 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
327 break;
328 }
329 }
330 }
331 return -1;
332 }
333
DrmFindH264CeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)334 int CodecDrmDecrypt::DrmFindH264CeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
335 uint32_t index)
336 {
337 uint32_t i = index;
338 uint8_t nalType = data[i + DRM_LEGACY_LEN] & DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM;
339 AVCODEC_LOGD("nal type=%{public}x", nalType);
340 if ((nalType >= DRM_H264_VIDEO_START_NAL_TYPE) && (nalType <= DRM_H264_VIDEO_END_NAL_TYPE)) {
341 /* sei is not after frame data. */
342 AVCODEC_LOGD("h264 frame found");
343 return 0;
344 } else if ((nalType == 39) || (nalType == 6)) { // 39 or 6 is SEI nal unit tag
345 if ((i + DRM_LEGACY_LEN + 1 < dataSize) &&
346 (data[i + DRM_LEGACY_LEN + 1] == DRM_USER_DATA_UNREGISTERED_TAG)) {
347 ceiStartPos = i;
348 }
349 }
350 if (ceiStartPos != DRM_INVALID_START_POS) {
351 uint32_t startPos = i + DRM_LEGACY_LEN + 1;
352 uint32_t endPos = i + DRM_LEGACY_LEN + 1;
353 ceiStartPos = DRM_INVALID_START_POS;
354 DrmGetSyncHeaderIndex(data, dataSize, endPos);
355 for (; (startPos + DRM_USER_DATA_REGISTERED_UUID_SIZE < endPos); startPos++) {
356 if (memcmp(data + startPos, USER_REGISTERED_UUID,
357 DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
358 ceiStartPos = i;
359 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
360 break;
361 }
362 }
363 }
364 return -1;
365 }
366
DrmFindCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index) const367 int CodecDrmDecrypt::DrmFindCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
368 uint32_t index) const
369 {
370 int ret = 0;
371 if (codingType_ == DRM_VIDEO_AVS) {
372 ret = DrmFindAvsCeiNalUnit(data, dataSize, ceiStartPos, index);
373 } else if (codingType_ == DRM_VIDEO_HEVC) {
374 ret = DrmFindHevcCeiNalUnit(data, dataSize, ceiStartPos, index);
375 } else if (codingType_ == DRM_VIDEO_AVC) {
376 ret = DrmFindH264CeiNalUnit(data, dataSize, ceiStartPos, index);
377 }
378 return ret;
379 }
380
DrmFindCeiPos(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t & ceiEndPos) const381 int CodecDrmDecrypt::DrmFindCeiPos(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
382 uint32_t &ceiEndPos) const
383 {
384 uint32_t i;
385 for (i = 0; (i + DRM_LEGACY_LEN) < dataSize; i++) {
386 /*the start code prefix is 0x000001*/
387 if ((data[i] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) &&
388 (data[i + DRM_ARR_SUBSCRIPT_ONE] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) &&
389 (data[i + DRM_ARR_SUBSCRIPT_TWO] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
390 uint32_t startPos = DRM_INVALID_START_POS;
391 if (ceiStartPos != DRM_INVALID_START_POS) {
392 ceiEndPos = i;
393 AVCODEC_LOGD("cei found, start pos:%{public}x end pos:%{public}x", ceiStartPos, ceiEndPos);
394 }
395 /* found a nal unit, process nal to find the cei.*/
396 if (!DrmFindCeiNalUnit(data, dataSize, startPos, i)) {
397 break;
398 }
399 if (startPos != DRM_INVALID_START_POS) {
400 ceiStartPos = startPos;
401 ceiEndPos = DRM_INVALID_START_POS;
402 }
403 i += DRM_LEGACY_LEN;
404 }
405 }
406 if ((ceiStartPos != DRM_INVALID_START_POS) && (ceiEndPos != DRM_INVALID_START_POS) &&
407 (ceiStartPos < ceiEndPos) && (ceiEndPos <= dataSize)) {
408 return 1; // 1 true
409 }
410 return 0;
411 }
412
DrmFindEncryptionFlagPos(const uint8_t * data,uint32_t dataSize,uint32_t & pos)413 void CodecDrmDecrypt::DrmFindEncryptionFlagPos(const uint8_t *data, uint32_t dataSize, uint32_t &pos)
414 {
415 uint32_t offset = pos;
416 if (data[offset + DRM_LEGACY_LEN] == DRM_AVS_FLAG) {
417 offset += DRM_LEGACY_LEN; //skip 0x00 0x00 0x01
418 offset += 2; // 2 skip this flag
419 } else {
420 for (; (offset + DRM_USER_DATA_REGISTERED_UUID_SIZE < dataSize); offset++) {
421 if (memcmp(data + offset, USER_REGISTERED_UUID, DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
422 offset += DRM_USER_DATA_REGISTERED_UUID_SIZE;
423 break;
424 }
425 }
426 }
427 if (offset < dataSize) {
428 pos = offset;
429 }
430 return;
431 }
432
DrmGetKeyId(uint8_t * data,uint32_t & dataSize,uint32_t & pos,MetaDrmCencInfo * cencInfo)433 int CodecDrmDecrypt::DrmGetKeyId(uint8_t *data, uint32_t &dataSize, uint32_t &pos, MetaDrmCencInfo *cencInfo)
434 {
435 uint32_t offset = pos;
436 CHECK_AND_RETURN_RET_LOG((offset < dataSize), -1, "cei data too short");
437 uint8_t encryptionFlag = (data[offset] & 0x80) >> 7; // 0x80 get encryptionFlag & 7 get bits
438 uint8_t nextKeyIdFlag = (data[offset] & 0x40) >> 6; // 0x40 get nextKeyIdFlag & 6 get bits
439 offset += 1; // 1 skip flag
440 DrmRemoveAmbiguityBytes(data, dataSize, offset, dataSize);
441
442 if (encryptionFlag != 0) {
443 CHECK_AND_RETURN_RET_LOG(((offset + META_DRM_KEY_ID_SIZE) <= dataSize), -1, "cei data too short");
444 errno_t res = memcpy_s(cencInfo->keyId, META_DRM_KEY_ID_SIZE, data + offset, META_DRM_KEY_ID_SIZE);
445 if (res != EOK) {
446 AVCODEC_LOGE("copy keyid err");
447 return -1;
448 }
449 cencInfo->keyIdLen = META_DRM_KEY_ID_SIZE;
450 offset += META_DRM_KEY_ID_SIZE;
451 } else {
452 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
453 }
454 if (nextKeyIdFlag == 1) {
455 offset += META_DRM_KEY_ID_SIZE;
456 }
457 pos = offset;
458 return 0;
459 }
460
DrmGetKeyIv(const uint8_t * data,uint32_t dataSize,uint32_t & pos,MetaDrmCencInfo * cencInfo)461 int CodecDrmDecrypt::DrmGetKeyIv(const uint8_t *data, uint32_t dataSize, uint32_t &pos, MetaDrmCencInfo *cencInfo)
462 {
463 uint32_t offset = pos;
464 CHECK_AND_RETURN_RET_LOG((offset < dataSize), -1, "cei data too short");
465 uint32_t ivLen = data[offset];
466 offset += 1; // 1 skip iv len
467 if ((offset + ivLen > dataSize) || (ivLen > META_DRM_IV_SIZE)) {
468 AVCODEC_LOGE("cei data too short");
469 return -1;
470 } else {
471 errno_t res = memcpy_s(cencInfo->iv, META_DRM_IV_SIZE, data + offset, ivLen);
472 if (res != EOK) {
473 AVCODEC_LOGE("copy iv err");
474 return -1;
475 }
476 cencInfo->ivLen = ivLen;
477 offset += ivLen;
478 }
479 pos = offset;
480 return 0;
481 }
482
DrmParseDrmDescriptor(const uint8_t * data,uint32_t dataSize,uint32_t & pos,uint8_t drmDescriptorFlag,MetaDrmCencInfo * cencInfo)483 int CodecDrmDecrypt::DrmParseDrmDescriptor(const uint8_t *data, uint32_t dataSize, uint32_t &pos,
484 uint8_t drmDescriptorFlag, MetaDrmCencInfo *cencInfo)
485 {
486 uint32_t offset = pos;
487 if (drmDescriptorFlag == 0) {
488 return 0;
489 }
490 CHECK_AND_RETURN_RET_LOG((offset + DRM_MIN_DRM_INFO_LEN < dataSize), -1, "cei data too short");
491 uint8_t videoAlgo = data[offset + DRM_MIN_DRM_INFO_LEN] & 0x0f; // video algo offset
492 SetDrmAlgoAndBlocks(videoAlgo, cencInfo);
493 offset = offset + DRM_MIN_DRM_INFO_LEN;
494 pos = offset;
495 return 0;
496 }
497
DrmSetKeyInfo(const uint8_t * data,uint32_t dataSize,uint32_t ceiStartPos,uint8_t & isAmbiguity,MetaDrmCencInfo * cencInfo)498 void CodecDrmDecrypt::DrmSetKeyInfo(const uint8_t *data, uint32_t dataSize, uint32_t ceiStartPos,
499 uint8_t &isAmbiguity, MetaDrmCencInfo *cencInfo)
500 {
501 uint32_t totalSize = dataSize;
502 uint32_t pos = ceiStartPos;
503 uint8_t *ceiBuf = nullptr;
504 uint8_t drmDescriptorFlag = 0;
505 uint8_t drmNotAmbiguityFlag = 0;
506 CHECK_AND_RETURN_LOG((dataSize != 0), "DrmSetKeyInfo dataSize is 0");
507 CHECK_AND_RETURN_LOG((pos + DRM_LEGACY_LEN < totalSize), "cei data too short");
508 ceiBuf = reinterpret_cast<uint8_t *>(malloc(dataSize));
509 if (ceiBuf == nullptr) {
510 AVCODEC_LOGE("malloc cei data failed");
511 return;
512 }
513 errno_t res = memcpy_s(ceiBuf, dataSize, data, dataSize);
514 if (res != EOK) {
515 free(ceiBuf);
516 return;
517 }
518 DrmFindEncryptionFlagPos(ceiBuf, totalSize, pos);
519 drmDescriptorFlag = (ceiBuf[pos] & 0x20) >> 5; // 0x20 get drmDescriptorFlag & 5 get bits
520 drmNotAmbiguityFlag = (ceiBuf[pos] & 0x10) >> 4; // 0x10 get drmNotAmbiguityFlag & 4 get bits
521 if (drmNotAmbiguityFlag == 1) {
522 isAmbiguity = 0;
523 } else {
524 isAmbiguity = 1; // 1:exist ambiguity
525 }
526
527 int ret = DrmGetKeyId(ceiBuf, totalSize, pos, cencInfo);
528 if (ret == 0) {
529 ret = DrmGetKeyIv(ceiBuf, totalSize, pos, cencInfo);
530 if (ret == 0) {
531 (void)DrmParseDrmDescriptor(ceiBuf, totalSize, pos, drmDescriptorFlag, cencInfo);
532 }
533 }
534 free(ceiBuf);
535 return;
536 }
537
DrmGetCencInfo(std::shared_ptr<AVBuffer> inBuf,uint32_t dataSize,uint8_t & isAmbiguity,MetaDrmCencInfo * cencInfo) const538 void CodecDrmDecrypt::DrmGetCencInfo(std::shared_ptr<AVBuffer> inBuf, uint32_t dataSize, uint8_t &isAmbiguity,
539 MetaDrmCencInfo *cencInfo) const
540 {
541 int ret;
542 uint32_t ceiStartPos = DRM_INVALID_START_POS;
543 uint32_t ceiEndPos = DRM_INVALID_START_POS;
544 CHECK_AND_RETURN_LOG((inBuf->memory_ != nullptr && inBuf->memory_->GetAddr() != nullptr && dataSize != 0 &&
545 dataSize <= DRM_MAX_STREAM_DATA_SIZE), "DrmGetCencInfo parameter err");
546 uint8_t *data = inBuf->memory_->GetAddr();
547
548 ret = DrmFindCeiPos(data, dataSize, ceiStartPos, ceiEndPos);
549 if (ret) {
550 DrmSetKeyInfo(data, ceiEndPos, ceiStartPos, isAmbiguity, cencInfo);
551 }
552 return;
553 }
554
DrmVideoCencDecrypt(std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf,uint32_t & dataSize)555 int32_t CodecDrmDecrypt::DrmVideoCencDecrypt(std::shared_ptr<AVBuffer> &inBuf, std::shared_ptr<AVBuffer> &outBuf,
556 uint32_t &dataSize)
557 {
558 AVCODEC_LOGD("DrmVideoCencDecrypt");
559 int32_t ret = AVCS_ERR_UNKNOWN;
560 CHECK_AND_RETURN_RET_LOG((inBuf != nullptr && outBuf != nullptr), ret, "DrmVideoCencDecrypt parameter err");
561 GetCodingType();
562 if (inBuf->meta_ != nullptr) {
563 std::vector<uint8_t> drmCencVec;
564 MetaDrmCencInfo *cencInfo = nullptr;
565 MetaDrmCencInfo clearCencInfo;
566 bool res = inBuf->meta_->GetData(Media::Tag::DRM_CENC_INFO, drmCencVec);
567 if (res) {
568 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&drmCencVec[0]);
569 CHECK_AND_RETURN_RET_LOG(
570 (cencInfo->encryptBlocks <= DRM_CRYPT_BYTE_BLOCK && cencInfo->skipBlocks <= DRM_SKIP_BYTE_BLOCK),
571 ret, "DrmVideoCencDecrypt parameter err");
572 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED) {
573 cencInfo->subSampleNum = 1;
574 cencInfo->subSamples[0].clearHeaderLen = dataSize;
575 cencInfo->subSamples[0].payLoadLen = 0;
576 }
577 } else {
578 errno_t errCode = memset_s(&clearCencInfo, sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
579 CHECK_AND_RETURN_RET_LOG(errCode == EOK, ret, "memset cenc info err");
580 clearCencInfo.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
581 clearCencInfo.subSampleNum = 1;
582 clearCencInfo.subSamples[0].clearHeaderLen = dataSize;
583 clearCencInfo.subSamples[0].payLoadLen = 0;
584 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&clearCencInfo);
585 }
586 if (cencInfo->mode == MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET ||
587 mode_ == MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET) {
588 uint8_t isAmbiguity = 1;
589 DrmGetCencInfo(inBuf, dataSize, isAmbiguity, cencInfo);
590 DrmModifyCencInfo(inBuf, dataSize, isAmbiguity, cencInfo);
591 cencInfo->subSampleNum = DRM_TS_SUB_SAMPLE_NUM;
592 mode_ = cencInfo->mode;
593 }
594 ret = DecryptMediaData(cencInfo, inBuf, outBuf);
595 }
596 return ret;
597 }
598
DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf,uint32_t & dataSize)599 int32_t CodecDrmDecrypt::DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> &inBuf, std::shared_ptr<AVBuffer> &outBuf,
600 uint32_t &dataSize)
601 {
602 AVCODEC_LOGD("DrmAudioCencDecrypt");
603 int32_t ret = AVCS_ERR_UNKNOWN;
604 CHECK_AND_RETURN_RET_LOG((inBuf != nullptr && outBuf != nullptr), ret, "DrmCencDecrypt parameter err");
605 CHECK_AND_RETURN_RET_LOG((inBuf->meta_ != nullptr), ret, "DrmCencDecrypt meta null");
606
607 std::vector<uint8_t> drmCencVec;
608 MetaDrmCencInfo *cencInfo = nullptr;
609 MetaDrmCencInfo clearCencInfo;
610 bool res = inBuf->meta_->GetData(Media::Tag::DRM_CENC_INFO, drmCencVec);
611 if (res) {
612 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&drmCencVec[0]);
613 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED) {
614 cencInfo->subSampleNum = 1;
615 cencInfo->subSamples[0].clearHeaderLen = dataSize;
616 cencInfo->subSamples[0].payLoadLen = 0;
617 }
618 if (cencInfo->subSampleNum == 0) {
619 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CTR ||
620 cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CTR) {
621 cencInfo->subSampleNum = 1; // 1: subSampleNum
622 cencInfo->subSamples[0].clearHeaderLen = 0;
623 cencInfo->subSamples[0].payLoadLen = dataSize;
624 }
625 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC ||
626 cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC) {
627 cencInfo->subSampleNum = 2; // 2: subSampleNum
628 cencInfo->subSamples[0].clearHeaderLen = 0;
629 cencInfo->subSamples[0].payLoadLen = (dataSize / 16) * 16; // 16: BlockSize
630 cencInfo->subSamples[1].clearHeaderLen = dataSize % 16; // 16: BlockSize
631 cencInfo->subSamples[1].payLoadLen = 0;
632 }
633 }
634 } else {
635 errno_t errCode = memset_s(&clearCencInfo, sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
636 CHECK_AND_RETURN_RET_LOG(errCode == EOK, ret, "memset cenc info err");
637 clearCencInfo.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
638 clearCencInfo.subSampleNum = 1;
639 clearCencInfo.subSamples[0].clearHeaderLen = dataSize;
640 clearCencInfo.subSamples[0].payLoadLen = 0;
641 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&clearCencInfo);
642 }
643 ret = DecryptMediaData(cencInfo, inBuf, outBuf);
644
645 return ret;
646 }
647
SetCodecName(const std::string & codecName)648 void CodecDrmDecrypt::SetCodecName(const std::string &codecName)
649 {
650 codecName_ = codecName;
651 }
652
GetCodingType()653 void CodecDrmDecrypt::GetCodingType()
654 {
655 codingType_ = DRM_VIDEO_NONE;
656 if (codecName_.find("avc") != codecName_.npos) {
657 codingType_ = DRM_VIDEO_AVC;
658 } else if (codecName_.find("hevc") != codecName_.npos) {
659 codingType_ = DRM_VIDEO_HEVC;
660 } else if (codecName_.find("avs") != codecName_.npos) {
661 codingType_ = DRM_VIDEO_AVS;
662 }
663 }
664
SetDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)665 void CodecDrmDecrypt::SetDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
666 const bool svpFlag)
667 {
668 AVCODEC_LOGI("CodecDrmDecrypt SetDecryptConfig");
669 std::lock_guard<std::mutex> drmLock(configMutex_);
670 if (svpFlag) {
671 svpFlag_ = SVP_TRUE;
672 } else {
673 svpFlag_ = SVP_FALSE;
674 }
675 mode_ = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
676 keySessionServiceProxy_ = keySession;
677 CHECK_AND_RETURN_LOG((keySessionServiceProxy_ != nullptr), "SetDecryptConfig keySessionServiceProxy nullptr");
678 keySessionServiceProxy_->GetMediaDecryptModule(decryptModuleProxy_);
679 CHECK_AND_RETURN_LOG((decryptModuleProxy_ != nullptr), "SetDecryptConfig decryptModuleProxy_ nullptr");
680 }
681
SetDrmBuffer(const std::shared_ptr<AVBuffer> & inBuf,const std::shared_ptr<AVBuffer> & outBuf,DrmBuffer & inDrmBuffer,DrmBuffer & outDrmBuffer)682 int32_t CodecDrmDecrypt::SetDrmBuffer(const std::shared_ptr<AVBuffer> &inBuf,
683 const std::shared_ptr<AVBuffer> &outBuf, DrmBuffer &inDrmBuffer, DrmBuffer &outDrmBuffer)
684 {
685 AVCODEC_LOGD("CodecDrmDecrypt SetDrmBuffer");
686 CHECK_AND_RETURN_RET_LOG((inBuf->memory_ != nullptr && outBuf->memory_ != nullptr), AVCS_ERR_NO_MEMORY,
687 "CodecDrmDecrypt SetDrmBuffer memory_ null");
688 inDrmBuffer.bufferType = static_cast<uint32_t>(inBuf->memory_->GetMemoryType());
689 inDrmBuffer.fd = inBuf->memory_->GetFileDescriptor();
690 inDrmBuffer.bufferLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
691 CHECK_AND_RETURN_RET_LOG((inBuf->memory_->GetCapacity() >= 0), AVCS_ERR_NO_MEMORY,
692 "CodecDrmDecrypt SetDrmBuffer input buffer failed due to GetCapacity() return -1");
693 inDrmBuffer.allocLen = static_cast<uint32_t>(inBuf->memory_->GetCapacity());
694 inDrmBuffer.filledLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
695 inDrmBuffer.offset = static_cast<uint32_t>(inBuf->memory_->GetOffset());
696 inDrmBuffer.sharedMemType = static_cast<uint32_t>(inBuf->memory_->GetMemoryFlag());
697
698 outDrmBuffer.bufferType = static_cast<uint32_t>(outBuf->memory_->GetMemoryType());
699 outDrmBuffer.fd = outBuf->memory_->GetFileDescriptor();
700 outDrmBuffer.bufferLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
701 CHECK_AND_RETURN_RET_LOG((outBuf->memory_->GetCapacity() >= 0), AVCS_ERR_NO_MEMORY,
702 "CodecDrmDecrypt SetDrmBuffer output buffer failed due to GetCapacity() return -1");
703 outDrmBuffer.allocLen = static_cast<uint32_t>(outBuf->memory_->GetCapacity());
704 outDrmBuffer.filledLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
705 outDrmBuffer.offset = static_cast<uint32_t>(outBuf->memory_->GetOffset());
706 outDrmBuffer.sharedMemType = static_cast<uint32_t>(outBuf->memory_->GetMemoryFlag());
707 return AVCS_ERR_OK;
708 }
709
DecryptMediaData(const MetaDrmCencInfo * const cencInfo,std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf)710 int32_t CodecDrmDecrypt::DecryptMediaData(const MetaDrmCencInfo * const cencInfo, std::shared_ptr<AVBuffer> &inBuf,
711 std::shared_ptr<AVBuffer> &outBuf)
712 {
713 AVCODEC_LOGI("CodecDrmDecrypt DecryptMediaData");
714 #ifdef SUPPORT_DRM
715 std::lock_guard<std::mutex> drmLock(configMutex_);
716 int32_t retCode = AVCS_ERR_INVALID_VAL;
717 DrmStandard::IMediaDecryptModuleService::CryptInfo cryptInfo;
718 CHECK_AND_RETURN_RET_LOG(((cencInfo->keyIdLen <= static_cast<uint32_t>(META_DRM_KEY_ID_SIZE)) &&
719 (cencInfo->ivLen <= static_cast<uint32_t>(META_DRM_IV_SIZE)) &&
720 (cencInfo->subSampleNum <= static_cast<uint32_t>(META_DRM_MAX_SUB_SAMPLE_NUM))), retCode, "parameter err");
721 cryptInfo.type = static_cast<DrmStandard::IMediaDecryptModuleService::CryptAlgorithmType>(cencInfo->algo);
722 std::vector<uint8_t> keyIdVector(cencInfo->keyId, cencInfo->keyId + cencInfo->keyIdLen);
723 cryptInfo.keyId = keyIdVector;
724 std::vector<uint8_t> ivVector(cencInfo->iv, cencInfo->iv + cencInfo->ivLen);
725 cryptInfo.iv = ivVector;
726 cryptInfo.pattern.encryptBlocks = cencInfo->encryptBlocks;
727 cryptInfo.pattern.skipBlocks = cencInfo->skipBlocks;
728
729 for (uint32_t i = 0; i < cencInfo->subSampleNum; i++) {
730 DrmStandard::IMediaDecryptModuleService::SubSample temp({ cencInfo->subSamples[i].clearHeaderLen,
731 cencInfo->subSamples[i].payLoadLen });
732 cryptInfo.subSample.emplace_back(temp);
733 }
734
735 DrmBuffer inDrmBuffer;
736 DrmBuffer outDrmBuffer;
737 retCode = SetDrmBuffer(inBuf, outBuf, inDrmBuffer, outDrmBuffer);
738 CHECK_AND_RETURN_RET_LOG((retCode == AVCS_ERR_OK), retCode, "SetDecryptConfig failed cause SetDrmBuffer failed");
739 retCode = AVCS_ERR_INVALID_VAL;
740 CHECK_AND_RETURN_RET_LOG((decryptModuleProxy_ != nullptr), retCode,
741 "SetDecryptConfig decryptModuleProxy_ nullptr");
742 retCode = decryptModuleProxy_->DecryptMediaData(svpFlag_, cryptInfo, inDrmBuffer, outDrmBuffer);
743 CHECK_AND_RETURN_RET_LOG((retCode == 0), AVCS_ERR_UNKNOWN, "CodecDrmDecrypt decrypt failed!");
744 return AVCS_ERR_OK;
745 #else
746 (void)cencInfo;
747 (void)inBuf;
748 (void)outBuf;
749 return AVCS_ERR_OK;
750 #endif
751 }
752
753 } // namespace MediaAVCodec
754 } // namespace OHOS
755