1cabdff1aSopenharmony_ci/**
2cabdff1aSopenharmony_ci * This file is part of FFmpeg.
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cabdff1aSopenharmony_ci * Lesser General Public License for more details.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17cabdff1aSopenharmony_ci */
18cabdff1aSopenharmony_ci
19cabdff1aSopenharmony_ci#include "encryption_info.h"
20cabdff1aSopenharmony_ci#include "mem.h"
21cabdff1aSopenharmony_ci#include "intreadwrite.h"
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#define FF_ENCRYPTION_INFO_EXTRA 24
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci// The format of the AVEncryptionInfo side data:
26cabdff1aSopenharmony_ci// u32be scheme
27cabdff1aSopenharmony_ci// u32be crypt_byte_block
28cabdff1aSopenharmony_ci// u32be skip_byte_block
29cabdff1aSopenharmony_ci// u32be key_id_size
30cabdff1aSopenharmony_ci// u32be iv_size
31cabdff1aSopenharmony_ci// u32be subsample_count
32cabdff1aSopenharmony_ci// u8[key_id_size] key_id
33cabdff1aSopenharmony_ci// u8[iv_size] iv
34cabdff1aSopenharmony_ci// {
35cabdff1aSopenharmony_ci//   u32be bytes_of_clear_data
36cabdff1aSopenharmony_ci//   u32be bytes_of_protected_data
37cabdff1aSopenharmony_ci// }[subsample_count]
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ciAVEncryptionInfo *av_encryption_info_alloc(uint32_t subsample_count, uint32_t key_id_size, uint32_t iv_size)
40cabdff1aSopenharmony_ci{
41cabdff1aSopenharmony_ci    AVEncryptionInfo *info;
42cabdff1aSopenharmony_ci
43cabdff1aSopenharmony_ci    info = av_mallocz(sizeof(*info));
44cabdff1aSopenharmony_ci    if (!info)
45cabdff1aSopenharmony_ci        return NULL;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    info->key_id = av_mallocz(key_id_size);
48cabdff1aSopenharmony_ci    info->key_id_size = key_id_size;
49cabdff1aSopenharmony_ci    info->iv = av_mallocz(iv_size);
50cabdff1aSopenharmony_ci    info->iv_size = iv_size;
51cabdff1aSopenharmony_ci    info->subsamples = av_calloc(subsample_count, sizeof(*info->subsamples));
52cabdff1aSopenharmony_ci    info->subsample_count = subsample_count;
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci    // Allow info->subsamples to be NULL if there are no subsamples.
55cabdff1aSopenharmony_ci    if (!info->key_id || !info->iv || (!info->subsamples && subsample_count)) {
56cabdff1aSopenharmony_ci        av_encryption_info_free(info);
57cabdff1aSopenharmony_ci        return NULL;
58cabdff1aSopenharmony_ci    }
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci    return info;
61cabdff1aSopenharmony_ci}
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_ciAVEncryptionInfo *av_encryption_info_clone(const AVEncryptionInfo *info)
64cabdff1aSopenharmony_ci{
65cabdff1aSopenharmony_ci    AVEncryptionInfo *ret;
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci    ret = av_encryption_info_alloc(info->subsample_count, info->key_id_size, info->iv_size);
68cabdff1aSopenharmony_ci    if (!ret)
69cabdff1aSopenharmony_ci        return NULL;
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci    ret->scheme = info->scheme;
72cabdff1aSopenharmony_ci    ret->crypt_byte_block = info->crypt_byte_block;
73cabdff1aSopenharmony_ci    ret->skip_byte_block = info->skip_byte_block;
74cabdff1aSopenharmony_ci    memcpy(ret->iv, info->iv, info->iv_size);
75cabdff1aSopenharmony_ci    memcpy(ret->key_id, info->key_id, info->key_id_size);
76cabdff1aSopenharmony_ci    memcpy(ret->subsamples, info->subsamples, sizeof(*info->subsamples) * info->subsample_count);
77cabdff1aSopenharmony_ci    return ret;
78cabdff1aSopenharmony_ci}
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_civoid av_encryption_info_free(AVEncryptionInfo *info)
81cabdff1aSopenharmony_ci{
82cabdff1aSopenharmony_ci    if (info) {
83cabdff1aSopenharmony_ci        av_free(info->key_id);
84cabdff1aSopenharmony_ci        av_free(info->iv);
85cabdff1aSopenharmony_ci        av_free(info->subsamples);
86cabdff1aSopenharmony_ci        av_free(info);
87cabdff1aSopenharmony_ci    }
88cabdff1aSopenharmony_ci}
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ciAVEncryptionInfo *av_encryption_info_get_side_data(const uint8_t* buffer, size_t size)
91cabdff1aSopenharmony_ci{
92cabdff1aSopenharmony_ci    AVEncryptionInfo *info;
93cabdff1aSopenharmony_ci    uint64_t key_id_size, iv_size, subsample_count, i;
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci    if (!buffer || size < FF_ENCRYPTION_INFO_EXTRA)
96cabdff1aSopenharmony_ci        return NULL;
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci    key_id_size = AV_RB32(buffer + 12);
99cabdff1aSopenharmony_ci    iv_size = AV_RB32(buffer + 16);
100cabdff1aSopenharmony_ci    subsample_count = AV_RB32(buffer + 20);
101cabdff1aSopenharmony_ci
102cabdff1aSopenharmony_ci    if (size < FF_ENCRYPTION_INFO_EXTRA + key_id_size + iv_size + subsample_count * 8)
103cabdff1aSopenharmony_ci        return NULL;
104cabdff1aSopenharmony_ci
105cabdff1aSopenharmony_ci    info = av_encryption_info_alloc(subsample_count, key_id_size, iv_size);
106cabdff1aSopenharmony_ci    if (!info)
107cabdff1aSopenharmony_ci        return NULL;
108cabdff1aSopenharmony_ci
109cabdff1aSopenharmony_ci    info->scheme = AV_RB32(buffer);
110cabdff1aSopenharmony_ci    info->crypt_byte_block = AV_RB32(buffer + 4);
111cabdff1aSopenharmony_ci    info->skip_byte_block = AV_RB32(buffer + 8);
112cabdff1aSopenharmony_ci    memcpy(info->key_id, buffer + 24, key_id_size);
113cabdff1aSopenharmony_ci    memcpy(info->iv, buffer + key_id_size + 24, iv_size);
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci    buffer += key_id_size + iv_size + 24;
116cabdff1aSopenharmony_ci    for (i = 0; i < subsample_count; i++) {
117cabdff1aSopenharmony_ci        info->subsamples[i].bytes_of_clear_data = AV_RB32(buffer);
118cabdff1aSopenharmony_ci        info->subsamples[i].bytes_of_protected_data = AV_RB32(buffer + 4);
119cabdff1aSopenharmony_ci        buffer += 8;
120cabdff1aSopenharmony_ci    }
121cabdff1aSopenharmony_ci
122cabdff1aSopenharmony_ci    return info;
123cabdff1aSopenharmony_ci}
124cabdff1aSopenharmony_ci
125cabdff1aSopenharmony_ciuint8_t *av_encryption_info_add_side_data(const AVEncryptionInfo *info, size_t *size)
126cabdff1aSopenharmony_ci{
127cabdff1aSopenharmony_ci    uint8_t *buffer, *cur_buffer;
128cabdff1aSopenharmony_ci    uint32_t i;
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci    if (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA < info->key_id_size ||
131cabdff1aSopenharmony_ci        UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size < info->iv_size ||
132cabdff1aSopenharmony_ci        (UINT32_MAX - FF_ENCRYPTION_INFO_EXTRA - info->key_id_size - info->iv_size) / 8 < info->subsample_count) {
133cabdff1aSopenharmony_ci        return NULL;
134cabdff1aSopenharmony_ci    }
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    *size = FF_ENCRYPTION_INFO_EXTRA + info->key_id_size + info->iv_size +
137cabdff1aSopenharmony_ci            (info->subsample_count * 8);
138cabdff1aSopenharmony_ci    cur_buffer = buffer = av_malloc(*size);
139cabdff1aSopenharmony_ci    if (!buffer)
140cabdff1aSopenharmony_ci        return NULL;
141cabdff1aSopenharmony_ci
142cabdff1aSopenharmony_ci    AV_WB32(cur_buffer,      info->scheme);
143cabdff1aSopenharmony_ci    AV_WB32(cur_buffer +  4, info->crypt_byte_block);
144cabdff1aSopenharmony_ci    AV_WB32(cur_buffer +  8, info->skip_byte_block);
145cabdff1aSopenharmony_ci    AV_WB32(cur_buffer + 12, info->key_id_size);
146cabdff1aSopenharmony_ci    AV_WB32(cur_buffer + 16, info->iv_size);
147cabdff1aSopenharmony_ci    AV_WB32(cur_buffer + 20, info->subsample_count);
148cabdff1aSopenharmony_ci    cur_buffer += 24;
149cabdff1aSopenharmony_ci    memcpy(cur_buffer, info->key_id, info->key_id_size);
150cabdff1aSopenharmony_ci    cur_buffer += info->key_id_size;
151cabdff1aSopenharmony_ci    memcpy(cur_buffer, info->iv, info->iv_size);
152cabdff1aSopenharmony_ci    cur_buffer += info->iv_size;
153cabdff1aSopenharmony_ci    for (i = 0; i < info->subsample_count; i++) {
154cabdff1aSopenharmony_ci        AV_WB32(cur_buffer, info->subsamples[i].bytes_of_clear_data);
155cabdff1aSopenharmony_ci        AV_WB32(cur_buffer + 4, info->subsamples[i].bytes_of_protected_data);
156cabdff1aSopenharmony_ci        cur_buffer += 8;
157cabdff1aSopenharmony_ci    }
158cabdff1aSopenharmony_ci
159cabdff1aSopenharmony_ci    return buffer;
160cabdff1aSopenharmony_ci}
161cabdff1aSopenharmony_ci
162cabdff1aSopenharmony_ci#ifdef OHOS_DRM
163cabdff1aSopenharmony_cistatic void av_encryption_info_set_drm_algo(uint32_t algo, AV_DrmCencInfo *cenc_info)
164cabdff1aSopenharmony_ci{
165cabdff1aSopenharmony_ci    switch (algo) {
166cabdff1aSopenharmony_ci        case MKBETAG('c','e','n','c'):
167cabdff1aSopenharmony_ci        case MKBETAG('c','e','n','s'):
168cabdff1aSopenharmony_ci            cenc_info->algo = AV_DRM_ALG_CENC_AES_CTR;
169cabdff1aSopenharmony_ci            break;
170cabdff1aSopenharmony_ci        case MKBETAG('c','b','c','1'):
171cabdff1aSopenharmony_ci        case MKBETAG('c','b','c','s'):
172cabdff1aSopenharmony_ci            cenc_info->algo = AV_DRM_ALG_CENC_AES_CBC;
173cabdff1aSopenharmony_ci            break;
174cabdff1aSopenharmony_ci        case MKBETAG('s','m','4','c'):
175cabdff1aSopenharmony_ci        case MKBETAG('s','m','4','s'):
176cabdff1aSopenharmony_ci            cenc_info->algo = AV_DRM_ALG_CENC_SM4_CBC;
177cabdff1aSopenharmony_ci            break;
178cabdff1aSopenharmony_ci        case MKBETAG('s','m','4','t'):
179cabdff1aSopenharmony_ci        case MKBETAG('s','m','4','r'):
180cabdff1aSopenharmony_ci            cenc_info->algo = AV_DRM_ALG_CENC_SM4_CTR;
181cabdff1aSopenharmony_ci            break;
182cabdff1aSopenharmony_ci        default:
183cabdff1aSopenharmony_ci            cenc_info->algo = AV_DRM_ALG_CENC_UNENCRYPTED;
184cabdff1aSopenharmony_ci            break;
185cabdff1aSopenharmony_ci    }
186cabdff1aSopenharmony_ci    return;
187cabdff1aSopenharmony_ci}
188cabdff1aSopenharmony_ci
189cabdff1aSopenharmony_ciAV_DrmCencInfo *av_encryption_info_add_side_data_ex(const AVEncryptionInfo *info, size_t *side_data_size,
190cabdff1aSopenharmony_ci    AV_DrmCencInfo *cenc_info, int pkt_data_size)
191cabdff1aSopenharmony_ci{
192cabdff1aSopenharmony_ci    uint32_t i;
193cabdff1aSopenharmony_ci    if ((info == NULL) || (info->key_id_size != AV_DRM_KEY_ID_SIZE) || (info->iv_size > AV_DRM_IV_SIZE) ||
194cabdff1aSopenharmony_ci        (info->iv_size == 0) || (info->subsample_count > AV_DRM_MAX_SUB_SAMPLE_NUM) || (info->key_id == NULL) ||
195cabdff1aSopenharmony_ci        (info->iv == NULL) || (info->subsamples == NULL) || (side_data_size == NULL)) {
196cabdff1aSopenharmony_ci        return NULL;
197cabdff1aSopenharmony_ci    }
198cabdff1aSopenharmony_ci
199cabdff1aSopenharmony_ci    *side_data_size = sizeof(AV_DrmCencInfo);
200cabdff1aSopenharmony_ci    cenc_info = av_mallocz(*side_data_size);
201cabdff1aSopenharmony_ci    if (!cenc_info)
202cabdff1aSopenharmony_ci        return NULL;
203cabdff1aSopenharmony_ci
204cabdff1aSopenharmony_ci    av_encryption_info_set_drm_algo(info->scheme, cenc_info);
205cabdff1aSopenharmony_ci    cenc_info->key_id_len = info->key_id_size;
206cabdff1aSopenharmony_ci    memcpy(cenc_info->key_id, info->key_id, info->key_id_size);
207cabdff1aSopenharmony_ci    cenc_info->iv_len = info->iv_size;
208cabdff1aSopenharmony_ci    memcpy(cenc_info->iv, info->iv, info->iv_size);
209cabdff1aSopenharmony_ci    cenc_info->mode = AV_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
210cabdff1aSopenharmony_ci    cenc_info->encrypt_blocks = info->crypt_byte_block;
211cabdff1aSopenharmony_ci    cenc_info->skip_blocks = info->skip_byte_block;
212cabdff1aSopenharmony_ci    cenc_info->first_encrypt_offset = 0;
213cabdff1aSopenharmony_ci    cenc_info->sub_sample_num = info->subsample_count;
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci    for (i = 0; i < cenc_info->sub_sample_num; i++) {
216cabdff1aSopenharmony_ci        cenc_info->sub_samples[i].clear_header_len = info->subsamples[i].bytes_of_clear_data;
217cabdff1aSopenharmony_ci        cenc_info->sub_samples[i].pay_load_len = info->subsamples[i].bytes_of_protected_data;
218cabdff1aSopenharmony_ci    }
219cabdff1aSopenharmony_ci    if ((info->subsample_count == 0) && (info->crypt_byte_block == 0) && (info->skip_byte_block == 0) &&
220cabdff1aSopenharmony_ci        ((info->scheme == MKBETAG('c','e','n','s')) || (info->scheme == MKBETAG('s','m','4','r')))) {
221cabdff1aSopenharmony_ci        cenc_info->sub_sample_num = 1; // 1: sub_sample num
222cabdff1aSopenharmony_ci        cenc_info->sub_samples[0].clear_header_len = 0;
223cabdff1aSopenharmony_ci        cenc_info->sub_samples[0].pay_load_len = (pkt_data_size / 16) * 16; // 16: block size
224cabdff1aSopenharmony_ci        if ((pkt_data_size % 16) != 0) { // 16: block size
225cabdff1aSopenharmony_ci            cenc_info->sub_sample_num = 2; // 2: sub_sample num
226cabdff1aSopenharmony_ci            cenc_info->sub_samples[1].clear_header_len = pkt_data_size % 16; // 16: block size
227cabdff1aSopenharmony_ci            cenc_info->sub_samples[1].pay_load_len = 0;
228cabdff1aSopenharmony_ci        }
229cabdff1aSopenharmony_ci    }
230cabdff1aSopenharmony_ci    return cenc_info;
231cabdff1aSopenharmony_ci}
232cabdff1aSopenharmony_ci#endif
233cabdff1aSopenharmony_ci
234cabdff1aSopenharmony_ci// The format of the AVEncryptionInitInfo side data:
235cabdff1aSopenharmony_ci// u32be init_info_count
236cabdff1aSopenharmony_ci// {
237cabdff1aSopenharmony_ci//   u32be system_id_size
238cabdff1aSopenharmony_ci//   u32be num_key_ids
239cabdff1aSopenharmony_ci//   u32be key_id_size
240cabdff1aSopenharmony_ci//   u32be data_size
241cabdff1aSopenharmony_ci//   u8[system_id_size] system_id
242cabdff1aSopenharmony_ci//   u8[key_id_size][num_key_id] key_ids
243cabdff1aSopenharmony_ci//   u8[data_size] data
244cabdff1aSopenharmony_ci// }[init_info_count]
245cabdff1aSopenharmony_ci
246cabdff1aSopenharmony_ci#define FF_ENCRYPTION_INIT_INFO_EXTRA 16
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_ciAVEncryptionInitInfo *av_encryption_init_info_alloc(
249cabdff1aSopenharmony_ci    uint32_t system_id_size, uint32_t num_key_ids, uint32_t key_id_size, uint32_t data_size)
250cabdff1aSopenharmony_ci{
251cabdff1aSopenharmony_ci    AVEncryptionInitInfo *info;
252cabdff1aSopenharmony_ci    uint32_t i;
253cabdff1aSopenharmony_ci
254cabdff1aSopenharmony_ci    info = av_mallocz(sizeof(*info));
255cabdff1aSopenharmony_ci    if (!info)
256cabdff1aSopenharmony_ci        return NULL;
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_ci    info->system_id = av_mallocz(system_id_size);
259cabdff1aSopenharmony_ci    info->system_id_size = system_id_size;
260cabdff1aSopenharmony_ci    info->key_ids = key_id_size ? av_calloc(num_key_ids, sizeof(*info->key_ids)) : NULL;
261cabdff1aSopenharmony_ci    info->num_key_ids = num_key_ids;
262cabdff1aSopenharmony_ci    info->key_id_size = key_id_size;
263cabdff1aSopenharmony_ci    info->data = av_mallocz(data_size);
264cabdff1aSopenharmony_ci    info->data_size = data_size;
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_ci    // Allow pointers to be NULL if the size is 0.
267cabdff1aSopenharmony_ci    if ((!info->system_id && system_id_size) || (!info->data && data_size) ||
268cabdff1aSopenharmony_ci        (!info->key_ids && num_key_ids && key_id_size)) {
269cabdff1aSopenharmony_ci        av_encryption_init_info_free(info);
270cabdff1aSopenharmony_ci        return NULL;
271cabdff1aSopenharmony_ci    }
272cabdff1aSopenharmony_ci
273cabdff1aSopenharmony_ci    if (key_id_size) {
274cabdff1aSopenharmony_ci        for (i = 0; i < num_key_ids; i++) {
275cabdff1aSopenharmony_ci            info->key_ids[i] = av_mallocz(key_id_size);
276cabdff1aSopenharmony_ci            if (!info->key_ids[i]) {
277cabdff1aSopenharmony_ci                av_encryption_init_info_free(info);
278cabdff1aSopenharmony_ci                return NULL;
279cabdff1aSopenharmony_ci            }
280cabdff1aSopenharmony_ci        }
281cabdff1aSopenharmony_ci    }
282cabdff1aSopenharmony_ci
283cabdff1aSopenharmony_ci    return info;
284cabdff1aSopenharmony_ci}
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_civoid av_encryption_init_info_free(AVEncryptionInitInfo *info)
287cabdff1aSopenharmony_ci{
288cabdff1aSopenharmony_ci    uint32_t i;
289cabdff1aSopenharmony_ci    if (info) {
290cabdff1aSopenharmony_ci        for (i = 0; i < info->num_key_ids; i++) {
291cabdff1aSopenharmony_ci            av_free(info->key_ids[i]);
292cabdff1aSopenharmony_ci        }
293cabdff1aSopenharmony_ci        av_encryption_init_info_free(info->next);
294cabdff1aSopenharmony_ci        av_free(info->system_id);
295cabdff1aSopenharmony_ci        av_free(info->key_ids);
296cabdff1aSopenharmony_ci        av_free(info->data);
297cabdff1aSopenharmony_ci        av_free(info);
298cabdff1aSopenharmony_ci    }
299cabdff1aSopenharmony_ci}
300cabdff1aSopenharmony_ci
301cabdff1aSopenharmony_ciAVEncryptionInitInfo *av_encryption_init_info_get_side_data(
302cabdff1aSopenharmony_ci    const uint8_t *side_data, size_t side_data_size)
303cabdff1aSopenharmony_ci{
304cabdff1aSopenharmony_ci    // |ret| tracks the front of the list, |info| tracks the back.
305cabdff1aSopenharmony_ci    AVEncryptionInitInfo *ret = NULL, *info, *temp_info;
306cabdff1aSopenharmony_ci    uint64_t system_id_size, num_key_ids, key_id_size, data_size, i, j;
307cabdff1aSopenharmony_ci    uint64_t init_info_count;
308cabdff1aSopenharmony_ci
309cabdff1aSopenharmony_ci    if (!side_data || side_data_size < 4)
310cabdff1aSopenharmony_ci        return NULL;
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci    init_info_count = AV_RB32(side_data);
313cabdff1aSopenharmony_ci    side_data += 4;
314cabdff1aSopenharmony_ci    side_data_size -= 4;
315cabdff1aSopenharmony_ci    for (i = 0; i < init_info_count; i++) {
316cabdff1aSopenharmony_ci        if (side_data_size < FF_ENCRYPTION_INIT_INFO_EXTRA) {
317cabdff1aSopenharmony_ci            av_encryption_init_info_free(ret);
318cabdff1aSopenharmony_ci            return NULL;
319cabdff1aSopenharmony_ci        }
320cabdff1aSopenharmony_ci
321cabdff1aSopenharmony_ci        system_id_size = AV_RB32(side_data);
322cabdff1aSopenharmony_ci        num_key_ids = AV_RB32(side_data + 4);
323cabdff1aSopenharmony_ci        key_id_size = AV_RB32(side_data + 8);
324cabdff1aSopenharmony_ci        data_size = AV_RB32(side_data + 12);
325cabdff1aSopenharmony_ci
326cabdff1aSopenharmony_ci        // UINT32_MAX + UINT32_MAX + UINT32_MAX * UINT32_MAX == UINT64_MAX
327cabdff1aSopenharmony_ci        if (side_data_size - FF_ENCRYPTION_INIT_INFO_EXTRA < system_id_size + data_size + num_key_ids * key_id_size) {
328cabdff1aSopenharmony_ci            av_encryption_init_info_free(ret);
329cabdff1aSopenharmony_ci            return NULL;
330cabdff1aSopenharmony_ci        }
331cabdff1aSopenharmony_ci        side_data += FF_ENCRYPTION_INIT_INFO_EXTRA;
332cabdff1aSopenharmony_ci        side_data_size -= FF_ENCRYPTION_INIT_INFO_EXTRA;
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_ci        temp_info = av_encryption_init_info_alloc(system_id_size, num_key_ids, key_id_size, data_size);
335cabdff1aSopenharmony_ci        if (!temp_info) {
336cabdff1aSopenharmony_ci            av_encryption_init_info_free(ret);
337cabdff1aSopenharmony_ci            return NULL;
338cabdff1aSopenharmony_ci        }
339cabdff1aSopenharmony_ci        if (i == 0) {
340cabdff1aSopenharmony_ci            info = ret = temp_info;
341cabdff1aSopenharmony_ci        } else {
342cabdff1aSopenharmony_ci            info->next = temp_info;
343cabdff1aSopenharmony_ci            info = temp_info;
344cabdff1aSopenharmony_ci        }
345cabdff1aSopenharmony_ci
346cabdff1aSopenharmony_ci        memcpy(info->system_id, side_data, system_id_size);
347cabdff1aSopenharmony_ci        side_data += system_id_size;
348cabdff1aSopenharmony_ci        side_data_size -= system_id_size;
349cabdff1aSopenharmony_ci        for (j = 0; j < num_key_ids; j++) {
350cabdff1aSopenharmony_ci            memcpy(info->key_ids[j], side_data, key_id_size);
351cabdff1aSopenharmony_ci            side_data += key_id_size;
352cabdff1aSopenharmony_ci            side_data_size -= key_id_size;
353cabdff1aSopenharmony_ci        }
354cabdff1aSopenharmony_ci        memcpy(info->data, side_data, data_size);
355cabdff1aSopenharmony_ci        side_data += data_size;
356cabdff1aSopenharmony_ci        side_data_size -= data_size;
357cabdff1aSopenharmony_ci    }
358cabdff1aSopenharmony_ci
359cabdff1aSopenharmony_ci    return ret;
360cabdff1aSopenharmony_ci}
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ciuint8_t *av_encryption_init_info_add_side_data(const AVEncryptionInitInfo *info, size_t *side_data_size)
363cabdff1aSopenharmony_ci{
364cabdff1aSopenharmony_ci    const AVEncryptionInitInfo *cur_info;
365cabdff1aSopenharmony_ci    uint8_t *buffer, *cur_buffer;
366cabdff1aSopenharmony_ci    uint32_t i, init_info_count;
367cabdff1aSopenharmony_ci    uint64_t temp_side_data_size;
368cabdff1aSopenharmony_ci
369cabdff1aSopenharmony_ci    temp_side_data_size = 4;
370cabdff1aSopenharmony_ci    init_info_count = 0;
371cabdff1aSopenharmony_ci    for (cur_info = info; cur_info; cur_info = cur_info->next) {
372cabdff1aSopenharmony_ci        temp_side_data_size += (uint64_t)FF_ENCRYPTION_INIT_INFO_EXTRA + cur_info->system_id_size + cur_info->data_size;
373cabdff1aSopenharmony_ci        if (init_info_count == UINT32_MAX || temp_side_data_size > UINT32_MAX) {
374cabdff1aSopenharmony_ci            return NULL;
375cabdff1aSopenharmony_ci        }
376cabdff1aSopenharmony_ci        init_info_count++;
377cabdff1aSopenharmony_ci
378cabdff1aSopenharmony_ci        if (cur_info->num_key_ids) {
379cabdff1aSopenharmony_ci            temp_side_data_size += (uint64_t)cur_info->num_key_ids * cur_info->key_id_size;
380cabdff1aSopenharmony_ci            if (temp_side_data_size > UINT32_MAX) {
381cabdff1aSopenharmony_ci                return NULL;
382cabdff1aSopenharmony_ci            }
383cabdff1aSopenharmony_ci        }
384cabdff1aSopenharmony_ci    }
385cabdff1aSopenharmony_ci    *side_data_size = temp_side_data_size;
386cabdff1aSopenharmony_ci
387cabdff1aSopenharmony_ci    cur_buffer = buffer = av_malloc(*side_data_size);
388cabdff1aSopenharmony_ci    if (!buffer)
389cabdff1aSopenharmony_ci        return NULL;
390cabdff1aSopenharmony_ci
391cabdff1aSopenharmony_ci    AV_WB32(cur_buffer, init_info_count);
392cabdff1aSopenharmony_ci    cur_buffer += 4;
393cabdff1aSopenharmony_ci    for (cur_info = info; cur_info; cur_info = cur_info->next) {
394cabdff1aSopenharmony_ci        AV_WB32(cur_buffer,      cur_info->system_id_size);
395cabdff1aSopenharmony_ci        AV_WB32(cur_buffer +  4, cur_info->num_key_ids);
396cabdff1aSopenharmony_ci        AV_WB32(cur_buffer +  8, cur_info->key_id_size);
397cabdff1aSopenharmony_ci        AV_WB32(cur_buffer + 12, cur_info->data_size);
398cabdff1aSopenharmony_ci        cur_buffer += 16;
399cabdff1aSopenharmony_ci
400cabdff1aSopenharmony_ci        memcpy(cur_buffer, cur_info->system_id, cur_info->system_id_size);
401cabdff1aSopenharmony_ci        cur_buffer += cur_info->system_id_size;
402cabdff1aSopenharmony_ci        for (i = 0; i < cur_info->num_key_ids; i++) {
403cabdff1aSopenharmony_ci            memcpy(cur_buffer, cur_info->key_ids[i], cur_info->key_id_size);
404cabdff1aSopenharmony_ci            cur_buffer += cur_info->key_id_size;
405cabdff1aSopenharmony_ci        }
406cabdff1aSopenharmony_ci        if (cur_info->data_size > 0) {
407cabdff1aSopenharmony_ci            memcpy(cur_buffer, cur_info->data, cur_info->data_size);
408cabdff1aSopenharmony_ci            cur_buffer += cur_info->data_size;
409cabdff1aSopenharmony_ci        }
410cabdff1aSopenharmony_ci    }
411cabdff1aSopenharmony_ci
412cabdff1aSopenharmony_ci    return buffer;
413cabdff1aSopenharmony_ci}
414