コード例 #1
0
ファイル: g_crypt.c プロジェクト: noelove/GPAC-old
GF_EXPORT
GF_Err gf_crypt_init(GF_Crypt *td, void *key, u32 lenofkey, const void *IV)
{
	GF_Err e;
	u32 sizes[MAX_KEY_SIZES];
	u32 i, num_of_sizes, ok = 0;
	u32 key_size = gf_crypt_get_key_size(td);

	if ((lenofkey > key_size) || (lenofkey==0)) return GF_BAD_PARAM;
	num_of_sizes = gf_crypt_get_supported_key_sizes(td, sizes);
	if (num_of_sizes) {
		for (i=0; i < num_of_sizes; i++) {
			if (lenofkey == sizes[i]) {
				ok = 1;
				break;
			}
		}
	} else if (lenofkey <= gf_crypt_get_key_size(td)) {
		ok = 1;
	}

	if (ok == 0) { /* not supported key size */
		key_size = gf_crypt_get_key_size(td);
		if (sizes != NULL) {
			for (i = 0; i < num_of_sizes; i++) {
				if (lenofkey <= sizes[i]) {
					key_size = sizes[i];
					break;
				}
			}
		} else { /* well every key size is supported! */
			key_size = lenofkey;
		}
	} else {
		key_size = lenofkey;
	}

	td->keyword_given = (char*)gf_malloc(sizeof(char)*gf_crypt_get_key_size(td));
	if (td->keyword_given==NULL) return GF_OUT_OF_MEM; 
	
	memmove(td->keyword_given, key, lenofkey);

	td->akey = (char*)gf_malloc(sizeof(char)*td->algo_size);
	if (td->akey==NULL) {
		gf_free(td->keyword_given);
		return GF_OUT_OF_MEM;
	}
	if (td->mode_size > 0) {
		td->abuf = (char*)gf_malloc(sizeof(char)*td->mode_size);
		if (td->abuf==NULL) {
			gf_free(td->keyword_given);
			gf_free(td->akey);
			return GF_OUT_OF_MEM;
		}
	}
	e = td->_init_mcrypt(td->abuf, (void *) key, key_size, (void *) IV, gf_crypt_get_block_size(td));
	if (e!=GF_OK) {
		gf_free(td->keyword_given);
		gf_free(td->akey);
		gf_free(td->abuf);
		return e;
	}

	e = gf_crypt_set_key(td, (void *) td->keyword_given, key_size, IV);

	if (e!=GF_OK) internal_end_mcrypt(td);
	return e;
}
コード例 #2
0
ファイル: isma_ea.c プロジェクト: DmitrySigaev/gpac_hbbtv
static GF_Err CENC_ProcessData(ISMAEAPriv *priv, GF_IPMPEvent *evt)
{
	GF_Err e;
	GF_BitStream *pleintext_bs, *cyphertext_bs, *sai_bs;
	char IV[17];
	bin128 KID;
	char *buffer;
	u32 max_size, i, subsample_count;
	u64 BSO;
	GF_CENCSampleAuxInfo *sai;

	e = GF_OK;
	pleintext_bs = cyphertext_bs = sai_bs = NULL;
	buffer = NULL;
	max_size = 4096;

	if (!priv->crypt) return GF_SERVICE_ERROR;
	
	if (!evt->is_encrypted || !evt->IV_size) return GF_OK;

	cyphertext_bs = gf_bs_new(evt->data, evt->data_size, GF_BITSTREAM_READ);
	sai_bs = gf_bs_new(evt->sai, evt->saiz, GF_BITSTREAM_READ);
	pleintext_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	buffer = (char*)gf_malloc(sizeof(char) * max_size);

	sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
	if (!sai) {
		e = GF_IO_ERR;
		goto exit;
	}
	memset(sai, 0, sizeof(GF_CENCSampleAuxInfo));
	sai->IV_size = evt->IV_size;
	/*read sample auxiliary information from bitstream*/
	gf_bs_read_data(sai_bs,  (char *)KID, 16);
	gf_bs_read_data(sai_bs, (char *)sai->IV, sai->IV_size);
	sai->subsample_count = gf_bs_read_u16(sai_bs);
	if (sai->subsample_count) {
		sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry));
		for (i = 0; i < sai->subsample_count; i++) {
			sai->subsamples[i].bytes_clear_data = gf_bs_read_u16(sai_bs);
			sai->subsamples[i].bytes_encrypted_data = gf_bs_read_u32(sai_bs);
		}
	}


	for (i = 0; i < priv->KID_count; i++) {
		if (!strncmp((const char *)KID, (const char *)priv->KIDs[i], 16)) {
			memmove(priv->key, priv->keys[i], 16);
			break;
		}
	}

	if (priv->first_crypted_samp) {
		memmove(IV, sai->IV, sai->IV_size);
		if (sai->IV_size == 8)
			memset(IV+8, 0, sizeof(char)*8);
		e = gf_crypt_init(priv->crypt, priv->key, 16, IV);
		if (e) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot initialize AES-128 AES-128 %s (%s)\n", priv->is_cenc ? "CTR" : "CBC", gf_error_to_string(e)) );
			e = GF_IO_ERR;
			goto exit;
		}
		priv->first_crypted_samp = GF_FALSE;
	} else {
		if (priv->is_cenc) {
			GF_BitStream *bs;
			bs = gf_bs_new(IV, 17, GF_BITSTREAM_WRITE);
			gf_bs_write_u8(bs, 0);	/*begin of counter*/
			gf_bs_write_data(bs,(char *)sai->IV, sai->IV_size);
			if (sai->IV_size == 8)
				gf_bs_write_u64(bs, 0); /*0-padded if IV_size == 8*/
			gf_bs_del(bs);
			gf_crypt_set_state(priv->crypt, IV, 17);
		}
		e = gf_crypt_set_key(priv->crypt, priv->key, 16, IV);
		if (e) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot set key AES-128 %s (%s)\n", priv->is_cenc ? "CTR" : "CBC", gf_error_to_string(e)) );
			e = GF_IO_ERR;
			goto exit;
		}
	}

	subsample_count = 0;
	BSO = 0;
	while (gf_bs_available(cyphertext_bs)) {
		assert(subsample_count < sai->subsample_count);

		/*read clear data and write it to pleintext bitstream*/
		if (max_size < sai->subsamples[subsample_count].bytes_clear_data) {
			buffer = (char*)gf_realloc(buffer, sizeof(char)*sai->subsamples[subsample_count].bytes_clear_data);
			max_size = sai->subsamples[subsample_count].bytes_clear_data;
		}
		gf_bs_read_data(cyphertext_bs, buffer, sai->subsamples[subsample_count].bytes_clear_data);
		gf_bs_write_data(pleintext_bs, buffer, sai->subsamples[subsample_count].bytes_clear_data);

		/*now read encrypted data, decrypted it and write to pleintext bitstream*/
		if (max_size < sai->subsamples[subsample_count].bytes_encrypted_data) {
			buffer = (char*)gf_realloc(buffer, sizeof(char)*sai->subsamples[subsample_count].bytes_encrypted_data);
			max_size = sai->subsamples[subsample_count].bytes_encrypted_data;
		}
		gf_bs_read_data(cyphertext_bs, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);
		gf_crypt_decrypt(priv->crypt, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);
		gf_bs_write_data(pleintext_bs, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);

		/*update IV for next subsample*/
		if (priv->is_cenc) {
			BSO += sai->subsamples[subsample_count].bytes_encrypted_data;
			if (gf_bs_available(cyphertext_bs)) {
				char next_IV[17];
				u64 prev_block_count, salt_portion, block_count_portion;
				u32 remain;
				GF_BitStream *bs, *tmp;

				prev_block_count = BSO / 16;
				remain = BSO % 16;
				tmp = gf_bs_new((const char *)sai->IV, 16, GF_BITSTREAM_READ);
				bs = gf_bs_new(next_IV, 17, GF_BITSTREAM_WRITE);
				gf_bs_write_u8(bs, 0);	/*begin of counter*/

				salt_portion = gf_bs_read_u64(tmp);
				block_count_portion = gf_bs_read_u64(tmp);
				/*reset the block counter to zero without affecting the other 64 bits of the IV*/
				if (prev_block_count > 0xFFFFFFFFFFFFFFFFULL - block_count_portion)
					block_count_portion = prev_block_count - (0xFFFFFFFFFFFFFFFFULL - block_count_portion) - 1;
				else
					block_count_portion +=  prev_block_count;
				gf_bs_write_u64(bs, salt_portion);
				gf_bs_write_u64(bs, block_count_portion);

				gf_crypt_set_state(priv->crypt, next_IV, 17);
				/*decrypt remain bytes*/
				if (remain) {
					char dummy[20];
					gf_crypt_decrypt(priv->crypt, dummy, remain);
				}

				gf_bs_del(bs);
				gf_bs_del(tmp);
			}
		}

		subsample_count++;
	}

	if (buffer) gf_free(buffer);
	gf_bs_get_content(pleintext_bs, &buffer, &evt->data_size);
	memmove(evt->data, buffer, evt->data_size);

