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