Change History
+2007.10.29 - Bug fixes v.1.2.17
+ o Changed Result_t implementation to use int instead of long, which
+ was causing trouble on some 64 bit platforms.
+ o Fixed EKLV HMAC. Broke backward compatibility with older Interop
+ files. To validate these files use asdcplib-1.1.14. This should
+ not cause too much trouble since files with broken and non-broken
+ HMAC have been in the wild for years without trouble.
+ o Fixed HMAC sequence numbering in encrypted stereoscopic files.
+ o Finished stereoscopic test targets in the makefile.
+ o Fixed the win32 build, now expects VS2005 compiler by default,
+ use WITH_VC6=1 top get VS6 flags.
+
+
2007.10.22 - Timed Text, Stereoscopic Picture and Bug fixes v.1.2.16
o Significant API changes have been made. Please read all entries
in this changelog to be sure you understand the changes. Also
// 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
const ui32_t VERSION_MAJOR = 1;
const ui32_t VERSION_APIMINOR = 2;
- const ui32_t VERSION_IMPMINOR = 16;
+ const ui32_t VERSION_IMPMINOR = 17;
const char* Version();
// UUIDs are passed around as strings of UUIDlen bytes
static const ui32_t B_len = 64; // rfc 2104, Sec. 2
-static byte_t ipad[KeyLen] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 };
+static byte_t ipad[B_len] = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+};
-static byte_t opad[KeyLen] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c };
+static byte_t opad[B_len] = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+};
class HMACContext::h__HMACContext
{
public:
byte_t m_SHAValue[HMAC_SIZE];
- LabelSet_t m_SetType;
bool m_Final;
h__HMACContext() : m_Final(false) {}
byte_t rng_buf[SHA_DIGEST_LENGTH*2];
Kumu::Gen_FIPS_186_Value(key, KeyLen, rng_buf, SHA_DIGEST_LENGTH*2);
memcpy(m_key, rng_buf+SHA_DIGEST_LENGTH, KeyLen);
- m_SetType = LS_MXF_SMPTE;
Reset();
}
SHA1_Update(&SHA, key_nonce, KeyLen);
SHA1_Final(sha_buf, &SHA);
memcpy(m_key, sha_buf, KeyLen);
- m_SetType = LS_MXF_INTEROP;
Reset();
}
Reset()
{
byte_t xor_buf[B_len];
+ memset(xor_buf, 0, B_len);
+ memcpy(xor_buf, m_key, KeyLen);
+
memset(m_SHAValue, 0, HMAC_SIZE);
m_Final = false;
SHA1_Init(&m_SHA);
// H(K XOR opad, H(K XOR ipad, text))
// ^^^^^^^^^^
- ui32_t i = 0;
-
- for ( ; i < KeyLen; i++ )
- xor_buf[i] = m_key[i] ^ ipad[i];
-
- if ( m_SetType == LS_MXF_SMPTE )
- {
- for ( ; i < B_len; i++ )
- xor_buf[i] = 0 ^ ipad[0];
-
- SHA1_Update(&m_SHA, xor_buf, B_len);
- }
- else
- {
- SHA1_Update(&m_SHA, xor_buf, KeyLen);
- }
+ for ( ui32_t i = 0; i < B_len; i++ )
+ xor_buf[i] ^= ipad[i];
+
+ SHA1_Update(&m_SHA, xor_buf, B_len);
}
//
void
Finalize()
{
- // H(K XOR opad, H(K XOR ipad, text))
- // ^^^^^^^^^^^^^^^
- SHA1_Final(m_SHAValue, &m_SHA);
-
SHA_CTX SHA;
SHA1_Init(&SHA);
byte_t xor_buf[B_len];
- ui32_t i = 0;
-
- for ( ; i < KeyLen; i++ )
- xor_buf[i] = m_key[i] ^ opad[i];
-
- if ( m_SetType == LS_MXF_SMPTE )
- {
- for ( ; i < B_len; i++ )
- xor_buf[i] = 0 ^ opad[0];
-
- SHA1_Update(&m_SHA, xor_buf, B_len);
- }
- else
- {
- SHA1_Update(&m_SHA, xor_buf, KeyLen);
- }
-
- SHA1_Update(&SHA, xor_buf, KeyLen);
+ memset(xor_buf, 0, B_len);
+ memcpy(xor_buf, m_key, KeyLen);
+
+ SHA1_Init(&SHA);
+
+ // H(K XOR opad, H(K XOR ipad, text))
+ // ^^^^^^^^^^
+ for ( ui32_t i = 0; i < B_len; i++ )
+ xor_buf[i] ^= opad[i];
+
+ SHA1_Update(&SHA, xor_buf, B_len);
+
+ // H(K XOR opad, H(K XOR ipad, text))
+ // ^
+ SHA1_Final(m_SHAValue, &m_SHA);
SHA1_Update(&SHA, m_SHAValue, HMAC_SIZE);
+ // H(K XOR opad, H(K XOR ipad, text))
+ // ^
SHA1_Final(m_SHAValue, &SHA);
m_Final = true;
}
if( ASDCP_SUCCESS(result) )
{
- m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor),
- (InterchangeObject**)&m_EssenceDescriptor);
- m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor),
- (InterchangeObject**)&m_EssenceSubDescriptor);
+ InterchangeObject* tmp_iobj = 0;
+ m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(RGBAEssenceDescriptor), &tmp_iobj);
+ m_EssenceDescriptor = static_cast<RGBAEssenceDescriptor*>(tmp_iobj);
+
+ m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(JPEG2000PictureSubDescriptor), &tmp_iobj);
+ m_EssenceSubDescriptor = static_cast<JPEG2000PictureSubDescriptor*>(tmp_iobj);
std::list<InterchangeObject*> ObjectList;
m_HeaderPart.GetMDObjectsByType(OBJ_TYPE_ARGS(Track), ObjectList);
}
if( ASDCP_SUCCESS(result) )
- result = ReadEKLVPacket(FrameNum, FrameBuf, Dict::ul(MDD_JPEG2000Essence), Ctx, HMAC);
+ {
+ ui32_t SequenceNum = FrameNum * 2;
+ SequenceNum += ( phase == SP_RIGHT ) ? 2 : 1;
+ result = ReadEKLVPacket(FrameNum, SequenceNum, FrameBuf, Dict::ul(MDD_JPEG2000Essence), Ctx, HMAC);
+ }
return result;
}
IndexTableSegment::IndexEntry Entry;
Entry.StreamOffset = StreamOffset;
m_FooterPart.PushIndexEntry(Entry);
- m_FramesWritten++;
}
+ m_FramesWritten++;
return result;
}
if ( m_NextPhase != SP_LEFT )
return RESULT_SPHASE;
+ assert( m_FramesWritten % 2 == 0 );
+ m_FramesWritten /= 2;
return lh__Writer::Finalize();
}
};
class ASDCP::TimedText::MXFReader::h__Reader : public ASDCP::h__Reader
{
- TimedTextDescriptor* m_EssenceDescriptor;
- ResourceMap_t m_ResourceMap;
+ DCTimedTextDescriptor* m_EssenceDescriptor;
+ ResourceMap_t m_ResourceMap;
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
for ( ; sdi != TDescObj->SubDescriptors.end() && KM_SUCCESS(result); sdi++ )
{
- result = m_HeaderPart.GetMDObjectByID(*sdi, (InterchangeObject**)&DescObject);
+ InterchangeObject* tmp_iobj = 0;
+ result = m_HeaderPart.GetMDObjectByID(*sdi, &tmp_iobj);
+ DescObject = static_cast<DCTimedTextResourceDescriptor*>(tmp_iobj);
if ( KM_SUCCESS(result) )
{
if( ASDCP_SUCCESS(result) )
{
if ( m_EssenceDescriptor == 0 )
- m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor), (InterchangeObject**)&m_EssenceDescriptor);
+ {
+ InterchangeObject* tmp_iobj = 0;
+ result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(DCTimedTextDescriptor), &tmp_iobj);
+ m_EssenceDescriptor = static_cast<DCTimedTextDescriptor*>(tmp_iobj);
+ }
- result = MD_to_TimedText_TDesc(m_TDesc);
+ if( ASDCP_SUCCESS(result) )
+ result = MD_to_TimedText_TDesc(m_TDesc);
}
if( ASDCP_SUCCESS(result) )
DCTimedTextResourceDescriptor* DescObject = 0;
// get the subdescriptor
- Result_t result = m_HeaderPart.GetMDObjectByID((*ri).second, (InterchangeObject**)&DescObject);
+ InterchangeObject* tmp_iobj = 0;
+ Result_t result = m_HeaderPart.GetMDObjectByID((*ri).second, &tmp_iobj);
+ DescObject = static_cast<DCTimedTextResourceDescriptor*>(tmp_iobj);
if ( KM_SUCCESS(result) )
{
// read the essence packet
if( ASDCP_SUCCESS(result) )
- result = ReadEKLVPacket(0, FrameBuf, Dict::ul(MDD_DCTimedTextDescriptor), Ctx, HMAC);
+ result = ReadEKLVPacket(0, 1, FrameBuf, Dict::ul(MDD_DCTimedTextDescriptor), Ctx, HMAC);
}
}
}
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
// reads from current position
- Result_t ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ Result_t ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC);
void Close();
};
class Result_t
{
- long value;
+ int value;
const char* label;
Result_t();
public:
- static const Result_t& Find(long);
+ static const Result_t& Find(int);
- Result_t(long v, const char* l);
+ Result_t(int v, const char* l);
~Result_t();
inline bool operator==(const Result_t& rhs) const { return value == rhs.value; }
inline bool Success() const { return ( value >= 0 ); }
inline bool Failure() const { return ( value < 0 ); }
- inline long Value() const { return value; }
- inline operator long() const { return value; }
+ inline int Value() const { return value; }
+ inline operator int() const { return value; }
inline const char* Label() const { return label; }
inline operator const char*() const { return label; }
struct map_entry_t
{
- long rcode;
+ int rcode;
Kumu::Result_t* result;
};
//
const Kumu::Result_t&
-Kumu::Result_t::Find(long v)
+Kumu::Result_t::Find(int v)
{
if ( v == 0 )
return RESULT_OK;
}
//
-Kumu::Result_t::Result_t(long v, const char* l) : value(v), label(l)
+Kumu::Result_t::Result_t(int v, const char* l) : value(v), label(l)
{
assert(l);
}
if( ASDCP_SUCCESS(result) )
- result = ReadEKLVPacket(FrameNum, FrameBuf, EssenceUL, Ctx, HMAC);
+ result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
return result;
}
Result_t
-ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
{
KLReader Reader;
if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
{
IntegrityPack IntPack;
- result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, FrameNum + 1, HMAC);
+ result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
}
}
else // return ciphertext to caller