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