summaryrefslogtreecommitdiff
path: root/src/AS_DCP_internal.h
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2005-12-20 01:55:40 +0000
committerjhurst <>2005-12-20 01:55:40 +0000
commit8095eaa320551b6795d0368c0ad0c227a3167caa (patch)
treee522d5137671fffbc8fcc084831b5d8806ef44f2 /src/AS_DCP_internal.h
wheee!
Diffstat (limited to 'src/AS_DCP_internal.h')
-rwxr-xr-xsrc/AS_DCP_internal.h299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h
new file mode 100755
index 0000000..473a4ab
--- /dev/null
+++ b/src/AS_DCP_internal.h
@@ -0,0 +1,299 @@
+/*
+Copyright (c) 2004-2005, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file AS_DCP_internal.h
+ \version $Id$
+ \brief AS-DCP library, non-public common elements
+*/
+
+#ifndef _AS_DCP_INTERNAL_H__
+#define _AS_DCP_INTERNAL_H__
+
+#include "AS_DCP_system.h"
+#include "Metadata.h"
+#include "hex_utils.h"
+
+using namespace std;
+using namespace ASDCP;
+using namespace ASDCP::MXF;
+
+
+
+namespace ASDCP
+{
+ // constant values used to calculate KLV and EKLV packet sizes
+ static const ui32_t klv_key_size = 16;
+ static const ui32_t klv_length_size = 4;
+
+ static const ui32_t klv_cryptinfo_size =
+ klv_length_size
+ + UUIDlen /* ContextID */
+ + klv_length_size
+ + sizeof(ui64_t) /* PlaintextOffset */
+ + klv_length_size
+ + klv_key_size /* SourceKey */
+ + klv_length_size
+ + sizeof(ui64_t) /* SourceLength */
+ + klv_length_size /* ESV length */ ;
+
+ static const ui32_t klv_intpack_size =
+ klv_length_size
+ + UUIDlen /* TrackFileID */
+ + klv_length_size
+ + sizeof(ui64_t) /* SequenceNumber */
+ + klv_length_size
+ + 20; /* HMAC length*/
+
+ // why this value? i dunno. it was peeled from mxflib.
+ static const ui32_t HeaderPadding = 16384;
+
+ const byte_t GCMulti_Data[16] =
+ { 0x06, 0x0E, 0x2B, 0x34, 0x04, 0x01, 0x01, 0x03,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7F, 0x01, 0x00 };
+
+ static const byte_t CipherAlgorithm_AES[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07,
+ 0x02, 0x09, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00 };
+
+ static const byte_t MICAlgorithm_NONE[klv_key_size] = {0};
+ static const byte_t MICAlgorithm_HMAC_SHA1[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07,
+ 0x02, 0x09, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00 };
+
+#ifdef SMPTE_LABELS
+ static byte_t OPAtom_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02,
+ 0x0d, 0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 };
+ static UL OPAtomUL(OPAtom_Data);
+#else
+ static byte_t OPAtom_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
+ 0x0d, 0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00 };
+ static UL OPAtomUL(OPAtom_Data);
+#endif
+
+ static const byte_t OP1a_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
+ 0x0d, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00 };
+ static UL OP1aUL(OP1a_Data);
+
+ // Essence element labels
+ static const byte_t WAVEssenceUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,
+ 0x0d, 0x01, 0x03, 0x01, 0x16, 0x01, 0x01, 0x00 };
+
+ static const byte_t MPEGEssenceUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,
+ 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x05, 0x00 };
+
+ static const byte_t JP2KEssenceUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01,
+ 0x0d, 0x01, 0x03, 0x01, 0x15, 0x01, 0x08, 0x01 };
+
+#ifdef SMPTE_LABELS
+ static const byte_t CryptEssenceUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x04, 0x01, 0x01,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7e, 0x01, 0x00 };
+#else
+ static const byte_t CryptEssenceUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x02, 0x04, 0x01, 0x07,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x7e, 0x01, 0x00 };
+#endif
+
+ // Essence Container Labels
+ static const byte_t WrappingUL_Data_PCM_24b_48k[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x01,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x06, 0x01, 0x00 };
+
+ static const byte_t WrappingUL_Data_MPEG2_VES[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x02,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x04, 0x60, 0x01 };
+
+ static const byte_t WrappingUL_Data_JPEG_2000[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x0c, 0x01, 0x00 };
+
+ static const byte_t WrappingUL_Data_Crypt[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07,
+ 0x0d, 0x01, 0x03, 0x01, 0x02, 0x0b, 0x01, 0x00 };
+
+
+ // the label for the Cryptographic Framework DM scheme
+ static const byte_t CryptoFrameworkUL_Data[klv_key_size] =
+ { 0x06, 0x0e, 0x2b, 0x34, 0x04, 0x01, 0x01, 0x07,
+ 0x0d, 0x01, 0x04, 0x01, 0x02, 0x01, 0x01, 0x00 };
+
+ // the check value for EKLV packets
+ // CHUKCHUKCHUKCHUK
+ static const byte_t ESV_CheckValue[CBC_BLOCK_SIZE] =
+ { 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b,
+ 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b };
+
+ // labels used for FilePackages
+ static std::string MPEG_PACKAGE_LABEL = "File Package: SMPTE 381M frame wrapping of MPEG2 video elementary stream";
+ static std::string JP2K_PACKAGE_LABEL = "File Package: SMPTE XXXM frame wrapping of JPEG 2000 codestreams";
+ static std::string PCM_PACKAGE_LABEL = "File Package: SMPTE 382M frame wrapping of wave audio";
+
+ // GetMDObjectByPath() allows searching for metadata object by pathname
+ // This character separates the path elements.
+ static const char OBJECT_PATH_SEPARATOR = '.';
+
+ //------------------------------------------------------------------------------------------
+ //
+
+ // MDObject* GetMDObjectByPath(MDObject&, const std::string);
+ // MDObject* GetMDObjectByType(MDObject&, const std::string);
+ // void DumpMDObject(MDObject&, std::string = " ", FILE* = 0);
+ // void DumpHeader(Partition&, FILE* = 0);
+ // void DumpIndexTable(IndexTablePtr, ui64_t = 0, FILE* = 0);
+ // Result_t init_mxf_types();
+ Result_t MD_to_MPEG2_VDesc(MXF::MPEG2VideoDescriptor*, MPEG2::VideoDescriptor&);
+ Result_t MD_to_JP2K_PDesc(MXF::RGBAEssenceDescriptor*, JP2K::PictureDescriptor&);
+ Result_t MD_to_PCM_ADesc(MXF::WaveAudioDescriptor*, PCM::AudioDescriptor&);
+ Result_t MD_to_WriterInfo(MXF::Identification*, WriterInfo&);
+ Result_t MD_to_CryptoInfo(MXF::CryptographicContext*, WriterInfo&);
+
+#if 0
+ Result_t MPEG2_VDesc_to_MD(MPEG2::VideoDescriptor&, MDObject&);
+ Result_t JP2K_PDesc_to_MD(JP2K::PictureDescriptor&, MDObject&);
+ Result_t PCM_ADesc_to_MD(PCM::AudioDescriptor&, MDObject&);
+ void AddDMScrypt(PackagePtr, WriterInfo&, const byte_t*);
+#endif
+
+ Result_t EncryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESEncContext*);
+ Result_t DecryptFrameBuffer(const ASDCP::FrameBuffer&, ASDCP::FrameBuffer&, AESDecContext*);
+
+ // calculate size of encrypted essence with IV, CheckValue, and padding
+ inline ui32_t
+ calc_esv_length(ui32_t source_length, ui32_t plaintext_offset)
+ {
+ ui32_t ct_size = source_length - plaintext_offset;
+ ui32_t diff = ct_size % CBC_BLOCK_SIZE;
+ ui32_t block_size = ct_size - diff;
+ return plaintext_offset + block_size + (CBC_BLOCK_SIZE * 3);
+ }
+
+ //
+ class h__Reader
+ {
+ ASDCP_NO_COPY_CONSTRUCT(h__Reader);
+
+ public:
+ FileReader m_File;
+ OPAtomHeader m_HeaderPart;
+ Partition m_BodyPart;
+ OPAtomIndexFooter m_FooterPart;
+ ui64_t m_EssenceStart;
+ WriterInfo m_Info;
+ ASDCP::FrameBuffer m_CtFrameBuf;
+
+ h__Reader();
+ virtual ~h__Reader();
+ //
+ // MDObject* GetMDObjectByType(const std::string ObjName);
+ // MDObject* GetMDObjectByPath(const std::string ObjPath);
+ Result_t InitInfo(WriterInfo& Info);
+ Result_t OpenMXFRead(const char* filename);
+ Result_t InitMXFIndex();
+ Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
+ void Close();
+ };
+
+ // helper class for calculating Integrity Packs, used by WriteEKLVPacket() below.
+ //
+ class IntegrityPack
+ {
+ public:
+ byte_t Data[klv_intpack_size];
+
+ IntegrityPack() {
+ memset(Data, 0, klv_intpack_size);
+ }
+
+ ~IntegrityPack() {}
+
+ Result_t CalcValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
+ Result_t TestValues(const ASDCP::FrameBuffer&, byte_t* AssetID, ui32_t sequence, HMACContext* HMAC);
+ };
+
+ //
+ class KLVReader
+ {
+ byte_t m_Key[32];
+ ui64_t m_Length;
+ ui32_t m_BERLength;
+ ui32_t m_HeaderLength;
+
+ ASDCP_NO_COPY_CONSTRUCT(KLVReader);
+
+ public:
+ KLVReader() : m_Length(0), m_BERLength(0), m_HeaderLength(0) {}
+ ~KLVReader() {}
+
+ inline const byte_t* Key() { return m_Key; }
+ inline const ui64_t Length() { return m_Length; }
+ inline const ui64_t KLLength() { return m_BERLength + klv_key_size; }
+ Result_t ReadKLFromFile(ASDCP::FileReader& Reader);
+#if 0
+ //
+ {
+ ui32_t read_count;
+ m_HeaderLength = klv_key_size + klv_length_size;
+ Result_t result = Reader.Read(m_Key, m_HeaderLength, &read_count);
+ assert(read_count == m_HeaderLength);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ m_BERLength = BER_length(m_Key + klv_key_size);
+
+ if ( m_BERLength != klv_length_size )
+ {
+ ASDCP::DefaultLogSink().Error("Found packet with BER length %lu; being less efficient...\n",
+ m_BERLength);
+ // TODO: recover the correct BER value
+ // and reposition the file pointer
+ assert(0);
+ }
+
+ if ( ! read_BER(m_Key + klv_key_size, &m_Length) )
+ return RESULT_FAIL;
+ }
+
+ return result;
+ }
+#endif
+
+ };
+
+} // namespace ASDCP
+
+#endif // _AS_DCP_INTERNAL_H__
+
+
+//
+// end AS_DCP_internal.h
+//