exit:
	if (pleintext_bs) gf_bs_del(pleintext_bs);
	if (sai_bs) gf_bs_del(sai_bs);
	if (cyphertext_bs) gf_bs_del(cyphertext_bs);
	if (buffer) gf_free(buffer);
	if (sai && sai->subsamples) gf_free(sai->subsamples);
	if (sai) gf_free(sai);
	return e;
}
コード例 #3
0
ファイル: isma_ea.c プロジェクト: TotoLulu94/gpac
static GF_Err CENC_ProcessData(ISMAEAPriv *priv, GF_IPMPEvent *evt)
{
	GF_Err e;
	GF_BitStream *pleintext_bs, *cyphertext_bs, *sai_bs;
	char IV[17];
	bin128 KID;
	char *buffer;
	u32 max_size, i, subsample_count;
	GF_CENCSampleAuxInfo *sai;

	pleintext_bs = cyphertext_bs = sai_bs = NULL;
	buffer = NULL;
	max_size = 4096;

	if (!priv->crypt) return GF_SERVICE_ERROR;

	if (!evt->is_encrypted || !evt->IV_size || !evt->saiz) return GF_OK;

	cyphertext_bs = gf_bs_new(evt->data, evt->data_size, GF_BITSTREAM_READ);
	sai_bs = gf_bs_new(evt->sai, evt->saiz, GF_BITSTREAM_READ);
	pleintext_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	buffer = (char*)gf_malloc(sizeof(char) * max_size);

	sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
	if (!sai) {
		e = GF_IO_ERR;
		goto exit;
	}
	memset(sai, 0, sizeof(GF_CENCSampleAuxInfo));
	sai->IV_size = evt->IV_size;
	/*read sample auxiliary information from bitstream*/
	gf_bs_read_data(sai_bs,  (char *)KID, 16);
	gf_bs_read_data(sai_bs, (char *)sai->IV, sai->IV_size);
	sai->subsample_count = gf_bs_read_u16(sai_bs);
	if (sai->subsample_count) {
		sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry));
		for (i = 0; i < sai->subsample_count; i++) {
			sai->subsamples[i].bytes_clear_data = gf_bs_read_u16(sai_bs);
			sai->subsamples[i].bytes_encrypted_data = gf_bs_read_u32(sai_bs);
		}
	}


	for (i = 0; i < priv->KID_count; i++) {
		if (!strncmp((const char *)KID, (const char *)priv->KIDs[i], 16)) {
			memmove(priv->key, priv->keys[i], 16);
			break;
		}
	}

	if (priv->first_crypted_samp) {
		memmove(IV, sai->IV, sai->IV_size);
		if (sai->IV_size == 8)
			memset(IV+8, 0, sizeof(char)*8);
		e = gf_crypt_init(priv->crypt, priv->key, 16, IV);
		if (e) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot initialize AES-128 AES-128 %s (%s)\n", priv->is_cenc ? "CTR" : "CBC", gf_error_to_string(e)) );
			e = GF_IO_ERR;
			goto exit;
		}
		priv->first_crypted_samp = GF_FALSE;
	} else {
		if (priv->is_cenc) {
			GF_BitStream *bs;
			bs = gf_bs_new(IV, 17, GF_BITSTREAM_WRITE);
			gf_bs_write_u8(bs, 0);	/*begin of counter*/
			gf_bs_write_data(bs,(char *)sai->IV, sai->IV_size);
			if (sai->IV_size == 8)
				gf_bs_write_u64(bs, 0); /*0-padded if IV_size == 8*/
			gf_bs_del(bs);
			gf_crypt_set_state(priv->crypt, IV, 17);
		}
		e = gf_crypt_set_key(priv->crypt, priv->key, 16, IV);
		if (e) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_AUTHOR, ("[CENC] Cannot set key AES-128 %s (%s)\n", priv->is_cenc ? "CTR" : "CBC", gf_error_to_string(e)) );
			e = GF_IO_ERR;
			goto exit;
		}
	}

	//sub-sample encryption
	if (sai->subsample_count) {
		subsample_count = 0;
		while (gf_bs_available(cyphertext_bs)) {
			if (subsample_count >= sai->subsample_count)
				break;

			/*read clear data and write it to pleintext bitstream*/
			if (max_size < sai->subsamples[subsample_count].bytes_clear_data) {
				buffer = (char*)gf_realloc(buffer, sizeof(char)*sai->subsamples[subsample_count].bytes_clear_data);
				max_size = sai->subsamples[subsample_count].bytes_clear_data;
			}
			gf_bs_read_data(cyphertext_bs, buffer, sai->subsamples[subsample_count].bytes_clear_data);
			gf_bs_write_data(pleintext_bs, buffer, sai->subsamples[subsample_count].bytes_clear_data);

			/*now read encrypted data, decrypted it and write to pleintext bitstream*/
			if (max_size < sai->subsamples[subsample_count].bytes_encrypted_data) {
				buffer = (char*)gf_realloc(buffer, sizeof(char)*sai->subsamples[subsample_count].bytes_encrypted_data);
				max_size = sai->subsamples[subsample_count].bytes_encrypted_data;
			}
			gf_bs_read_data(cyphertext_bs, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);
			gf_crypt_decrypt(priv->crypt, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);
			gf_bs_write_data(pleintext_bs, buffer, sai->subsamples[subsample_count].bytes_encrypted_data);

			subsample_count++;
		}
		if (buffer) gf_free(buffer);
		gf_bs_get_content(pleintext_bs, &buffer, &evt->data_size);
	}
	//full sample encryption
	else {
		if (max_size < evt->data_size) {
			buffer = (char*)gf_realloc(buffer, sizeof(char)*evt->data_size);
		}
		gf_bs_read_data(cyphertext_bs, buffer, evt->data_size);
		gf_crypt_decrypt(priv->crypt, buffer, evt->data_size);
	}
	memmove(evt->data, buffer, evt->data_size);

exit:
	if (pleintext_bs) gf_bs_del(pleintext_bs);
	if (sai_bs) gf_bs_del(sai_bs);
	if (cyphertext_bs) gf_bs_del(cyphertext_bs);
	if (buffer) gf_free(buffer);
	if (sai && sai->subsamples) gf_free(sai->subsamples);
	if (sai) gf_free(sai);
	return e;
}