static ui32_t calc_CBR_frame_size(ASDCP::WriterInfo& Info, const ASDCP::PCM::AudioDescriptor& ADesc) { ui32_t CBR_frame_size = 0; if ( Info.EncryptedEssence ) { CBR_frame_size = SMPTE_UL_LENGTH + MXF_BER_LENGTH + klv_cryptinfo_size + calc_esv_length(ASDCP::PCM::CalcFrameBufferSize(ADesc), 0) + ( Info.UsesHMAC ? klv_intpack_size : (MXF_BER_LENGTH * 3) ); } else { CBR_frame_size = ASDCP::PCM::CalcFrameBufferSize(ADesc) + SMPTE_UL_LENGTH + MXF_BER_LENGTH; } return CBR_frame_size; }
Result_t ASDCP::EncryptFrameBuffer(const ASDCP::FrameBuffer& FBin, ASDCP::FrameBuffer& FBout, AESEncContext* Ctx) { ASDCP_TEST_NULL(Ctx); FBout.Size(0); // size the buffer Result_t result = FBout.Capacity(calc_esv_length(FBin.Size(), FBin.PlaintextOffset())); // write the IV byte_t* p = FBout.Data(); // write the IV to the frame buffer Ctx->GetIVec(p); p += CBC_BLOCK_SIZE; // encrypt the check value to the frame buffer if ( ASDCP_SUCCESS(result) ) { result = Ctx->EncryptBlock(ESV_CheckValue, p, CBC_BLOCK_SIZE); p += CBC_BLOCK_SIZE; } // write optional plaintext region if ( FBin.PlaintextOffset() > 0 ) { assert(FBin.PlaintextOffset() <= FBin.Size()); memcpy(p, FBin.RoData(), FBin.PlaintextOffset()); p += FBin.PlaintextOffset(); } ui32_t ct_size = FBin.Size() - FBin.PlaintextOffset(); ui32_t diff = ct_size % CBC_BLOCK_SIZE; ui32_t block_size = ct_size - diff; assert((block_size % CBC_BLOCK_SIZE) == 0); // encrypt the ciphertext region essence data if ( ASDCP_SUCCESS(result) ) { result = Ctx->EncryptBlock(FBin.RoData() + FBin.PlaintextOffset(), p, block_size); p += block_size; } // construct and encrypt the padding if ( ASDCP_SUCCESS(result) ) { byte_t the_last_block[CBC_BLOCK_SIZE]; if ( diff > 0 ) memcpy(the_last_block, FBin.RoData() + FBin.PlaintextOffset() + block_size, diff); for (ui32_t i = 0; diff < CBC_BLOCK_SIZE; diff++, i++ ) the_last_block[diff] = i; result = Ctx->EncryptBlock(the_last_block, p, CBC_BLOCK_SIZE); } if ( ASDCP_SUCCESS(result) ) FBout.Size(calc_esv_length(FBin.Size(), FBin.PlaintextOffset())); return result; }