Exemplo n.º 1
0
static vod_status_t
mp4_encrypt_video_snpf_build_auxiliary_data(mp4_encrypt_video_state_t* state)
{
	u_char iv[MP4_AES_CTR_IV_SIZE];
	uint32_t bytes_of_encrypted_data;
	uint16_t bytes_of_clear_data;
	bool_t init_track;
	u_char* p;

	state->default_auxiliary_sample_size = sizeof(cenc_sample_auxiliary_data_t) + sizeof(cenc_sample_auxiliary_data_subsample_t);
	state->saiz_sample_count = state->base.sequence->total_frame_count;

	p = vod_alloc(
		state->base.request_context->pool, 
		state->default_auxiliary_sample_size * state->base.sequence->total_frame_count);
	if (p == NULL)
	{
		vod_log_debug0(VOD_LOG_DEBUG_LEVEL, state->base.request_context->log, 0,
			"mp4_encrypt_video_snpf_build_auxiliary_data: vod_alloc failed");
		return VOD_ALLOC_FAILED;
	}

	state->auxiliary_data.start = p;

	bytes_of_clear_data = state->base.cur_clip->first_track->media_info.u.video.nal_packet_size_length + 1;
	vod_memcpy(iv, state->base.iv, sizeof(iv));

	for (;;)
	{
		if (!mp4_encrypt_move_to_next_frame(&state->base, &init_track))
		{
			break;
		}

		if (init_track)
		{
			bytes_of_clear_data = state->base.cur_clip->first_track->media_info.u.video.nal_packet_size_length + 1;
		}

		// cenc_sample_auxiliary_data_t
		p = vod_copy(p, iv, sizeof(iv));
		mp4_aes_ctr_increment_be64(iv);
		write_be16(p, 1);		// subsample count

		// cenc_sample_auxiliary_data_subsample_t
		bytes_of_encrypted_data = state->base.cur_frame->size - bytes_of_clear_data;
		write_be16(p, bytes_of_clear_data);
		write_be32(p, bytes_of_encrypted_data);

		state->base.cur_frame++;
	}

	state->auxiliary_data.pos = p;

	// reset the state
	state->base.cur_clip = state->base.sequence->filtered_clips;
	mp4_encrypt_init_track(&state->base, state->base.cur_clip->first_track);

	return VOD_OK;
}
Exemplo n.º 2
0
u_char*
mp4_encrypt_audio_write_auxiliary_data(mp4_encrypt_state_t* state, u_char* p)
{
	u_char* end_pos = p + sizeof(state->iv) * state->sequence->total_frame_count;
	u_char iv[MP4_AES_CTR_IV_SIZE];

	vod_memcpy(iv, state->iv, sizeof(iv));

	while (p < end_pos)
	{
		p = vod_copy(p, iv, sizeof(iv));
		mp4_aes_ctr_increment_be64(iv);
	}

	return p;
}
Exemplo n.º 3
0
vod_status_t
mp4_aes_ctr_process(mp4_aes_ctr_state_t* state, u_char* dest, const u_char* src, uint32_t size)
{
	const u_char* src_end = src + size;
	const u_char* cur_end_pos;
	u_char* encrypted_counter_pos;
	int out_size;

	while (src < src_end)
	{
		if (state->block_offset == 0)
		{
			if (1 != EVP_EncryptUpdate(
				&state->cipher,
				state->encrypted_counter,
				&out_size,
				state->counter,
				sizeof(state->counter)) ||
				out_size != sizeof(state->encrypted_counter))
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"mp4_aes_ctr_process: EVP_EncryptUpdate failed");
				return VOD_UNEXPECTED;
			}

			mp4_aes_ctr_increment_be64(state->counter + 8);
		}

		encrypted_counter_pos = state->encrypted_counter + state->block_offset;
		cur_end_pos = src + MP4_AES_CTR_COUNTER_SIZE - state->block_offset;
		cur_end_pos = vod_min(cur_end_pos, src_end);

		state->block_offset += cur_end_pos - src;
		state->block_offset &= (MP4_AES_CTR_COUNTER_SIZE - 1);

		while (src < cur_end_pos)
		{
			*dest++ = *src++ ^ *encrypted_counter_pos++;
		}
	}

	return VOD_OK;
}
Exemplo n.º 4
0
static vod_status_t
mp4_encrypt_start_frame(mp4_encrypt_state_t* state)
{
	// make sure we have a frame
	if (state->cur_frame >= state->last_frame)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
		"mp4_encrypt_start_frame: no more frames");
		return VOD_BAD_DATA;
	}

	// get the frame size
	state->frame_size_left = state->cur_frame->size;
	state->cur_frame++;

	// set and increment the iv
	mp4_aes_ctr_set_iv(&state->cipher, state->iv);
	mp4_aes_ctr_increment_be64(state->iv);

	return VOD_OK;
}
Exemplo n.º 5
0
vod_status_t
mp4_aes_ctr_process(mp4_aes_ctr_state_t* state, u_char* dest, const u_char* src, uint32_t size)
{
	const u_char* src_end = src + size;
	const u_char* cur_end_pos;
	u_char* encrypted_counter_pos;
	u_char* cur_block;
	u_char* next_block;
	u_char* end_block;
	size_t encrypted_size;
	int out_size;

	while (src < src_end)
	{
		if (state->encrypted_pos >= state->encrypted_end)
		{
			// find the size of the data to encrypt
			encrypted_size = aes_round_up_to_block_exact(src_end - src);
			if (encrypted_size > sizeof(state->counter))
			{
				encrypted_size = sizeof(state->counter);
			}

			// initialize the clear counters (the first counter is already initialized)
			end_block = state->counter + encrypted_size - AES_BLOCK_SIZE;
			for (cur_block = state->counter; cur_block < end_block; cur_block = next_block)
			{
				next_block = cur_block + AES_BLOCK_SIZE;
				vod_memcpy(next_block, cur_block, AES_BLOCK_SIZE);
				mp4_aes_ctr_increment_be64(next_block + 8);
			}

			// encrypt the clear counters
			if (1 != EVP_EncryptUpdate(
				&state->cipher,
				state->encrypted_counter,
				&out_size,
				state->counter,
				encrypted_size) ||
				out_size != (int)encrypted_size)
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"mp4_aes_ctr_process: EVP_EncryptUpdate failed");
				return VOD_UNEXPECTED;
			}

			// update the first counter
			if (encrypted_size > AES_BLOCK_SIZE)
			{
				vod_memcpy(state->counter, end_block, AES_BLOCK_SIZE);
			}
			mp4_aes_ctr_increment_be64(state->counter + 8);

			state->encrypted_end = state->encrypted_counter + encrypted_size;

			encrypted_counter_pos = state->encrypted_counter;
			cur_end_pos = src + encrypted_size;
		}
		else
		{
			encrypted_counter_pos = state->encrypted_pos;
			cur_end_pos = src + (state->encrypted_end - encrypted_counter_pos);
		}

		if (src_end < cur_end_pos)
		{
			cur_end_pos = src_end;
		}

		while (src < cur_end_pos)
		{
			*dest++ = *src++ ^ *encrypted_counter_pos++;
		}

		state->encrypted_pos = encrypted_counter_pos;
	}

	return VOD_OK;
}