1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2018-2020
6 * All rights reserved
7 *
8 * This file is part of GPAC / CENC and ISMA encrypt module
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include <gpac/filters.h>
27 #include <gpac/constants.h>
28 #include <gpac/crypt_tools.h>
29 #include <gpac/crypt.h>
30 #include <gpac/base_coding.h>
31 #include <gpac/download.h>
32 #include <gpac/xml.h>
33 #include <gpac/internal/isomedia_dev.h>
34
35 #include <gpac/internal/media_dev.h>
36
37 #ifndef GPAC_DISABLE_CRYPTO
38
39
40 enum
41 {
42 ISMAEA_STATE_ERROR,
43 ISMAEA_STATE_SETUP,
44 ISMAEA_STATE_PLAY,
45 };
46
47
48 typedef enum {
49 CENC_FULL_SAMPLE,
50
51 /*below types may have several ranges (clear/encrypted) per sample*/
52 CENC_AVC, /*AVC, nalu-based*/
53 CENC_HEVC, /*HEVC, nalu-based*/
54 CENC_AV1, /*AV1, OBU-based*/
55 CENC_VPX, /*VPX, custom, see https://www.webmproject.org/vp9/mp4/ */
56 } CENCCodecMode;
57
58
59 typedef struct
60 {
61 Bool passthrough;
62
63 GF_CryptInfo *cinfo;
64
65 GF_FilterPid *ipid;
66 GF_FilterPid *opid;
67 GF_TrackCryptInfo *tci;
68 GF_Crypt *crypt;
69 u32 codec_id;
70
71 u32 nb_pck;
72
73 //ISMA/OMA var
74 u32 nalu_size_length;
75 u32 dsi_crc;
76 Bool isma_oma;
77 u64 BSO;
78 u64 range_end;
79 Bool prev_pck_encryped;
80 u32 KI_length;
81 u32 isma_IV_size;
82 Bool has_crypted_pck;
83
84 Bool is_adobe;
85 bin128 key;
86
87 CENCCodecMode cenc_codec;
88
89 u32 bytes_in_nal_hdr;
90 Bool use_subsamples;
91 Bool cenc_init;
92 u32 nb_pck_encrypted, kidx;
93 char IV[16];
94 bin128 default_KID;
95
96 //true if using AES-CTR mode, false if using AES-CBC mode
97 Bool ctr_mode;
98
99 #ifndef GPAC_DISABLE_AV_PARSERS
100 AVCState avc;
101 #ifndef GPAC_DISABLE_HEVC
102 HEVCState hevc;
103 #endif
104 AV1State av1;
105 #endif
106 Bool slice_header_clear;
107 } GF_CENCStream;
108
109 typedef struct
110 {
111 //options
112 const char *cfile;
113 Bool allc;
114
115 //internal
116 GF_CryptInfo *cinfo;
117
118 GF_List *streams;
119 GF_BitStream *bs_w, *bs_r;
120 } GF_CENCEncCtx;
121
122
isma_enc_configure(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,Bool is_isma,const char * scheme_uri,const char * kms_uri)123 static GF_Err isma_enc_configure(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, Bool is_isma, const char *scheme_uri, const char *kms_uri)
124 {
125 GF_Err e;
126 bin128 IV;
127 const GF_PropertyValue *p;
128 p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_DECODER_CONFIG);
129 if (!p) p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT);
130
131 switch (cstr->codec_id) {
132 case GF_CODECID_AVC:
133 case GF_CODECID_SVC:
134 case GF_CODECID_MVC:
135 if (p) {
136 GF_AVCConfig *avcc = gf_odf_avc_cfg_read(p->value.data.ptr, p->value.data.size);
137 cstr->nalu_size_length = avcc ? avcc->nal_unit_size : 0;
138 if (avcc) gf_odf_avc_cfg_del(avcc);
139 }
140 if (!cstr->nalu_size_length) {
141 cstr->nalu_size_length = 4;
142 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ISMACrypt] Missing NALU length size, assuming 4\n") );
143 }
144 break;
145 case GF_CODECID_HEVC:
146 case GF_CODECID_LHVC:
147 if (p) {
148 GF_HEVCConfig *hvcc = gf_odf_hevc_cfg_read(p->value.data.ptr, p->value.data.size, (cstr->codec_id==GF_CODECID_LHVC) ? GF_TRUE : GF_FALSE);
149 cstr->nalu_size_length = hvcc ? hvcc->nal_unit_size : 0;
150 if (hvcc) gf_odf_hevc_cfg_del(hvcc);
151 }
152 if (!cstr->nalu_size_length) {
153 cstr->nalu_size_length = 4;
154 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ISMACrypt] Missing NALU length size, assuming 4\n") );
155 }
156 break;
157 }
158
159 if (!scheme_uri || !strlen(scheme_uri)) scheme_uri = "urn:gpac:isma:encryption_scheme";
160
161 if (cstr->tci && ((cstr->tci->sel_enc_type==GF_CRYPT_SELENC_RAND) || (cstr->tci->sel_enc_type==GF_CRYPT_SELENC_RAND_RANGE)) ) {
162 gf_rand_init(1);
163 }
164
165 cstr->isma_IV_size = 0;
166 if (!is_isma) {
167 /*128 bit IV in OMA*/
168 cstr->isma_IV_size = 16;
169 } else {
170 p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_CENC_IV_SIZE);
171 if (p) {
172 cstr->isma_IV_size = p->value.uint;
173 } else {
174 p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_MEDIA_DATA_SIZE);
175 if (p) {
176 u64 BSO = p->value.longuint;
177
178 if (BSO<0xFFFF) cstr->isma_IV_size = 2;
179 else if (BSO<0xFFFFFFFF) cstr->isma_IV_size = 4;
180 else cstr->isma_IV_size = 8;
181 }
182 }
183 if (!cstr->isma_IV_size || (cstr->isma_IV_size > 8)) cstr->isma_IV_size = 8;
184 }
185
186 if (!cstr->tci || !cstr->tci->KID_count) {
187 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMACrypt] No keys specified for ISMA\n"));
188 return GF_BAD_PARAM;
189 }
190
191 /*init crypto*/
192 memset(IV, 0, sizeof(char)*16);
193 memcpy(IV, cstr->tci->first_IV, sizeof(char)*8);
194 if (cstr->crypt) gf_crypt_close(cstr->crypt);
195 cstr->crypt = gf_crypt_open(GF_AES_128, GF_CTR);
196 if (!cstr->crypt) {
197 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMACrypt] Cannot open AES-128 CTR\n"));
198 return GF_IO_ERR;
199 }
200
201 e = gf_crypt_init(cstr->crypt, cstr->tci->keys[0], IV);
202 if (e) {
203 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ISMACrypt] Cannot initialize AES-128 CTR (%s)\n", gf_error_to_string(e)) );
204 return GF_IO_ERR;
205 }
206
207 GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMACrypt] Encrypting stream %s - KMS: %s%s\n", gf_filter_pid_get_name(cstr->ipid), cstr->tci->KMS_URI, cstr->tci->sel_enc_type ? " - Selective Encryption" : ""));
208
209 if (!stricmp(kms_uri, "self")) {
210 char Data[100], d64[100];
211 u32 size_b64;
212 memcpy(Data, cstr->tci->keys[0], sizeof(char)*16);
213 memcpy(Data+16, cstr->tci->first_IV, sizeof(char)*8);
214 size_b64 = gf_base64_encode(Data, 24, d64, 100);
215 d64[size_b64] = 0;
216 cstr->tci->KMS_URI = gf_realloc(cstr->tci->KMS_URI, size_b64+6);
217 strcpy(cstr->tci->KMS_URI, "(key)");
218 strcat(cstr->tci->KMS_URI, d64);
219 kms_uri = cstr->tci->KMS_URI;
220 }
221
222 /*create ISMA protection*/
223 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_PROTECTION_SCHEME_VERSION, &PROP_UINT(1) );
224 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_PROTECTION_KMS_URI, kms_uri ? &PROP_STRING(kms_uri) : NULL);
225 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ISMA_SELECTIVE_ENC, &PROP_BOOL( (cstr->tci->sel_enc_type!=0) ? GF_TRUE : GF_FALSE) );
226 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ISMA_IV_LENGTH, &PROP_UINT(cstr->isma_IV_size) );
227
228 if (is_isma) {
229 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_PROTECTION_SCHEME_URI, scheme_uri ? &PROP_STRING(scheme_uri) : NULL );
230 } else {
231 if ((cstr->tci->sel_enc_type==GF_CRYPT_SELENC_PREVIEW) && cstr->tci->sel_enc_range) {
232 char szSTR[100];
233 u32 len;
234 char *szPreview;
235
236 sprintf(szSTR, "PreviewRange:%d", cstr->tci->sel_enc_range);
237 len = (u32) strlen(szSTR) + ( cstr->tci->TextualHeaders ? (u32) strlen(cstr->tci->TextualHeaders) : 0 ) + 1;
238 szPreview = gf_malloc(sizeof(char) * len);
239 strcpy(szPreview, cstr->tci->TextualHeaders ? cstr->tci->TextualHeaders : "");
240 strcat(szPreview, szSTR);
241
242 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_OMA_TXT_HDR, &PROP_STRING_NO_COPY(szPreview));
243 } else {
244 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_OMA_TXT_HDR, cstr->tci->TextualHeaders ? &PROP_STRING(cstr->tci->TextualHeaders) : NULL);
245 }
246
247 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_OMA_CID, scheme_uri ? &PROP_STRING(scheme_uri) : NULL );
248
249 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_OMA_CRYPT_TYPE, &PROP_UINT(cstr->tci->encryption));
250 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_OMA_CLEAR_LEN, &PROP_LONGUINT(cstr->tci->sel_enc_range) );
251 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ISMA_KI_LENGTH, &PROP_UINT(0) );
252 }
253
254 cstr->range_end = 0;
255 if (cstr->tci->sel_enc_type==GF_CRYPT_SELENC_PREVIEW) {
256 p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_TIMESCALE);
257 if (p)
258 cstr->range_end = p->value.uint *cstr->tci->sel_enc_range;
259 }
260
261 cstr->isma_oma = GF_TRUE;
262 cstr->prev_pck_encryped = GF_TRUE;
263 cstr->has_crypted_pck = GF_FALSE;
264
265 //we drop IPMPX support for now
266 #if GPAC_DEPRECTAED
267 /*format as IPMP(X) - note that the ISMACryp spec is broken since it always uses IPMPPointers to a
268 single desc which would assume the same protection (eg key & salt) for all streams using it...*/
269 if (!tci->ipmp_type) return GF_OK;
270
271 ipmpdp = (GF_IPMPPtr*)gf_odf_desc_new(GF_ODF_IPMP_PTR_TAG);
272 if (!tci->ipmp_desc_id) tci->ipmp_desc_id = track;
273 if (tci->ipmp_type==2) {
274 ipmpdp->IPMP_DescriptorID = 0xFF;
275 ipmpdp->IPMP_DescriptorIDEx = tci->ipmp_desc_id;
276 } else {
277 ipmpdp->IPMP_DescriptorID = tci->ipmp_desc_id;
278 }
279 gf_isom_add_desc_to_description(mp4, track, 1, (GF_Descriptor *)ipmpdp);
280 gf_odf_desc_del((GF_Descriptor*)ipmpdp);
281
282 ipmpdU = (GF_IPMPUpdate*)gf_odf_com_new(GF_ODF_IPMP_UPDATE_TAG);
283 /*format IPMPD*/
284 ipmpd = (GF_IPMP_Descriptor*)gf_odf_desc_new(GF_ODF_IPMP_TAG);
285 if (tci->ipmp_type==2) {
286 #ifndef GPAC_MINIMAL_ODF
287 ipmpd->IPMP_DescriptorID = 0xFF;
288 ipmpd->IPMP_DescriptorIDEx = tci->ipmp_desc_id;
289 ipmpd->IPMPS_Type = 0xFFFF;
290 ipmpd->IPMP_ToolID[14] = 0x49;
291 ipmpd->IPMP_ToolID[15] = 0x53;
292 ipmpd->control_point = 1;
293 ipmpd->cp_sequence_code = 0x80;
294 /*format IPMPXData*/
295 ismac = (GF_IPMPX_ISMACryp *) gf_ipmpx_data_new(GF_IPMPX_ISMACRYP_TAG);
296 ismac->cryptoSuite = 1; /*default ISMA AESCTR128*/
297 ismac->IV_length = IV_size;
298 ismac->key_indicator_length = 0;
299 ismac->use_selective_encryption = (tci->sel_enc_type!=0)? 1 : 0;
300 gf_list_add(ipmpd->ipmpx_data, ismac);
301 #endif
302 } else {
303 ipmpd->IPMP_DescriptorID = tci->ipmp_desc_id;
304 }
305 gf_list_add(ipmpdU->IPMPDescList, ipmpd);
306
307 for (i=0; i<gf_isom_get_track_count(mp4); i++) {
308 GF_ODCodec *cod;
309 if (gf_isom_get_media_type(mp4, i+1) != GF_ISOM_MEDIA_OD) continue;
310
311 /*add com*/
312 samp = gf_isom_get_sample(mp4, i+1, 1, &di);
313 cod = gf_odf_codec_new();
314 gf_odf_codec_set_au(cod, samp->data, samp->dataLength);
315 gf_odf_codec_decode(cod);
316 gf_odf_codec_add_com(cod, (GF_ODCom *) ipmpdU);
317 gf_free(samp->data);
318 samp->data = NULL;
319 samp->dataLength = 0;
320 gf_odf_codec_encode(cod, 1);
321 gf_odf_codec_get_au(cod, &samp->data, &samp->dataLength);
322 ipmpdU = NULL;
323 gf_odf_codec_del(cod);
324 gf_isom_update_sample(mp4, i+1, 1, samp, 1);
325 gf_isom_sample_del(&samp);
326
327 if (tci->ipmp_type==2) {
328 GF_IPMP_ToolList*ipmptl = (GF_IPMP_ToolList*)gf_odf_desc_new(GF_ODF_IPMP_TL_TAG);
329 GF_IPMP_Tool *ipmpt = (GF_IPMP_Tool*)gf_odf_desc_new(GF_ODF_IPMP_TOOL_TAG);
330 gf_list_add(ipmptl->ipmp_tools, ipmpt);
331 ipmpt->IPMP_ToolID[14] = 0x49;
332 ipmpt->IPMP_ToolID[15] = 0x53;
333 gf_isom_add_desc_to_root_od(mp4, (GF_Descriptor *)ipmptl);
334 gf_odf_desc_del((GF_Descriptor *)ipmptl);
335 }
336 break;
337 }
338 #endif
339 return GF_OK;
340 }
341
adobe_enc_configure(GF_CENCEncCtx * ctx,GF_CENCStream * cstr)342 static GF_Err adobe_enc_configure(GF_CENCEncCtx *ctx, GF_CENCStream *cstr)
343 {
344 if (cstr->crypt) gf_crypt_close(cstr->crypt);
345 cstr->crypt = gf_crypt_open(GF_AES_128, GF_CBC);
346 if (!cstr->crypt) {
347 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[Adobe] Cannot open AES-128 CBC \n"));
348 return GF_IO_ERR;
349 }
350
351 /*Adobe's protection scheme does not support selective key*/
352 memcpy(cstr->key, cstr->tci->keys[0], 16);
353
354 if (cstr->tci->metadata)
355 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ADOBE_CRYPT_META, &PROP_DATA(cstr->tci->metadata, (u32) strlen(cstr->tci->metadata) ) );
356
357 cstr->is_adobe = GF_TRUE;
358
359 return GF_OK;
360 }
361
cenc_parse_pssh(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,const char * cfile_name)362 static GF_Err cenc_parse_pssh(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, const char *cfile_name)
363 {
364 GF_DOMParser *parser;
365 GF_XMLNode *root, *node;
366 u32 i;
367 GF_Err e;
368 u32 nb_pssh=0;
369 GF_BitStream *pssh_bs=NULL;
370
371 parser = gf_xml_dom_new();
372 e = gf_xml_dom_parse(parser, cfile_name, NULL, NULL);
373 if (e) {
374 gf_xml_dom_del(parser);
375 return e;
376 }
377 root = gf_xml_dom_get_root(parser);
378 if (!root) {
379 gf_xml_dom_del(parser);
380 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC/ISMA] Cannot open or validate xml file %s\n", ctx->cfile));
381 return GF_NOT_SUPPORTED;
382 }
383 pssh_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
384 gf_bs_write_u32(pssh_bs, 0);
385
386 i=0;
387 while ((node = (GF_XMLNode *) gf_list_enum(root->content, &i))) {
388 Bool is_pssh;
389 u32 version, cypherMode, specInfoSize, len, KID_count, j;
390 bin128 cypherKey, cypherIV, systemID;
391 GF_XMLAttribute *att;
392 u8 *data, *specInfo;
393 GF_BitStream *bs;
394 bin128 *KIDs;
395 s32 cypherOffset = -1;
396 Bool has_key = GF_FALSE, has_IV = GF_FALSE;
397
398 if (strcmp(node->name, "DRMInfo")) continue;
399
400 j = 0;
401 is_pssh = GF_FALSE;
402 version = cypherMode = 0;
403 data = specInfo = NULL;
404 bs = NULL;
405
406 while ( (att = (GF_XMLAttribute *)gf_list_enum(node->attributes, &j))) {
407 if (!strcmp(att->name, "type")) {
408 if (!strcmp(att->value, "pssh"))
409 is_pssh = GF_TRUE;
410 } else if (!strcmp(att->name, "version")) {
411 version = atoi(att->value);
412 } else if (!strcmp(att->name, "cypherMode")) {
413 /*cypher-mode: 0: ctr (default mode) - 1: cbc - 2: clear*/
414 if (!strcmp(att->value, "yes"))
415 cypherMode = 0;
416 else if (!strcmp(att->value, "no"))
417 cypherMode = 1;
418 } else if (!strcmp(att->name, "cypherKey")) {
419 e = gf_bin128_parse(att->value, cypherKey);
420 if (e != GF_OK) {
421 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannnot parse cypherKey\n"));
422 return e;
423 }
424 has_key = GF_TRUE;
425 } else if (!strcmp(att->name, "cypherIV")) {
426 e = gf_bin128_parse(att->value, cypherIV);
427 if (e != GF_OK) {
428 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannnot parse cypherIV\n"));
429 return e;
430 }
431 has_IV = GF_TRUE;
432 } else if (!strcmp(att->name, "cypherOffset")) {
433 cypherOffset = atoi(att->value);
434 }
435 }
436
437 if (!is_pssh) {
438 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[CENC/ISMA] Not a Protection System Specific Header Box - skipping\n"));
439 continue;
440 }
441
442 e = gf_xml_parse_bit_sequence(node, cfile_name, &specInfo, &specInfoSize);
443 if (e) {
444 if (specInfo) gf_free(specInfo);
445 gf_xml_dom_del(parser);
446 return e;
447 }
448
449 bs = gf_bs_new(specInfo, specInfoSize, GF_BITSTREAM_READ);
450 gf_bs_read_data(bs, (char *)systemID, 16);
451 if (version) {
452 KID_count = gf_bs_read_u32(bs);
453 KIDs = (bin128 *)gf_malloc(KID_count*sizeof(bin128));
454 for (j = 0; j < KID_count; j++) {
455 gf_bs_read_data(bs, (char *)KIDs[j], 16);
456 }
457 }
458 else {
459 KID_count = 0;
460 KIDs = NULL;
461 }
462 if (specInfoSize < 16 + (version ? 4 + 16*KID_count : 0)) {
463 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[CENC/ISMA] Invalid PSSH blob in version %d: size %d key count %d - ignoring PSSH\n", version, specInfoSize, KID_count));
464 continue;
465 }
466 len = specInfoSize - 16 - (version ? 4 + 16*KID_count : 0);
467 data = (char *)gf_malloc(len*sizeof(char));
468 gf_bs_read_data(bs, data, len);
469
470 if (has_key && has_IV && (cypherOffset >= 0) && (cypherMode != 1)) {
471 GF_Crypt *gc = gf_crypt_open(GF_AES_128, GF_CTR);
472 if (!gc) {
473 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC/ISMA] Cannot open AES-128 CTR\n"));
474 return GF_IO_ERR;
475 }
476 e = gf_crypt_init(gc, cypherKey, cypherIV);
477 gf_crypt_encrypt(gc, data+cypherOffset, len-cypherOffset);
478 gf_crypt_close(gc);
479 }
480 if (!e) {
481 nb_pssh++;
482 gf_bs_write_data(pssh_bs, systemID, 16);
483 gf_bs_write_u32(pssh_bs, version);
484 gf_bs_write_u32(pssh_bs, KID_count);
485 for (j=0; j<KID_count; j++) {
486 gf_bs_write_data(pssh_bs, KIDs[j], 16);
487 }
488 gf_bs_write_u32(pssh_bs, len);
489 gf_bs_write_data(pssh_bs, data, len);
490 }
491
492 if (specInfo) gf_free(specInfo);
493 if (data) gf_free(data);
494 if (KIDs) gf_free(KIDs);
495 if (bs) gf_bs_del(bs);
496 if (e) break;
497 }
498
499 gf_xml_dom_del(parser);
500
501 if (nb_pssh) {
502 u8 *pssh=NULL;
503 u32 pssh_size=0;
504 u32 pos = (u32) gf_bs_get_position(pssh_bs);
505 gf_bs_seek(pssh_bs, 0);
506 gf_bs_write_u32(pssh_bs, nb_pssh);
507 gf_bs_seek(pssh_bs, pos);
508 gf_bs_get_content(pssh_bs, &pssh, &pssh_size);
509 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_PSSH, &PROP_DATA_NO_COPY(pssh, pssh_size));
510 }
511 gf_bs_del(pssh_bs);
512
513 return e;
514 }
515
516
cenc_enc_configure(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,const char * cfile_name)517 static GF_Err cenc_enc_configure(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, const char *cfile_name)
518 {
519 #if !defined(GPAC_DISABLE_AV_PARSERS)
520 u32 i;
521 #endif
522 u32 dsi_crc=0;
523 Bool is_reinit=GF_FALSE;
524 GF_AVCConfig *avccfg;
525 GF_HEVCConfig *hevccfg;
526 const GF_PropertyValue *p;
527
528 p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_DECODER_CONFIG);
529 if (!p) p = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT);
530
531 if (p) {
532 dsi_crc = gf_crc_32(p->value.data.ptr, p->value.data.size);
533 }
534 if (dsi_crc != cstr->dsi_crc)
535 is_reinit = GF_TRUE;
536 else if (!dsi_crc && !cstr->crypt)
537 is_reinit = GF_TRUE;
538
539 cstr->dsi_crc = dsi_crc;
540
541 if (is_reinit) {
542 const GF_PropertyValue *p2;
543 cstr->nalu_size_length = 0;
544 switch (cstr->codec_id) {
545 case GF_CODECID_AVC:
546 case GF_CODECID_SVC:
547 case GF_CODECID_MVC:
548 if (!p)
549 return GF_OK;
550
551 avccfg = gf_odf_avc_cfg_read(p->value.data.ptr, p->value.data.size);
552 if (avccfg) cstr->nalu_size_length = avccfg->nal_unit_size;
553
554 cstr->cenc_codec = CENC_AVC;
555
556 p2 = gf_filter_pid_get_property(cstr->ipid, GF_PROP_PID_ISOM_SUBTYPE);
557 if (p2 && (p2->value.uint==GF_ISOM_BOX_TYPE_AVC1)) {
558 if (!cstr->tci->allow_encrypted_slice_header) {
559 cstr->slice_header_clear = GF_TRUE;
560 } else if (cstr->tci->scheme_type==GF_CRYPT_TYPE_CBCS) {
561 cstr->slice_header_clear = GF_TRUE;
562 }
563 } else {
564 cstr->slice_header_clear = GF_TRUE;
565 }
566 #ifndef GPAC_DISABLE_AV_PARSERS
567 if (avccfg) {
568 for (i=0; i<gf_list_count(avccfg->sequenceParameterSets); i++) {
569 GF_AVCConfigSlot *slc = gf_list_get(avccfg->sequenceParameterSets, i);
570 gf_media_avc_read_sps(slc->data, slc->size, &cstr->avc, 0, NULL);
571 }
572 for (i=0; i<gf_list_count(avccfg->pictureParameterSets); i++) {
573 GF_AVCConfigSlot *slc = gf_list_get(avccfg->pictureParameterSets, i);
574 gf_media_avc_read_pps(slc->data, slc->size, &cstr->avc);
575 }
576
577 gf_odf_avc_cfg_del(avccfg);
578 }
579 #else
580 if (avccfg) gf_odf_avc_cfg_del(avccfg);
581 #endif
582 cstr->bytes_in_nal_hdr = 1;
583
584 if (!cstr->slice_header_clear && cstr->tci->clear_bytes)
585 cstr->bytes_in_nal_hdr = cstr->tci->clear_bytes;
586
587 if (!cstr->nalu_size_length) {
588 cstr->nalu_size_length = 4;
589 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[CENCCrypt] Missing NALU length size, assuming 4\n") );
590 }
591 break;
592 case GF_CODECID_HEVC:
593 case GF_CODECID_LHVC:
594 if (!p)
595 return GF_OK;
596
597 hevccfg = gf_odf_hevc_cfg_read(p->value.data.ptr, p->value.data.size, (cstr->codec_id==GF_CODECID_LHVC) ? GF_TRUE : GF_FALSE);
598 if (hevccfg) cstr->nalu_size_length = hevccfg->nal_unit_size;
599
600 #if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC)
601 gf_media_hevc_parse_ps(hevccfg, &cstr->hevc, GF_HEVC_NALU_VID_PARAM);
602 gf_media_hevc_parse_ps(hevccfg, &cstr->hevc, GF_HEVC_NALU_SEQ_PARAM);
603 gf_media_hevc_parse_ps(hevccfg, &cstr->hevc, GF_HEVC_NALU_PIC_PARAM);
604 #endif
605
606 //mandatory for HEVC
607 cstr->slice_header_clear = GF_TRUE;
608
609 cstr->cenc_codec = CENC_HEVC;
610
611 if (hevccfg) gf_odf_hevc_cfg_del(hevccfg);
612 cstr->bytes_in_nal_hdr = 2;
613
614 if (!cstr->nalu_size_length) {
615 cstr->nalu_size_length = 4;
616 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[CENCCrypt] Missing NALU length size, assuming 4\n") );
617 }
618 break;
619 case GF_CODECID_AV1:
620 if (!p)
621 return GF_OK;
622
623 #if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_AV1)
624 cstr->av1.config = gf_odf_av1_cfg_read(p->value.data.ptr, p->value.data.size);
625 cstr->cenc_codec = CENC_AV1;
626 cstr->bytes_in_nal_hdr = 2;
627 #endif
628 //mandatory for AV1
629 cstr->slice_header_clear = GF_TRUE;
630 break;
631 case GF_CODECID_VP8:
632 case GF_CODECID_VP9:
633 if (p) {
634 cstr->cenc_codec = CENC_VPX;
635 cstr->bytes_in_nal_hdr = 2;
636 }
637 break;
638 }
639 }
640
641 if (((cstr->tci->scheme_type == GF_CRYPT_TYPE_CENS) || (cstr->tci->scheme_type == GF_CRYPT_TYPE_CBCS) ) && (cstr->cenc_codec>CENC_FULL_SAMPLE) && (cstr->cenc_codec<=CENC_AV1)
642 ) {
643 if (!cstr->tci->crypt_byte_block || !cstr->tci->skip_byte_block) {
644 if (cstr->tci->crypt_byte_block || cstr->tci->skip_byte_block) {
645 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[CENC] Using pattern mode, crypt_byte_block and skip_byte_block shall be 0 only for track other than video, using 1 crypt + 9 skip\n"));
646 }
647 cstr->tci->crypt_byte_block = 1;
648 cstr->tci->skip_byte_block = 9;
649 }
650 }
651
652 if ( (cstr->cenc_codec==CENC_VPX) && (cstr->tci->scheme_type != GF_CRYPT_TYPE_CENC) ) {
653 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Encryption mode %s is not supported with VP8/VP9, only cenc is\n", gf_4cc_to_str(cstr->tci->scheme_type) ));
654 return GF_NOT_SUPPORTED;
655 }
656
657
658 cstr->use_subsamples = GF_FALSE;
659 if (cstr->cenc_codec != CENC_FULL_SAMPLE) cstr->use_subsamples = GF_TRUE;
660 //CBCS mode with skip byte block may be used for any track, in which case we need subsamples
661 else if (cstr->tci->scheme_type == GF_CRYPT_TYPE_CBCS) {
662 if (cstr->tci->skip_byte_block) {
663 cstr->use_subsamples = GF_TRUE;
664 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("\n[CENC] Using cbcs pattern mode on non NAL video track, this may not be supported by most devices; consider setting skip_byte_block to 0\n\n"));
665 //cbcs allows bytes of clear data
666 cstr->bytes_in_nal_hdr = cstr->tci->clear_bytes;
667 }
668 //This is not clear in the spec, setting skip and crypt to 0 means no pattern, in which case tenc version shall be 0
669 //but cbcs asks for 1 - needs further clarification
670 #if 0
671 //setup defaults
672 else if (!cstr->tci->crypt_byte_block) {
673 cstr->tci->crypt_byte_block = 1;
674 }
675 #else
676 else {
677 cstr->tci->crypt_byte_block = 0;
678 }
679 #endif
680 }
681 else if ((cstr->tci->scheme_type == GF_CRYPT_TYPE_CENS) && cstr->tci->skip_byte_block) {
682 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[CENC] Using cens pattern mode on non NAL video track not allowed, forcing skip_byte_block to 0\n"));
683 cstr->tci->skip_byte_block = 0;
684 if (!cstr->tci->crypt_byte_block) {
685 cstr->tci->crypt_byte_block = 1;
686 }
687 }
688
689 if (is_reinit) {
690 if (cstr->crypt) gf_crypt_close(cstr->crypt);
691 if (cstr->ctr_mode) {
692 cstr->crypt = gf_crypt_open(GF_AES_128, GF_CTR);
693 }
694 else {
695 cstr->crypt = gf_crypt_open(GF_AES_128, GF_CBC);
696 }
697
698 if (!cstr->crypt) {
699 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot open AES-128 %s\n", cstr->ctr_mode ? "CTR" : "CBC"));
700 return GF_IO_ERR;
701 }
702
703 /*select key*/
704 if (!cstr->tci->keys) {
705 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] No key specified\n"));
706 return GF_BAD_PARAM;
707 }
708 if (cstr->tci->defaultKeyIdx && (cstr->tci->defaultKeyIdx < cstr->tci->KID_count)) {
709 memcpy(cstr->key, cstr->tci->keys[cstr->tci->defaultKeyIdx], 16);
710 memcpy(cstr->default_KID, cstr->tci->KIDs[cstr->tci->defaultKeyIdx], 16);
711 cstr->kidx = cstr->tci->defaultKeyIdx;
712 } else {
713 memcpy(cstr->key, cstr->tci->keys[0], 16);
714 memcpy(cstr->default_KID, cstr->tci->KIDs[0], 16);
715 cstr->kidx = 0;
716 }
717 cstr->prev_pck_encryped = cstr->tci->IsEncrypted;
718 }
719
720 /*set CENC protection properties*/
721
722 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_PROTECTION_SCHEME_VERSION, &PROP_UINT(0x00010000) );
723 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ENCRYPTED, &PROP_BOOL(cstr->tci->IsEncrypted ? GF_TRUE : GF_FALSE) );
724
725 if (cstr->tci->IV_size) {
726 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_IV_SIZE, &PROP_UINT(cstr->tci->IV_size) );
727 } else {
728 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_IV_SIZE, NULL);
729 }
730 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_KID, &PROP_DATA(cstr->default_KID, sizeof(bin128) ) );
731
732 if (cstr->tci->skip_byte_block || cstr->tci->crypt_byte_block) {
733 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_PATTERN, &PROP_FRAC_INT(cstr->tci->skip_byte_block, cstr->tci->crypt_byte_block ) );
734 } else {
735 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_PATTERN, NULL);
736 }
737 if (cstr->tci->constant_IV_size) {
738 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_IV_CONST, &PROP_DATA(cstr->tci->constant_IV, cstr->tci->constant_IV_size) );
739 } else {
740 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_IV_CONST, NULL );
741 }
742 //if constantIV and not using CENC subsample, no CENC auxiliary info
743 if (!cstr->tci->constant_IV_size || cstr->use_subsamples) {
744 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_STORE, &PROP_UINT(cstr->tci->sai_saved_box_type) );
745 }
746
747 //parse pssh even if reinit since we need to reassign pssh property
748 return cenc_parse_pssh(ctx, cstr, cfile_name);
749 }
750
cenc_enc_configure_pid(GF_Filter * filter,GF_FilterPid * pid,Bool is_remove)751 static GF_Err cenc_enc_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
752 {
753 const GF_PropertyValue *prop;
754 GF_Err e = GF_OK;
755 u32 scheme_type = 0;
756 GF_TrackCryptInfo *tci = NULL;
757 const char *scheme_uri = NULL;
758 const char *kms_uri = NULL;
759 GF_CryptInfo *cinfo = NULL;
760 GF_CENCStream *cstr;
761 GF_CENCEncCtx *ctx = (GF_CENCEncCtx *)gf_filter_get_udta(filter);
762 const char *cfile_name = ctx->cfile;
763 GF_TrackCryptInfo *tci_any = NULL;
764 u32 i, count;
765
766
767 if (is_remove) {
768 cstr = gf_filter_pid_get_udta(pid);
769 if (cstr) {
770 gf_list_del_item(ctx->streams, cstr);
771 gf_filter_pid_remove(cstr->opid);
772 if (cstr->crypt) gf_crypt_close(cstr->crypt);
773 if (cstr->cinfo) gf_crypt_info_del(cstr->cinfo);
774 gf_free(cstr);
775 }
776 return GF_OK;
777 }
778
779 if (! gf_filter_pid_check_caps(pid))
780 return GF_NOT_SUPPORTED;
781
782 prop = gf_filter_pid_get_property(pid, GF_PROP_PID_CRYPT_INFO);
783 if (prop) {
784 cinfo = gf_crypt_info_load(prop->value.string, &e);
785 if (!cinfo) {
786 GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[CENCrypt] failed to load crypt info file %s for pid %s\n", prop->value.string, gf_filter_pid_get_name(pid) ) );
787 return e;
788 }
789 cfile_name = prop->value.string;
790 }
791 if (!cinfo) cinfo = ctx->cinfo;
792
793
794 if (cinfo) {
795 prop = gf_filter_pid_get_property(pid, GF_PROP_PID_ID);
796 count = gf_list_count(cinfo->tcis);
797 for (i=0; i<count; i++) {
798 tci = gf_list_get(cinfo->tcis, i);
799 if (prop && tci->trackID && (tci->trackID==prop->value.uint)) break;
800 if (!tci_any && !tci->trackID) tci_any = tci;
801 if ((cinfo != ctx->cinfo) && !tci_any) tci_any = tci;
802 tci = NULL;
803 }
804 if (!tci) tci = tci_any;
805 } else if (ctx->allc) {
806 GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[CENCrypt] Missing DRM config file\n") );
807 return GF_NOT_SUPPORTED;
808 }
809
810 if (!tci) {
811 if (cinfo) {
812 GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[CENCrypt] Missing track crypt info in DRM config file, PID will not be crypted\n") );
813 }
814 } else {
815 scheme_type = tci->scheme_type;
816
817 switch (scheme_type) {
818 case GF_CRYPT_TYPE_ISMA:
819 case GF_CRYPT_TYPE_OMA:
820 case GF_CRYPT_TYPE_ADOBE:
821 case GF_CRYPT_TYPE_CENC:
822 case GF_CRYPT_TYPE_CBC1:
823 case GF_CRYPT_TYPE_CENS:
824 case GF_CRYPT_TYPE_CBCS:
825 case GF_CRYPT_TYPE_PIFF:
826 break;
827 default:
828 GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[CENCrypt] Unsupported scheme type %s\n", gf_4cc_to_str(scheme_type) ));
829 if (cinfo != ctx->cinfo) gf_crypt_info_del(cinfo);
830 return GF_NOT_SUPPORTED;
831 }
832 }
833
834 cstr = gf_filter_pid_get_udta(pid);
835 if (!cstr) {
836 GF_SAFEALLOC(cstr, GF_CENCStream);
837 if (!cstr) return GF_OUT_OF_MEM;
838 cstr->ipid = pid;
839 cstr->opid = gf_filter_pid_new(filter);
840 cstr->tci = tci;
841 gf_list_add(ctx->streams, cstr);
842 gf_filter_pid_set_udta(pid, cstr);
843 }
844 if (cstr->cinfo) gf_crypt_info_del(cstr->cinfo);
845 cstr->cinfo = (cinfo != ctx->cinfo) ? cinfo : NULL;
846 cstr->tci = tci;
847 cstr->passthrough = tci ? GF_FALSE : GF_TRUE;
848
849 //copy properties at init or reconfig
850 gf_filter_pid_copy_properties(cstr->opid, pid);
851
852 prop = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
853 if (prop) cstr->codec_id = prop->value.uint;
854
855 if (cstr->tci) {
856 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_PROTECTION_SCHEME_TYPE, &PROP_UINT(scheme_type) );
857
858
859 prop = gf_filter_pid_get_property(pid, GF_PROP_PID_STREAM_TYPE);
860 if (prop) {
861 switch (prop->value.uint) {
862 case GF_STREAM_VISUAL:
863 case GF_STREAM_AUDIO:
864 case GF_STREAM_SCENE:
865 case GF_STREAM_FONT:
866 case GF_STREAM_TEXT:
867 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_ORIG_STREAM_TYPE, & PROP_UINT(prop->value.uint) );
868 break;
869 default:
870 GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[CENCrypt] Stream type %s cannot be encrypted, using passthrough\n", gf_stream_type_name(prop->value.uint) ));
871 cstr->passthrough = GF_TRUE;
872 break;
873 }
874 }
875 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_CENC_STSD_MODE, &PROP_UINT(tci->force_clear_stsd_idx) );
876 }
877
878 if (cstr->passthrough) return GF_OK;
879
880 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_ENCRYPTED) );
881
882 scheme_uri = cstr->tci->Scheme_URI;
883 kms_uri = cstr->tci->KMS_URI;
884
885 /*default to FILE uri*/
886 if (!kms_uri || !strlen(kms_uri) ) {
887 kms_uri = cfile_name;
888 }
889
890 cstr->ctr_mode = GF_FALSE;
891
892 switch (scheme_type) {
893 case GF_CRYPT_TYPE_ISMA:
894 cstr->ctr_mode = GF_TRUE;
895 return isma_enc_configure(ctx, cstr, GF_TRUE, scheme_uri, kms_uri);
896 case GF_CRYPT_TYPE_OMA:
897 return isma_enc_configure(ctx, cstr, GF_FALSE, scheme_uri, kms_uri);
898 case GF_CRYPT_TYPE_ADOBE:
899 return adobe_enc_configure(ctx, cstr);
900 case GF_CRYPT_TYPE_CENC:
901 case GF_CRYPT_TYPE_CENS:
902 case GF_CRYPT_TYPE_PIFF:
903 cstr->ctr_mode = GF_TRUE;
904 case GF_CRYPT_TYPE_CBC1:
905 case GF_CRYPT_TYPE_CBCS:
906 return cenc_enc_configure(ctx, cstr, cfile_name);
907 default:
908 return GF_NOT_SUPPORTED;
909 }
910
911 return e;
912 }
913
914
isma_process(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,GF_FilterPacket * pck)915 static GF_Err isma_process(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_FilterPacket *pck)
916 {
917 u32 isma_hdr_size=0;
918 GF_FilterPacket *dst_pck;
919 const u8 *data;
920 u8 *output;
921 u32 size, rand, flags;
922 u64 cts = gf_filter_pck_get_cts(pck);
923 u8 sap = gf_filter_pck_get_sap(pck);
924
925
926 flags = 0;
927
928 switch (cstr->tci->sel_enc_type) {
929 case GF_CRYPT_SELENC_RAP:
930 if (sap) flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
931 break;
932 case GF_CRYPT_SELENC_NON_RAP:
933 if (!sap) flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
934 break;
935 /*random*/
936 case GF_CRYPT_SELENC_RAND:
937 rand = gf_rand();
938 if (rand%2) flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
939 break;
940 /*random every sel_freq samples*/
941 case GF_CRYPT_SELENC_RAND_RANGE:
942 if (! (cstr->nb_pck % cstr->tci->sel_enc_range) ) cstr->has_crypted_pck = 0;
943 if (! cstr->has_crypted_pck) {
944 rand = gf_rand();
945 if (!(rand % cstr->tci->sel_enc_range)) flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
946
947 if (!(flags & GF_ISOM_ISMA_IS_ENCRYPTED) && !( (1+cstr->nb_pck) % cstr->tci->sel_enc_range)) {
948 flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
949 }
950 cstr->has_crypted_pck = (flags & GF_ISOM_ISMA_IS_ENCRYPTED);
951 }
952 break;
953 /*every sel_freq samples*/
954 case GF_CRYPT_SELENC_RANGE:
955 if (!(cstr->nb_pck % cstr->tci->sel_enc_type)) flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
956 break;
957 case GF_CRYPT_SELENC_PREVIEW:
958 if (cts >= cstr->range_end)
959 flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
960 break;
961 case 0:
962 flags |= GF_ISOM_ISMA_IS_ENCRYPTED;
963 break;
964 default:
965 break;
966 }
967
968 if (cstr->tci->sel_enc_type) flags |= GF_ISOM_ISMA_USE_SEL_ENC;
969
970 if (flags & GF_ISOM_ISMA_USE_SEL_ENC) isma_hdr_size = 1;
971 if (flags & GF_ISOM_ISMA_IS_ENCRYPTED) isma_hdr_size += cstr->isma_IV_size + cstr->KI_length;
972
973 data = gf_filter_pck_get_data(pck, &size);
974 if (!data) {
975 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMACrypt] No data associated with packet\n" ));
976 return GF_OK;
977 }
978 dst_pck = gf_filter_pck_new_alloc(cstr->opid, size+isma_hdr_size, &output);
979 memcpy(output+isma_hdr_size, data, sizeof(char)*size);
980 gf_filter_pck_merge_properties(pck, dst_pck);
981
982
983 /*isma e&a stores AVC1 in AVC/H264 annex B bitstream fashion, with 0x00000001 start codes*/
984 if (cstr->nalu_size_length) {
985 u32 done = 0;
986 u8 *d = (u8*) output+isma_hdr_size;
987 while (done < size) {
988 u32 nal_size = GF_4CC(d[0], d[1], d[2], d[3]);
989 d[0] = d[1] = d[2] = 0;
990 d[3] = 1;
991 d += 4 + nal_size;
992 done += 4 + nal_size;
993 }
994 }
995
996 //encrypt
997 if (flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
998 /*resync IV*/
999 if (!cstr->prev_pck_encryped) {
1000 char IV[17];
1001 u64 count;
1002 u32 remain;
1003 GF_BitStream *bs;
1004 count = cstr->BSO / 16;
1005 remain = (u32) (cstr->BSO % 16);
1006
1007 /*format IV to begin of counter*/
1008 bs = gf_bs_new(IV, 17, GF_BITSTREAM_WRITE);
1009 gf_bs_write_u8(bs, 0); /*begin of counter*/
1010 gf_bs_write_data(bs, cstr->tci->first_IV, 8);
1011 gf_bs_write_u64(bs, (s64) count);
1012 gf_bs_del(bs);
1013 gf_crypt_set_IV(cstr->crypt, IV, GF_AES_128_KEYSIZE+1);
1014
1015 /*decrypt remain bytes*/
1016 if (remain) {
1017 char dummy[20];
1018 gf_crypt_decrypt(cstr->crypt, dummy, remain);
1019 }
1020 }
1021 gf_crypt_encrypt(cstr->crypt, output+isma_hdr_size, size);
1022 cstr->prev_pck_encryped = GF_TRUE;
1023 } else {
1024 cstr->prev_pck_encryped = GF_FALSE;
1025 }
1026
1027 //rewrite ISMA header
1028 if (!ctx->bs_w) ctx->bs_w = gf_bs_new(output, isma_hdr_size, GF_BITSTREAM_WRITE);
1029 else gf_bs_reassign_buffer(ctx->bs_w, output, isma_hdr_size);
1030
1031 if (flags & GF_ISOM_ISMA_USE_SEL_ENC) {
1032 gf_bs_write_int(ctx->bs_w, (flags & GF_ISOM_ISMA_IS_ENCRYPTED) ? 1 : 0, 1);
1033 gf_bs_write_int(ctx->bs_w, 0, 7);
1034 }
1035 if (flags & GF_ISOM_ISMA_IS_ENCRYPTED) {
1036 if (cstr->isma_IV_size) gf_bs_write_long_int(ctx->bs_w, (s64) cstr->BSO, 8*cstr->isma_IV_size);
1037 //not yet implemented
1038 // if (cstr->KI_length) gf_bs_write_data(ctx->bs_w, (char*) key_indicator, cstr->KI_length);
1039 }
1040
1041 cstr->BSO += size;
1042
1043 gf_filter_pck_send(dst_pck);
1044 return GF_OK;
1045 }
1046
adobe_process(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,GF_FilterPacket * pck)1047 static GF_Err adobe_process(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_FilterPacket *pck)
1048 {
1049 Bool is_encrypted = GF_TRUE;
1050 GF_FilterPacket *dst_pck;
1051 const u8 *data;
1052 u8 *output;
1053 GF_Err e;
1054 bin128 IV;
1055 u32 size, adobe_hdr_size;
1056 u32 len, padding_bytes;
1057 u8 sap = gf_filter_pck_get_sap(pck);
1058
1059 switch (cstr->tci->sel_enc_type) {
1060 case GF_CRYPT_SELENC_RAP:
1061 if (!sap) is_encrypted = GF_FALSE;
1062 break;
1063 case GF_CRYPT_SELENC_NON_RAP:
1064 if (sap) is_encrypted = GF_FALSE;
1065 break;
1066 default:
1067 break;
1068 }
1069
1070 adobe_hdr_size = 1;
1071 if (is_encrypted) adobe_hdr_size += 16;
1072
1073 data = gf_filter_pck_get_data(pck, &size);
1074 if (!data) {
1075 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMACrypt] No data associated with packet\n" ));
1076 return GF_OK;
1077 }
1078 padding_bytes = 0;
1079 len = size;
1080 if (is_encrypted) {
1081 padding_bytes = 16 - len % 16;
1082 len += padding_bytes;
1083 }
1084 dst_pck = gf_filter_pck_new_alloc(cstr->opid, len + adobe_hdr_size, &output);
1085 memcpy(output+adobe_hdr_size, data, sizeof(char)*size);
1086 gf_filter_pck_merge_properties(pck, dst_pck);
1087
1088
1089 if (is_encrypted) {
1090 if (!cstr->prev_pck_encryped) {
1091 memcpy(IV, cstr->tci->first_IV, sizeof(char)*16);
1092 e = gf_crypt_init(cstr->crypt, cstr->key, IV);
1093 cstr->prev_pck_encryped = GF_TRUE;
1094 } else {
1095 cstr->isma_IV_size = 16;
1096 e = gf_crypt_get_IV(cstr->crypt, IV, &cstr->isma_IV_size);
1097 }
1098
1099 if (e) {
1100 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[ADOBE] Cannot initialize AES-128 CBC (%s)\n", gf_error_to_string(e)) );
1101 gf_filter_pck_discard(dst_pck);
1102 return GF_IO_ERR;
1103 }
1104
1105 memset(output+adobe_hdr_size+size, padding_bytes, sizeof(char)*padding_bytes);
1106
1107 gf_crypt_encrypt(cstr->crypt, output+adobe_hdr_size, len);
1108
1109 /*write encrypted AU header*/
1110 output[0] = 0x10;
1111 memcpy(output+1, (char *) IV, sizeof(char) * 16);
1112 } else {
1113 /*write encrypted AU header*/
1114 output[0] = 0x0;
1115 }
1116
1117 gf_filter_pck_send(dst_pck);
1118 return GF_OK;
1119 }
1120
1121
1122 /*Common Encryption*/
increase_counter(char * x,int x_size)1123 static void increase_counter(char *x, int x_size) {
1124 register int i;
1125
1126 for (i=x_size-1; i>=0; i--) {
1127 register int y=0;
1128 if ((u8) x[i] == 0xFF) {
1129 x[i] = 0;
1130 y = 1;
1131 } else x[i]++;
1132
1133 if (y==0) break;
1134 }
1135
1136 return;
1137 }
1138
cenc_resync_IV(GF_Crypt * mc,char IV[16],u8 IV_size)1139 static void cenc_resync_IV(GF_Crypt *mc, char IV[16], u8 IV_size)
1140 {
1141 char next_IV[17];
1142 u32 size = 17;
1143
1144 gf_crypt_get_IV(mc, (u8 *) next_IV, &size);
1145 /*
1146 NOTE 1: the next_IV returned by get_state has 17 bytes, the first byte being the current counter position in the following 16 bytes.
1147 If this index is 0, this means that we are at the begining of a new block and we can use it as IV for next sample,
1148 otherwise we must discard unsued bytes in the counter (next sample shall begin with counter at 0)
1149 if less than 16 blocks were cyphered, we must force increasing the next IV for next sample, not doing so would produce the same IV for the next bytes cyphered,
1150 which is forbidden by CENC (unique IV per sample). In GPAC, we ALWAYS force counter increase
1151
1152 NOTE 2: in case where IV_size is 8, because the cypher block is treated as 16 bytes while processing,
1153 we need to increment manually the 8-bytes IV (bytes 0 to 7) for the next sample, otherwise we would likely the same IV (eg unless we had cyphered 16 * 2^64 - 1
1154 bytes in the last sample , quite unlikely !)
1155
1156 NOTE 3: Bytes 8 to 15 are set to 0 when forcing a new IV for 8-bytes IVs.
1157
1158 NOTE 4: Since CENC forces declaration of a unique, potentially random, IV per sample, we could increase the IV counter at each sample start
1159 but this is currently not done
1160 */
1161 if (IV_size == 8) {
1162 /*cf note 2*/
1163 increase_counter(&next_IV[1], IV_size);
1164 next_IV[0] = 0;
1165 /*cf note 3*/
1166 memset(&next_IV[9], 0, 8*sizeof(char));
1167 } else if (next_IV[0]) {
1168 /*cf note 1*/
1169 increase_counter(&next_IV[1], IV_size);
1170 next_IV[0] = 0;
1171 }
1172
1173 gf_crypt_set_IV(mc, next_IV, size);
1174
1175 memset(IV, 0, 16*sizeof(char));
1176 memcpy(IV, next_IV+1, 16*sizeof(char));
1177 }
1178
1179 #ifndef GPAC_DISABLE_AV_PARSERS
1180 //parses slice header and returns its size
cenc_get_clear_bytes(GF_CENCStream * cstr,GF_BitStream * plaintext_bs,char * samp_data,u32 nal_size,u32 bytes_in_nalhr)1181 static u32 cenc_get_clear_bytes(GF_CENCStream *cstr, GF_BitStream *plaintext_bs, char *samp_data, u32 nal_size, u32 bytes_in_nalhr)
1182 {
1183 u32 clear_bytes = 0;
1184 if (cstr->slice_header_clear) {
1185 u32 nal_start = (u32) gf_bs_get_position(plaintext_bs);
1186 if (cstr->cenc_codec==CENC_AVC) {
1187 u32 ntype;
1188 gf_media_avc_parse_nalu(plaintext_bs, &cstr->avc);
1189 ntype = cstr->avc.last_nal_type_parsed;
1190 switch (ntype) {
1191 case GF_AVC_NALU_NON_IDR_SLICE:
1192 case GF_AVC_NALU_DP_A_SLICE:
1193 case GF_AVC_NALU_DP_B_SLICE:
1194 case GF_AVC_NALU_DP_C_SLICE:
1195 case GF_AVC_NALU_IDR_SLICE:
1196 case GF_AVC_NALU_SLICE_AUX:
1197 case GF_AVC_NALU_SVC_SLICE:
1198 gf_bs_align(plaintext_bs);
1199 clear_bytes = (u32) gf_bs_get_position(plaintext_bs) - nal_start;
1200 break;
1201 default:
1202 clear_bytes = nal_size;
1203 break;
1204 }
1205 } else {
1206 #if !defined(GPAC_DISABLE_HEVC)
1207 u8 ntype, ntid, nlid;
1208 cstr->hevc.full_slice_header_parse = GF_TRUE;
1209 gf_media_hevc_parse_nalu (samp_data + nal_start, nal_size, &cstr->hevc, &ntype, &ntid, &nlid);
1210 if (ntype<=GF_HEVC_NALU_SLICE_CRA) {
1211 clear_bytes = cstr->hevc.s_info.payload_start_offset;
1212 } else {
1213 clear_bytes = nal_size;
1214 }
1215 #endif
1216 }
1217 gf_bs_seek(plaintext_bs, nal_start);
1218 } else {
1219 clear_bytes = bytes_in_nalhr;
1220 }
1221 gf_bs_enable_emulation_byte_removal(plaintext_bs, GF_FALSE);
1222 return clear_bytes;
1223 }
1224 #endif
1225
cenc_encrypt_packet(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,GF_FilterPacket * pck)1226 static GF_Err cenc_encrypt_packet(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_FilterPacket *pck)
1227 {
1228 GF_BitStream *sai_bs;
1229 u32 prev_entry_bytes_clear=0;
1230 u32 prev_entry_bytes_crypt=0;
1231 u32 pck_size;
1232 GF_FilterPacket *dst_pck;
1233 const u8 *data;
1234 u8 *output;
1235 u32 sai_size = cstr->tci->IV_size;
1236 u32 nb_subsamples=0;
1237
1238 //in cbcs scheme, if Per_Sample_IV_size is not 0 (no constant IV), fetch current IV
1239 if (!cstr->ctr_mode && cstr->tci->IV_size) {
1240 u32 IV_size = 16;
1241 gf_crypt_get_IV(cstr->crypt, cstr->IV, &IV_size);
1242 }
1243
1244
1245 data = gf_filter_pck_get_data(pck, &pck_size);
1246
1247 //CENC can use inplace processing for decryption
1248 dst_pck = gf_filter_pck_new_clone(cstr->opid, pck, &output);
1249 if (!dst_pck) {
1250 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Failed to allocated/clone packet for encrypting payload\n" ) );
1251 gf_filter_pid_drop_packet(cstr->ipid);
1252 return GF_SERVICE_ERROR;
1253 }
1254
1255 gf_filter_pck_merge_properties(pck, dst_pck);
1256 gf_filter_pck_set_crypt_flags(dst_pck, GF_FILTER_PCK_CRYPT);
1257
1258 if (!ctx->bs_r) ctx->bs_r = gf_bs_new(data, pck_size, GF_BITSTREAM_READ);
1259 else gf_bs_reassign_buffer(ctx->bs_r, data, pck_size);
1260
1261 sai_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1262
1263 gf_bs_write_data(sai_bs, cstr->IV, cstr->tci->IV_size);
1264
1265 while (gf_bs_available(ctx->bs_r)) {
1266 GF_Err e=GF_OK;
1267
1268 if (cstr->use_subsamples) {
1269 #ifndef GPAC_DISABLE_AV_PARSERS
1270 ObuType obut;
1271 u32 num_frames_in_superframe = 0, superframe_index_size = 0;
1272 u32 frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME];
1273 struct {
1274 int clear, encrypted;
1275 } ranges[AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS];
1276 u64 obu_size;
1277 u32 hdr_size;
1278 u32 i;
1279 #else
1280 struct {
1281 int clear, encrypted;
1282 } ranges[1];
1283 #endif
1284 u64 pos;
1285 u32 clear_bytes_at_end = 0;
1286 u32 clear_bytes = 0;
1287 u32 nb_ranges = 1;
1288 u32 range_idx = 0;
1289 u32 nalu_size = 0;
1290
1291 #ifndef GPAC_DISABLE_AV_PARSERS
1292 switch (cstr->cenc_codec) {
1293 case CENC_AVC:
1294 case CENC_HEVC:
1295 nalu_size = gf_bs_read_int(ctx->bs_r, 8*cstr->nalu_size_length);
1296 if (nalu_size == 0) {
1297 continue;
1298 }
1299 clear_bytes = cenc_get_clear_bytes(cstr, ctx->bs_r, (char *) data, nalu_size, cstr->bytes_in_nal_hdr);
1300 break;
1301
1302 case CENC_AV1:
1303 pos = gf_bs_get_position(ctx->bs_r);
1304 e = gf_media_aom_av1_parse_obu(ctx->bs_r, &obut, &obu_size, &hdr_size, &cstr->av1);
1305 if (e) {
1306 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Failed to parse OBU\n" ));
1307 return e;
1308 }
1309 gf_bs_seek(ctx->bs_r, pos);
1310
1311 nalu_size = (u32)obu_size;
1312 switch (obut) {
1313 //we only encrypt frame and tile group
1314 case OBU_FRAME:
1315 case OBU_TILE_GROUP:
1316 if (!cstr->av1.frame_state.nb_tiles_in_obu) {
1317 clear_bytes = (u32) obu_size;
1318 } else {
1319 nb_ranges = cstr->av1.frame_state.nb_tiles_in_obu;
1320
1321 ranges[0].clear = cstr->av1.frame_state.tiles[0].obu_start_offset;
1322 ranges[0].encrypted = cstr->av1.frame_state.tiles[0].size;
1323 for (i = 1; i < nb_ranges; ++i) {
1324 ranges[i].clear = cstr->av1.frame_state.tiles[i].obu_start_offset - (cstr->av1.frame_state.tiles[i - 1].obu_start_offset + cstr->av1.frame_state.tiles[i - 1].size);
1325 ranges[i].encrypted = cstr->av1.frame_state.tiles[i].size;
1326 }
1327 clear_bytes = ranges[0].clear;
1328 nalu_size = clear_bytes + ranges[0].encrypted;
1329
1330 /* A subsample SHALL be created for each tile even if less than 16 bytes
1331 see https://github.com/AOMediaCodec/av1-isobmff/pull/116#discussion_r340176740
1332
1333 If previous range had encrypted bytes, create a new one, otherwise merge in prev
1334 */
1335 if (prev_entry_bytes_crypt) {
1336 if (!nb_subsamples) gf_bs_write_u16(sai_bs, 0);
1337 nb_subsamples++;
1338 gf_bs_write_u16(sai_bs, prev_entry_bytes_clear);
1339 gf_bs_write_u32(sai_bs, prev_entry_bytes_crypt);
1340 sai_size+=6;
1341
1342 prev_entry_bytes_crypt = 0;
1343 prev_entry_bytes_clear = 0;
1344 }
1345 }
1346 break;
1347 default:
1348 clear_bytes = (u32) obu_size;
1349 break;
1350 }
1351 break;
1352 case CENC_VPX:
1353 if (cstr->tci->block_align != 2) {
1354 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[CENC] VP9 mandates that blockAlign=\"always\". Forcing value.\n"));
1355 cstr->tci->block_align = 2;
1356 }
1357
1358 pos = gf_bs_get_position(ctx->bs_r);
1359 e = gf_media_vp9_parse_superframe(ctx->bs_r, pck_size, &num_frames_in_superframe, frame_sizes, &superframe_index_size);
1360 if (e || !num_frames_in_superframe) return e;
1361 gf_bs_seek(ctx->bs_r, pos);
1362
1363 nb_ranges = num_frames_in_superframe;
1364
1365 for (i = 0; i < num_frames_in_superframe; ++i) {
1366 Bool key_frame;
1367 u32 width = 0, height = 0, renderWidth = 0, renderHeight = 0;
1368 GF_VPConfig *vp9_cfg = gf_odf_vp_cfg_new();
1369 u64 pos2 = gf_bs_get_position(ctx->bs_r);
1370 e = gf_media_vp9_parse_sample(ctx->bs_r, vp9_cfg, &key_frame, &width, &height, &renderWidth, &renderHeight);
1371 gf_odf_vp_cfg_del(vp9_cfg);
1372 if (e) {
1373 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[CENC] Error parsing VP9 frame at DTS "LLU"\n", gf_filter_pck_get_dts(pck) ));
1374 return e;
1375 }
1376
1377 ranges[i].clear = (int)(gf_bs_get_position(ctx->bs_r) - pos2);
1378 ranges[i].encrypted = frame_sizes[i] - ranges[i].clear;
1379
1380 gf_bs_seek(ctx->bs_r, pos2 + frame_sizes[i]);
1381 }
1382 if (gf_bs_get_position(ctx->bs_r) + superframe_index_size != pos + pck_size) {
1383 GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[CENC] Inconsistent VP9 size %u (parsed "LLU") at DTS "LLU". Re-import raw VP9/IVF for more details.\n",
1384 pck_size, gf_bs_get_position(ctx->bs_r) + superframe_index_size - pos, gf_filter_pck_get_dts(pck)));
1385 }
1386 gf_bs_seek(ctx->bs_r, pos);
1387
1388 clear_bytes = ranges[0].clear;
1389 assert(frame_sizes[0] == ranges[0].clear + ranges[0].encrypted);
1390 nalu_size = frame_sizes[0];
1391
1392 //final superframe index must be in clear
1393 if (superframe_index_size > 0) {
1394 ranges[nb_ranges].clear = superframe_index_size;
1395 ranges[nb_ranges].encrypted = 0;
1396 nb_ranges++;
1397 }
1398
1399 //not clearly defined in the spec (so we do the same as in AV1 which is more clearly defined):
1400 if (frame_sizes[0] - clear_bytes >= 16) {
1401 //A subsample SHALL be created for each tile >= 16 bytes. If previous range had encrypted bytes, create a new one, otherwise merge in prev
1402 if (prev_entry_bytes_crypt) {
1403 if (!nb_subsamples) gf_bs_write_u16(sai_bs, 0);
1404 nb_subsamples++;
1405 gf_bs_write_u16(sai_bs, prev_entry_bytes_clear);
1406 gf_bs_write_u32(sai_bs, prev_entry_bytes_crypt);
1407 sai_size+=6;
1408
1409 prev_entry_bytes_crypt = 0;
1410 prev_entry_bytes_clear = 0;
1411 }
1412 } else {
1413 clear_bytes = nalu_size;
1414 }
1415 break;
1416 default:
1417 assert(0);
1418 }
1419 #else
1420 clear_bytes = nalu_size;
1421 #endif
1422
1423 while (nb_ranges) {
1424 if (cstr->ctr_mode) {
1425
1426 // adjust so that encrypted bytes are a multiple of 16 bytes: cenc SHOULD, cens SHALL, we always do it
1427 if (nalu_size > clear_bytes) {
1428 u32 ret = (nalu_size - clear_bytes) % 16;
1429 //in AV1 always enforced
1430 if (cstr->cenc_codec==CENC_AV1) {
1431 clear_bytes += ret;
1432 }
1433 //for CENC (should),
1434 else if ((cstr->tci->scheme_type == GF_CRYPT_TYPE_CENC) || (cstr->tci->scheme_type == GF_CRYPT_TYPE_PIFF)) {
1435 //do it if not disabled by user
1436 if (cstr->tci->block_align != 1) {
1437 //always align even if sample is not encrypted in the end
1438 if (cstr->tci->block_align==2) {
1439 clear_bytes += ret;
1440 }
1441 //or if we don't end up with sample in the clear
1442 else if (nalu_size > clear_bytes + ret) {
1443 clear_bytes += ret;
1444 }
1445 }
1446 } else {
1447 clear_bytes += ret;
1448 }
1449 }
1450 } else {
1451 //in cbcs, we don't adjust bytes_encrypted_data to be a multiple of 16 bytes and leave the last block unencrypted
1452 //except in VPX, where BytesOfProtectedData SHALL end on the last byte of the decode_tile structure
1453 if ((cstr->cenc_codec != CENC_VPX) && (cstr->tci->scheme_type == GF_CRYPT_TYPE_CBCS)) {
1454 u32 ret = (nalu_size - clear_bytes) % 16;
1455 clear_bytes_at_end = ret;
1456 }
1457 //in cbc1 or cbcs+VPX, we adjust bytes_encrypted_data to be a multiple of 16 bytes
1458 else {
1459 u32 ret = (nalu_size - clear_bytes) % 16;
1460 clear_bytes += ret;
1461 clear_bytes_at_end = 0;
1462 }
1463
1464 }
1465
1466 /*skip bytes of clear data*/
1467 gf_bs_skip_bytes(ctx->bs_r, clear_bytes);
1468
1469 //read data to encrypt
1470 if (nalu_size > clear_bytes) {
1471 /*get encrypted data start*/
1472 u32 cur_pos = (u32) gf_bs_get_position(ctx->bs_r);
1473
1474 /*skip bytes of encrypted data*/
1475 gf_bs_skip_bytes(ctx->bs_r, nalu_size - clear_bytes);
1476
1477 //cbcs scheme with constant IV, reinit at each sub sample,
1478 if (!cstr->ctr_mode && !cstr->tci->IV_size)
1479 gf_crypt_set_IV(cstr->crypt, cstr->IV, 16);
1480
1481 //pattern encryption
1482 if (cstr->tci->crypt_byte_block && cstr->tci->skip_byte_block) {
1483 u32 res = nalu_size - clear_bytes - clear_bytes_at_end;
1484 pos = cur_pos;
1485 assert((res % 16) == 0);
1486
1487 while (res) {
1488 e = gf_crypt_encrypt(cstr->crypt, output+pos, res >= (u32) (16*cstr->tci->crypt_byte_block) ? 16*cstr->tci->crypt_byte_block : res);
1489 if (res >= (u32) (16 * (cstr->tci->crypt_byte_block + cstr->tci->skip_byte_block))) {
1490 pos += 16 * (cstr->tci->crypt_byte_block + cstr->tci->skip_byte_block);
1491 res -= 16 * (cstr->tci->crypt_byte_block + cstr->tci->skip_byte_block);
1492 } else {
1493 res = 0;
1494 }
1495 }
1496 }
1497 //full subsample encryption
1498 else {
1499 e = gf_crypt_encrypt(cstr->crypt, output+cur_pos, nalu_size - clear_bytes);
1500 }
1501 }
1502
1503
1504 //prev entry is not a VCL, append this NAL
1505 if (!prev_entry_bytes_crypt) {
1506 prev_entry_bytes_clear += cstr->nalu_size_length + clear_bytes;
1507 prev_entry_bytes_crypt += nalu_size - clear_bytes;
1508 } else {
1509 //store current
1510 if (!nb_subsamples) gf_bs_write_u16(sai_bs, 0);
1511 nb_subsamples++;
1512 gf_bs_write_u16(sai_bs, prev_entry_bytes_clear);
1513 gf_bs_write_u32(sai_bs, prev_entry_bytes_crypt);
1514 sai_size+=6;
1515
1516 prev_entry_bytes_clear = cstr->nalu_size_length + clear_bytes;
1517 prev_entry_bytes_crypt = nalu_size - clear_bytes;
1518 }
1519
1520 //check bytes of clear is not larger than 16bits
1521 while (prev_entry_bytes_clear > 0xFFFF) {
1522 //store current
1523 if (!nb_subsamples) gf_bs_write_u16(sai_bs, 0);
1524 nb_subsamples++;
1525 gf_bs_write_u16(sai_bs, 0xFFFF);
1526 gf_bs_write_u32(sai_bs, 0);
1527 sai_size+=6;
1528
1529 prev_entry_bytes_clear -= 0xFFFF;
1530 }
1531
1532
1533 nb_ranges--;
1534 if (!nb_ranges) break;
1535
1536 range_idx++;
1537 if (range_idx >= AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS) {
1538 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] More ranges than tiles allowed spec, bitstream error ?\n"));
1539 return GF_BAD_PARAM;
1540 }
1541 switch (cstr->cenc_codec) {
1542 case CENC_AV1:
1543 clear_bytes = ranges[range_idx].clear;
1544 nalu_size = clear_bytes + ranges[range_idx].encrypted;
1545 break;
1546 case CENC_VPX:
1547 if (nb_ranges > 1) {
1548 clear_bytes = ranges[range_idx].clear;
1549 nalu_size = clear_bytes + ranges[range_idx].encrypted;
1550 } else { /*last*/
1551 nalu_size = clear_bytes = ranges[range_idx].clear;
1552 assert(ranges[range_idx].encrypted == 0);
1553 }
1554 break;
1555 default:
1556 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Unexpected subrange for sample format, only allowed for VPX and AV1\n"));
1557 return GF_BAD_PARAM;
1558 }
1559 }
1560 } else if (cstr->ctr_mode) {
1561 gf_bs_skip_bytes(ctx->bs_r, pck_size);
1562 e = gf_crypt_encrypt(cstr->crypt, output, pck_size);
1563 } else {
1564 u32 clear_trailing;
1565
1566 clear_trailing = pck_size % 16;
1567
1568 //cbcs scheme with constant IV, reinit at each sample,
1569 if (!cstr->tci->IV_size)
1570 gf_crypt_set_IV(cstr->crypt, cstr->IV, 16);
1571
1572 if (pck_size >= 16) {
1573 gf_crypt_encrypt(cstr->crypt, output, pck_size - clear_trailing);
1574 }
1575 gf_bs_skip_bytes(ctx->bs_r, pck_size);
1576 }
1577
1578 if (e) {
1579 gf_filter_pck_discard(dst_pck);
1580 return e;
1581 }
1582 }
1583
1584 if (prev_entry_bytes_clear || prev_entry_bytes_crypt) {
1585 if (!nb_subsamples) gf_bs_write_u16(sai_bs, 0);
1586 nb_subsamples++;
1587 gf_bs_write_u16(sai_bs, prev_entry_bytes_clear);
1588 gf_bs_write_u32(sai_bs, prev_entry_bytes_crypt);
1589 sai_size+=6;
1590 }
1591 if (cstr->ctr_mode)
1592 cenc_resync_IV(cstr->crypt, cstr->IV, cstr->tci->IV_size);
1593
1594 if (sai_size) {
1595 u8 *sai=NULL;
1596 sai_size = (u32) gf_bs_get_position(sai_bs);
1597 gf_bs_seek(sai_bs, cstr->tci->IV_size);
1598 gf_bs_write_u16(sai_bs, nb_subsamples);
1599 gf_bs_seek(sai_bs, sai_size);
1600 sai_size = 0;
1601 gf_bs_get_content(sai_bs, &sai, &sai_size);
1602
1603 gf_filter_pck_set_property(dst_pck, GF_PROP_PCK_CENC_SAI, &PROP_DATA_NO_COPY(sai, sai_size) );
1604 }
1605 gf_bs_del(sai_bs);
1606
1607 gf_filter_pck_send(dst_pck);
1608 return GF_OK;
1609 }
1610
cenc_process(GF_CENCEncCtx * ctx,GF_CENCStream * cstr,GF_FilterPacket * pck)1611 static GF_Err cenc_process(GF_CENCEncCtx *ctx, GF_CENCStream *cstr, GF_FilterPacket *pck)
1612 {
1613 Bool is_encrypted = GF_TRUE;
1614 const u8 *data;
1615 GF_Err e;
1616 Bool all_rap=GF_FALSE;
1617 u32 pck_size;
1618 Bool key_changed = GF_FALSE;
1619 Bool force_clear = GF_FALSE;
1620 u8 sap = gf_filter_pck_get_sap(pck);
1621
1622 data = gf_filter_pck_get_data(pck, &pck_size);
1623 if (!data) {
1624 GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMACrypt] No data associated with packet\n" ));
1625 return GF_OK;
1626 }
1627
1628 if (!ctx->bs_w) ctx->bs_w = gf_bs_new((char *) &sap, 1, GF_BITSTREAM_WRITE);
1629
1630 switch (cstr->tci->sel_enc_type) {
1631 case GF_CRYPT_SELENC_RAP:
1632 if (!sap && !all_rap) {
1633 is_encrypted = GF_FALSE;
1634 }
1635 break;
1636 case GF_CRYPT_SELENC_NON_RAP:
1637 if (sap || all_rap) {
1638 is_encrypted = GF_FALSE;
1639 }
1640 break;
1641 case GF_CRYPT_SELENC_CLEAR:
1642 is_encrypted = GF_FALSE;
1643 break;
1644 case GF_CRYPT_SELENC_CLEAR_FORCED:
1645 is_encrypted = GF_FALSE;
1646 force_clear = GF_TRUE;
1647 if (cstr->tci->sel_enc_range && (cstr->nb_pck+1 >= cstr->tci->sel_enc_range)) {
1648 cstr->tci->sel_enc_type = GF_CRYPT_SELENC_NONE;
1649 }
1650 break;
1651 default:
1652 break;
1653 }
1654
1655 if (!is_encrypted) {
1656 u8 *sai=NULL;
1657 u32 i, sai_size = 0;
1658 Bool signal_sai = GF_FALSE;
1659 GF_FilterPacket *dst_pck;
1660 dst_pck = gf_filter_pck_new_ref(cstr->opid, NULL, 0, pck);
1661 gf_filter_pck_merge_properties(pck, dst_pck);
1662
1663 if (force_clear && !cstr->tci->force_clear_stsd_idx)
1664 signal_sai = GF_TRUE;
1665 //format NULL bitstream only for forced clear mode
1666 if (cstr->use_subsamples && signal_sai) {
1667 GF_BitStream *bs;
1668 u32 subsample_count = 1;
1669 u32 olen = pck_size;
1670 while (olen>0xFFFF) {
1671 olen -= 0xFFFF;
1672 subsample_count ++;
1673 }
1674 bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
1675 if (force_clear) {
1676 bin128 NULL_IV;
1677 memset(NULL_IV, 0, 16);
1678 memcpy(NULL_IV, (char *) &cstr->nb_pck, 4);
1679 gf_bs_write_data(bs, NULL_IV, cstr->tci->IV_size);
1680 }
1681 gf_bs_write_u16(bs, subsample_count);
1682 olen = pck_size;
1683 for (i = 0; i < subsample_count; i++) {
1684 if (olen<0xFFFF) {
1685 gf_bs_write_u16(bs, olen);
1686 } else {
1687 gf_bs_write_u16(bs, 0xFFFF);
1688 olen -= 0xFFFF;
1689 }
1690 gf_bs_write_u32(bs, 0);
1691 }
1692 gf_bs_get_content(bs, &sai, &sai_size);
1693 gf_bs_del(bs);
1694 }
1695 if (sai)
1696 gf_filter_pck_set_property(dst_pck, GF_PROP_PCK_CENC_SAI, &PROP_DATA_NO_COPY(sai, sai_size) );
1697
1698 gf_filter_pck_set_crypt_flags(dst_pck, signal_sai ? GF_FILTER_PCK_CRYPT : 0);
1699 gf_filter_pck_send(dst_pck);
1700 return GF_OK;
1701 }
1702
1703 /*generate initialization vector for the first sample in track ... */
1704 if (!cstr->cenc_init) {
1705 memset(cstr->IV, 0, sizeof(char)*16);
1706 if (cstr->tci->IV_size == 8) {
1707 memcpy(cstr->IV, cstr->tci->first_IV, sizeof(char)*8);
1708 memset(cstr->IV+8, 0, sizeof(char)*8);
1709 }
1710 else if (cstr->tci->IV_size == 16) {
1711 memcpy(cstr->IV, cstr->tci->first_IV, sizeof(char)*16);
1712 }
1713 else if (!cstr->tci->IV_size) {
1714 if (cstr->tci->constant_IV_size == 8) {
1715 memcpy(cstr->IV, cstr->tci->constant_IV, sizeof(char)*8);
1716 memset(cstr->IV+8, 0, sizeof(char)*8);
1717 }
1718 else if (cstr->tci->constant_IV_size == 16) {
1719 memcpy(cstr->IV, cstr->tci->constant_IV, sizeof(char)*16);
1720 } else {
1721 return GF_NOT_SUPPORTED;
1722 }
1723 } else {
1724 return GF_NOT_SUPPORTED;
1725 }
1726
1727 e = gf_crypt_init(cstr->crypt, cstr->key, cstr->IV);
1728 if (e) {
1729 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot initialize AES-128 %s (%s)\n", cstr->ctr_mode ? "CTR" : "CBC", gf_error_to_string(e)) );
1730 return GF_IO_ERR;
1731 }
1732 cstr->cenc_init = GF_TRUE;
1733 } else {
1734 if (cstr->tci->keyRoll) {
1735 u32 new_idx = (cstr->nb_pck_encrypted / cstr->tci->keyRoll) % cstr->tci->KID_count;
1736 if (cstr->kidx != new_idx) {
1737 cstr->kidx = new_idx;
1738 memcpy(cstr->key, cstr->tci->keys[cstr->kidx], 16);
1739 key_changed = GF_TRUE;
1740 e = gf_crypt_set_key(cstr->crypt, cstr->key);
1741 if (e) {
1742 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot set key AES-128 %s (%s)\n", cstr->ctr_mode ? "CTR" : "CBC", gf_error_to_string(e)) );
1743 return e;
1744 }
1745 }
1746 }
1747 }
1748
1749 if (key_changed) {
1750 gf_filter_pid_set_property(cstr->opid, GF_PROP_PID_KID, &PROP_DATA( cstr->tci->KIDs[cstr->kidx], sizeof(bin128) ) );
1751 //TODO add support for multiple patterns and keys ?
1752 //TODO add support for multiple IV size in key roll ?
1753 }
1754
1755 e = cenc_encrypt_packet(ctx, cstr, pck);
1756 if (e) {
1757 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Error encrypting packet %d in PID %s: %s\n", cstr->nb_pck, gf_filter_pid_get_name(cstr->ipid), gf_error_to_string(e)) );
1758 return e;
1759 }
1760
1761 cstr->nb_pck_encrypted++;
1762 return GF_OK;
1763 }
1764
cenc_enc_process(GF_Filter * filter)1765 static GF_Err cenc_enc_process(GF_Filter *filter)
1766 {
1767 GF_CENCEncCtx *ctx = (GF_CENCEncCtx *)gf_filter_get_udta(filter);
1768 u32 i, nb_eos, count = gf_list_count(ctx->streams);
1769
1770 nb_eos = 0;
1771 for (i=0; i<count; i++) {
1772 GF_Err e = GF_OK;;
1773 GF_CENCStream *cstr = gf_list_get(ctx->streams, i);
1774 GF_FilterPacket *pck = gf_filter_pid_get_packet(cstr->ipid);
1775 if (!pck) {
1776 if (gf_filter_pid_is_eos(cstr->ipid)) {
1777 gf_filter_pid_set_eos(cstr->opid);
1778 nb_eos++;
1779 }
1780 continue;
1781 }
1782
1783 if (cstr->passthrough) {
1784 gf_filter_pck_forward(pck, cstr->opid);
1785 }
1786 else if (cstr->isma_oma) {
1787 e = isma_process(ctx, cstr, pck);
1788 } else if (cstr->is_adobe) {
1789 e = adobe_process(ctx, cstr, pck);
1790 } else {
1791 e = cenc_process(ctx, cstr, pck);
1792 }
1793 gf_filter_pid_drop_packet(cstr->ipid);
1794 cstr->nb_pck++;
1795
1796 if (e) return e;
1797 }
1798 if (nb_eos==count) return GF_EOS;
1799
1800 return GF_OK;
1801 }
1802
cenc_enc_initialize(GF_Filter * filter)1803 static GF_Err cenc_enc_initialize(GF_Filter *filter)
1804 {
1805 GF_CENCEncCtx *ctx = (GF_CENCEncCtx *)gf_filter_get_udta(filter);
1806
1807 if (ctx->cfile) {
1808 GF_Err e;
1809 ctx->cinfo = gf_crypt_info_load(ctx->cfile, &e);
1810 if (!ctx->cinfo) {
1811 GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENCCrypt] Cannot load config file %s\n", ctx->cfile ));
1812 return GF_BAD_PARAM;
1813 }
1814 }
1815
1816 ctx->streams = gf_list_new();
1817 return GF_OK;
1818 }
1819
cenc_enc_finalize(GF_Filter * filter)1820 static void cenc_enc_finalize(GF_Filter *filter)
1821 {
1822 GF_CENCEncCtx *ctx = (GF_CENCEncCtx *)gf_filter_get_udta(filter);
1823 if (ctx->cinfo) gf_crypt_info_del(ctx->cinfo);
1824 while (gf_list_count(ctx->streams)) {
1825 GF_CENCStream *s = gf_list_pop_back(ctx->streams);
1826 if (s->crypt) gf_crypt_close(s->crypt);
1827 if (s->cinfo) gf_crypt_info_del(s->cinfo);
1828 #ifndef GPAC_DISABLE_AV_PARSERS
1829 if (s->av1.config) gf_odf_av1_cfg_del(s->av1.config);
1830 #endif
1831 gf_free(s);
1832 }
1833 gf_list_del(ctx->streams);
1834 if (ctx->bs_w) gf_bs_del(ctx->bs_w);
1835 if (ctx->bs_r) gf_bs_del(ctx->bs_r);
1836 }
1837
1838
1839 static const GF_FilterCapability CENCEncCaps[] =
1840 {
1841 CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_ENCRYPTED),
1842 CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_STREAM_TYPE, GF_STREAM_FILE),
1843 CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1844 CAP_UINT(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
1845
1846 CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_ENCRYPTED),
1847 CAP_UINT(GF_CAPS_OUTPUT_EXCLUDED, GF_PROP_PID_CODECID, GF_CODECID_RAW),
1848 // CAP_UINT(GF_CAPS_OUTPUT_STATIC_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
1849 };
1850
1851 #define OFFS(_n) #_n, offsetof(GF_CENCEncCtx, _n)
1852 static const GF_FilterArgs GF_CENCEncArgs[] =
1853 {
1854 { OFFS(cfile), "crypt file location - see filter help", GF_PROP_STRING, NULL, NULL, 0},
1855 { OFFS(allc), "throw error if no DRM config file is found for a PID - see filter help", GF_PROP_STRING, NULL, NULL, 0},
1856 {0}
1857 };
1858
1859 GF_FilterRegister CENCEncRegister = {
1860 .name = "cecrypt",
1861 GF_FS_SET_DESCRIPTION("CENC encryptor")
1862 GF_FS_SET_HELP("The CENC encryptor supports CENC, ISMA and Adobe encryption. It uses a DRM config file for declaring keys.\n"
1863 "The syntax is available at https://wiki.gpac.io/Common-Encryption\n"
1864 "The DRM config file can be set per PID using the property `CryptInfo`, or set at the filter level using [-cfile]().\n"
1865 "When the DRM config file is set per PID, the first `CrypTrack` in the DRM config file with the same ID is used, otherwise the first `CrypTrack` is used.\n"
1866 "If no DRM config file is defined for a given PID, this PID will not be encrypted, or an error will be thrown if [-allc]() is specified.\n"
1867 )
1868 .private_size = sizeof(GF_CENCEncCtx),
1869 .max_extra_pids=-1,
1870 //encryptor shall be explicitly loaded
1871 .flags = GF_FS_REG_EXPLICIT_ONLY,
1872 .args = GF_CENCEncArgs,
1873 SETCAPS(CENCEncCaps),
1874 .configure_pid = cenc_enc_configure_pid,
1875 .initialize = cenc_enc_initialize,
1876 .finalize = cenc_enc_finalize,
1877 .process = cenc_enc_process
1878
1879 };
1880
1881 #endif /*GPAC_DISABLE_CRYPTO*/
1882
cenc_encrypt_register(GF_FilterSession * session)1883 const GF_FilterRegister *cenc_encrypt_register(GF_FilterSession *session)
1884 {
1885 #ifndef GPAC_DISABLE_CRYPTO
1886 return &CENCEncRegister;
1887 #else
1888 return NULL;
1889 #endif
1890 }
1891