/*---------------------------------------------------------------------- | AP4_OmaDcfCbcSampleEncrypter::EncryptSampleData +---------------------------------------------------------------------*/ AP4_Result AP4_OmaDcfCbcSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out, AP4_UI64 counter, bool /*skip_encryption*/) { // make sure there is enough space in the output buffer data_out.Reserve(data_in.GetDataSize()+2*AP4_CIPHER_BLOCK_SIZE+1); // setup the buffers AP4_Size out_size = data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE; unsigned char* out = data_out.UseData(); // selective encryption flag *out++ = 0x80; // IV on 16 bytes: [SSSSSSSSXXXXXXXX] // where SSSSSSSS is the 64-bit salt and // XXXXXXXX is the 64-bit base counter AP4_CopyMemory(out, m_Salt, 8); AP4_BytesFromUInt64BE(&out[8], counter); // encrypt the payload m_Cipher->SetIV(out); m_Cipher->ProcessBuffer(data_in.GetData(), data_in.GetDataSize(), out+AP4_CIPHER_BLOCK_SIZE, &out_size, true); AP4_CHECK(data_out.SetDataSize(out_size+AP4_CIPHER_BLOCK_SIZE+1)); return AP4_SUCCESS; }
/*---------------------------------------------------------------------- | AP4_OmaDcfCtrSampleEncrypter::EncryptSampleData +---------------------------------------------------------------------*/ AP4_Result AP4_OmaDcfCtrSampleEncrypter::EncryptSampleData(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out, AP4_UI64 counter, bool /*skip_encryption*/) { // setup the buffers const unsigned char* in = data_in.GetData(); AP4_CHECK(data_out.SetDataSize(data_in.GetDataSize()+AP4_CIPHER_BLOCK_SIZE+1)); unsigned char* out = data_out.UseData(); // selective encryption flag *out++ = 0x80; // IV on 16 bytes: [SSSSSSSSXXXXXXXX] // where SSSSSSSS is the 64-bit salt and // XXXXXXXX is the 64-bit base counter AP4_CopyMemory(out, m_Salt, 8); AP4_BytesFromUInt64BE(&out[8], counter); // encrypt the payload AP4_Size data_size = data_in.GetDataSize(); m_Cipher->SetIV(out); m_Cipher->ProcessBuffer(in, data_size, out+AP4_CIPHER_BLOCK_SIZE); return AP4_SUCCESS; }
/*---------------------------------------------------------------------- | AP4_BytesFromDoubleBE +---------------------------------------------------------------------*/ void AP4_BytesFromDoubleBE(unsigned char* bytes, double value) { void* v_value = reinterpret_cast<void*>(&value); AP4_UI64* i_value = reinterpret_cast<AP4_UI64*>(v_value); AP4_BytesFromUInt64BE(bytes, *i_value); }
/*---------------------------------------------------------------------- | AP4_ByteStream::WriteUI64 +---------------------------------------------------------------------*/ AP4_Result AP4_ByteStream::WriteUI64(AP4_UI64 value) { unsigned char buffer[8]; // convert value to bytes AP4_BytesFromUInt64BE(buffer, value); // write bytes to the stream return Write((void*)buffer, 8); }
/*---------------------------------------------------------------------- | AP4_CtrStreamCipher::ComputeCounter +---------------------------------------------------------------------*/ void AP4_CtrStreamCipher::ComputeCounter(AP4_UI64 stream_offset, AP4_UI08 counter_block[AP4_CIPHER_BLOCK_SIZE]) { // setup counter offset bytes AP4_UI64 counter_offset = stream_offset/AP4_CIPHER_BLOCK_SIZE; AP4_UI08 counter_offset_bytes[8]; AP4_BytesFromUInt64BE(counter_offset_bytes, counter_offset); // compute the new counter unsigned int carry = 0; for (unsigned int i=0; i<m_CounterSize; i++) { unsigned int o = AP4_CIPHER_BLOCK_SIZE-1-i; unsigned int x = m_IV[o]; unsigned int y = (i<8)?counter_offset_bytes[7-i]:0; unsigned int sum = x+y+carry; counter_block[o] = (AP4_UI08)(sum&0xFF); carry = ((sum >= 0x100)?1:0); } for (unsigned int i=m_CounterSize; i<AP4_CIPHER_BLOCK_SIZE; i++) { unsigned int o = AP4_CIPHER_BLOCK_SIZE-1-i; counter_block[o] = m_IV[o]; } }