/*---------------------------------------------------------------------- | AP4_GrpiAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_GrpiAtom::WriteFields(AP4_ByteStream& stream) { AP4_CHECK(stream.WriteUI16((AP4_UI16)m_GroupId.GetLength())); AP4_CHECK(stream.WriteUI08(m_KeyEncryptionMethod)); AP4_CHECK(stream.WriteUI16((AP4_UI16)m_GroupKey.GetDataSize())); AP4_CHECK(stream.Write(m_GroupId.GetChars(), m_GroupId.GetLength())); AP4_CHECK(stream.Write(m_GroupKey.GetData(), m_GroupKey.GetDataSize())); return AP4_SUCCESS; }
/*---------------------------------------------------------------------- | AP4_OdheAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_OdheAtom::WriteFields(AP4_ByteStream& stream) { // write the content type AP4_CHECK(stream.WriteUI08((AP4_UI08)m_ContentType.GetLength())); if (m_ContentType.GetLength()) { AP4_CHECK(stream.Write(m_ContentType.GetChars(), m_ContentType.GetLength())); } // write the children return m_Children.Apply(AP4_AtomListWriter(stream)); }
/*---------------------------------------------------------------------- | 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_OmaDcfCtrSampleDecrypter::DecryptSampleData +---------------------------------------------------------------------*/ AP4_Result AP4_OmaDcfCtrSampleDecrypter::DecryptSampleData(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out, const AP4_UI08* /*iv*/) { bool is_encrypted = true; const unsigned char* in = data_in.GetData(); AP4_Size in_size = data_in.GetDataSize(); // default to 0 output AP4_CHECK(data_out.SetDataSize(0)); // check the selective encryption flag if (m_SelectiveEncryption) { if (in_size < 1) return AP4_ERROR_INVALID_FORMAT; is_encrypted = ((in[0]&0x80)!=0); in++; } // check the size unsigned int header_size = (m_SelectiveEncryption?1:0)+(is_encrypted?m_IvLength:0); if (header_size > in_size) return AP4_ERROR_INVALID_FORMAT; // process the sample data AP4_Size payload_size = in_size-header_size; AP4_CHECK(data_out.Reserve(payload_size)); unsigned char* out = data_out.UseData(); if (is_encrypted) { // set the IV if (m_IvLength == 16) { m_Cipher->SetIV(in); } else { AP4_UI08 iv[16]; AP4_SetMemory(iv, 0, 16); AP4_CopyMemory(iv+16-m_IvLength, in, m_IvLength); m_Cipher->SetIV(iv); } AP4_CHECK(m_Cipher->ProcessBuffer(in+m_IvLength, payload_size, out)); } else { AP4_CopyMemory(out, in, payload_size); } AP4_CHECK(data_out.SetDataSize(payload_size)); return AP4_SUCCESS; }
/*---------------------------------------------------------------------- | AP4_OmaDbcCbcSampleDecrypter::DecryptSampleData +---------------------------------------------------------------------*/ AP4_Result AP4_OmaDcfCbcSampleDecrypter::DecryptSampleData(AP4_DataBuffer& data_in, AP4_DataBuffer& data_out, const AP4_UI08* /*iv*/) { bool is_encrypted = true; const unsigned char* in = data_in.GetData(); AP4_Size in_size = data_in.GetDataSize(); AP4_Size out_size; // default to 0 output AP4_CHECK(data_out.SetDataSize(0)); // check the selective encryption flag if (m_SelectiveEncryption) { if (in_size < 1) return AP4_ERROR_INVALID_FORMAT; is_encrypted = ((in[0]&0x80)!=0); in++; } // check the size unsigned int header_size = (m_SelectiveEncryption?1:0)+(is_encrypted?m_IvLength:0); if (header_size > in_size) return AP4_ERROR_INVALID_FORMAT; // process the sample data unsigned int payload_size = in_size-header_size; data_out.Reserve(payload_size); unsigned char* out = data_out.UseData(); if (is_encrypted) { // get the IV const AP4_UI08* iv = (const AP4_UI08*)in; in += AP4_CIPHER_BLOCK_SIZE; m_Cipher->SetIV(iv); out_size = payload_size; AP4_CHECK(m_Cipher->ProcessBuffer(in, payload_size, out, &out_size, true)); } else { AP4_CopyMemory(out, in, payload_size); out_size = payload_size; } AP4_CHECK(data_out.SetDataSize(out_size)); return AP4_SUCCESS; }
/*---------------------------------------------------------------------- | AP4_OddaAtom::WriteFields +---------------------------------------------------------------------*/ AP4_Result AP4_OddaAtom::WriteFields(AP4_ByteStream& stream) { // write the content type AP4_CHECK(stream.WriteUI64(m_EncryptedDataLength)); // check that we have a source stream // and a normal size if (m_EncryptedPayload == NULL || GetSize() < 8) { return AP4_FAILURE; } // rewind the encrypted stream AP4_CHECK(m_EncryptedPayload->Seek(0)); // copy the encrypted stream to the output AP4_CHECK(m_EncryptedPayload->CopyTo(stream, m_EncryptedDataLength)); return AP4_SUCCESS; }