X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FAS_DCP_AES.cpp;h=6c81cade5fa207f5d7a3c844d7f8a160e5b1bea6;hb=19bd80c074e1dec35404fd85607a2a68c791b2d9;hp=3d3656653c82f89be794723247529b97bbc63393;hpb=8095eaa320551b6795d0368c0ad0c227a3167caa;p=asdcplib.git diff --git a/src/AS_DCP_AES.cpp b/src/AS_DCP_AES.cpp index 3d36566..6c81cad 100755 --- a/src/AS_DCP_AES.cpp +++ b/src/AS_DCP_AES.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004, John Hurst +Copyright (c) 2004-2009, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,16 +32,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include +#include +using Kumu::DefaultLogSink; using namespace ASDCP; const int KEY_SIZE_BITS = 128; - -#ifndef ASDCP_WITHOUT_OPENSSL #include #include +#include #include + void print_ssl_error() { @@ -50,16 +53,9 @@ print_ssl_error() DefaultLogSink().Error("OpenSSL: %s\n", ERR_error_string(errval, err_buf)); } -#endif - - //------------------------------------------------------------------------------------------ -#ifdef ASDCP_WITHOUT_OPENSSL -class ASDCP::AESEncContext::h__AESContext -#else class ASDCP::AESEncContext::h__AESContext : public AES_KEY -#endif { public: byte_t m_IVec[CBC_BLOCK_SIZE]; @@ -74,12 +70,11 @@ ASDCP::AESEncContext::~AESEncContext() {} ASDCP::Result_t ASDCP::AESEncContext::InitKey(const byte_t* key) { - ASDCP_TEST_NULL(key); + KM_TEST_NULL_L(key); if ( m_Context ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL m_Context = new h__AESContext; if ( AES_set_encrypt_key(key, KEY_SIZE_BITS, m_Context) ) @@ -89,9 +84,6 @@ ASDCP::AESEncContext::InitKey(const byte_t* key) } return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } @@ -101,17 +93,13 @@ ASDCP::AESEncContext::InitKey(const byte_t* key) ASDCP::Result_t ASDCP::AESEncContext::SetIVec(const byte_t* i_vec) { - ASDCP_TEST_NULL(i_vec); + KM_TEST_NULL_L(i_vec); if ( ! m_Context ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL memcpy(m_Context->m_IVec, i_vec, CBC_BLOCK_SIZE); return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } @@ -120,17 +108,13 @@ ASDCP::AESEncContext::SetIVec(const byte_t* i_vec) ASDCP::Result_t ASDCP::AESEncContext::GetIVec(byte_t* i_vec) const { - ASDCP_TEST_NULL(i_vec); + KM_TEST_NULL_L(i_vec); if ( ! m_Context ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL memcpy(i_vec, m_Context->m_IVec, CBC_BLOCK_SIZE); return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } @@ -139,15 +123,14 @@ ASDCP::AESEncContext::GetIVec(byte_t* i_vec) const ASDCP::Result_t ASDCP::AESEncContext::EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t block_size) { - ASDCP_TEST_NULL(pt_buf); - ASDCP_TEST_NULL(ct_buf); + KM_TEST_NULL_L(pt_buf); + KM_TEST_NULL_L(ct_buf); assert(block_size > 0); assert( block_size % CBC_BLOCK_SIZE == 0 ); if ( m_Context.empty() ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL h__AESContext* Ctx = m_Context; byte_t tmp_buf[CBC_BLOCK_SIZE]; const byte_t* in_p = pt_buf; @@ -168,19 +151,12 @@ ASDCP::AESEncContext::EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t } return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } //------------------------------------------------------------------------------------------ -#ifdef ASDCP_WITHOUT_OPENSSL -class ASDCP::AESDecContext::h__AESContext -#else class ASDCP::AESDecContext::h__AESContext : public AES_KEY -#endif { public: byte_t m_IVec[CBC_BLOCK_SIZE]; @@ -195,12 +171,11 @@ ASDCP::AESDecContext::~AESDecContext() {} ASDCP::Result_t ASDCP::AESDecContext::InitKey(const byte_t* key) { - ASDCP_TEST_NULL(key); + KM_TEST_NULL_L(key); if ( m_Context ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL m_Context = new h__AESContext; if ( AES_set_decrypt_key(key, KEY_SIZE_BITS, m_Context) ) @@ -210,9 +185,6 @@ ASDCP::AESDecContext::InitKey(const byte_t* key) } return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } // Initializes 16 byte CBC Initialization Vector. This operation may be performed @@ -221,17 +193,13 @@ ASDCP::AESDecContext::InitKey(const byte_t* key) ASDCP::Result_t ASDCP::AESDecContext::SetIVec(const byte_t* i_vec) { - ASDCP_TEST_NULL(i_vec); + KM_TEST_NULL_L(i_vec); if ( ! m_Context ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL memcpy(m_Context->m_IVec, i_vec, CBC_BLOCK_SIZE); return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } // Decrypt a 16 byte block of data. @@ -239,15 +207,14 @@ ASDCP::AESDecContext::SetIVec(const byte_t* i_vec) ASDCP::Result_t ASDCP::AESDecContext::DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t block_size) { - ASDCP_TEST_NULL(ct_buf); - ASDCP_TEST_NULL(pt_buf); + KM_TEST_NULL_L(ct_buf); + KM_TEST_NULL_L(pt_buf); assert(block_size > 0); assert( block_size % CBC_BLOCK_SIZE == 0 ); if ( m_Context.empty() ) return RESULT_INIT; -#ifndef ASDCP_WITHOUT_OPENSSL register h__AESContext* Ctx = m_Context; const byte_t* in_p = ct_buf; @@ -268,41 +235,64 @@ ASDCP::AESDecContext::DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t } return RESULT_OK; -#else // ASDCP_WITHOUT_OPENSSL - return RESULT_FAIL; -#endif // ASDCP_WITHOUT_OPENSSL } //------------------------------------------------------------------------------------------ +static const ui32_t B_len = 64; // rfc 2104, Sec. 2 + +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, + 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 ipad[KeyLen] = { 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, + 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 { -#ifndef ASDCP_WITHOUT_OPENSSL SHA_CTX m_SHA; -#endif // ASDCP_WITHOUT_OPENSSL - byte_t m_key[KeyLen]; + byte_t m_key[KeyLen]; ASDCP_NO_COPY_CONSTRUCT(h__HMACContext); public: - byte_t sha_value[HMAC_SIZE]; - bool m_Final; + byte_t m_SHAValue[HMAC_SIZE]; + bool m_Final; h__HMACContext() : m_Final(false) {} ~h__HMACContext() {} - // + // SMPTE 429.6 MIC key generation void SetKey(const byte_t* key) + { + byte_t rng_buf[SHA_DIGEST_LENGTH*2]; + Kumu::Gen_FIPS_186_Value(key, KeyLen, rng_buf, SHA_DIGEST_LENGTH*2); + + // rng_buf contains two rounds, x0 and x1 (each 160 bits). + // Use x1 per SMPTE 430-6-2006 Sec. 7.10 + memcpy(m_key, rng_buf+SHA_DIGEST_LENGTH, KeyLen); + Reset(); + } + + // MXF Interop MIC key generation + void SetInteropKey(const byte_t* key) { static byte_t key_nonce[KeyLen] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#ifndef ASDCP_WITHOUT_OPENSSL byte_t sha_buf[SHA_DIGEST_LENGTH]; // 7.10: MICKey = trunc( SHA1 ( key, key_nonce ) ) @@ -312,63 +302,67 @@ public: SHA1_Update(&SHA, key_nonce, KeyLen); SHA1_Final(sha_buf, &SHA); memcpy(m_key, sha_buf, KeyLen); - Reset(); -#endif // ASDCP_WITHOUT_OPENSSL } + // void Reset() { -#ifndef ASDCP_WITHOUT_OPENSSL - byte_t xor_buf[KeyLen]; - memset(sha_value, 0, HMAC_SIZE); + 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)) // ^^^^^^^^^^ - for ( ui32_t i = 0; i < KeyLen; i++ ) - xor_buf[i] = m_key[i] ^ ipad[i]; + for ( ui32_t i = 0; i < B_len; i++ ) + xor_buf[i] ^= ipad[i]; - SHA1_Update(&m_SHA, xor_buf, KeyLen); -#endif // ASDCP_WITHOUT_OPENSSL + SHA1_Update(&m_SHA, xor_buf, B_len); } // void Update(const byte_t* buf, ui32_t buf_len) { -#ifndef ASDCP_WITHOUT_OPENSSL // H(K XOR opad, H(K XOR ipad, text)) // ^^^^ SHA1_Update(&m_SHA, buf, buf_len); -#endif // ASDCP_WITHOUT_OPENSSL } // void Finalize() { -#ifndef ASDCP_WITHOUT_OPENSSL - // H(K XOR opad, H(K XOR ipad, text)) - // ^^^^^^^^^^^^^^^ - SHA1_Final(sha_value, &m_SHA); - SHA_CTX SHA; SHA1_Init(&SHA); - byte_t xor_buf[KeyLen]; + byte_t xor_buf[B_len]; + 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); - for ( ui32_t i = 0; i < KeyLen; i++ ) - xor_buf[i] = m_key[i] ^ opad[i]; - - SHA1_Update(&SHA, xor_buf, KeyLen); - SHA1_Update(&SHA, sha_value, HMAC_SIZE); + // H(K XOR opad, H(K XOR ipad, text)) + // ^ + SHA1_Final(m_SHAValue, &m_SHA); + SHA1_Update(&SHA, m_SHAValue, HMAC_SIZE); - SHA1_Final(sha_value, &SHA); + // H(K XOR opad, H(K XOR ipad, text)) + // ^ + SHA1_Final(m_SHAValue, &SHA); m_Final = true; -#endif // ASDCP_WITHOUT_OPENSSL } }; @@ -384,12 +378,21 @@ HMACContext::~HMACContext() // Result_t -HMACContext::InitKey(const byte_t* key) +HMACContext::InitKey(const byte_t* key, LabelSet_t SetType) { - ASDCP_TEST_NULL(key); + KM_TEST_NULL_L(key); m_Context = new h__HMACContext; - m_Context->SetKey(key); + + switch ( SetType ) + { + case LS_MXF_INTEROP: m_Context->SetInteropKey(key); break; + case LS_MXF_SMPTE: m_Context->SetKey(key); break; + default: + m_Context = 0; + return RESULT_INIT; + } + return RESULT_OK; } @@ -407,7 +410,7 @@ HMACContext::Reset() Result_t HMACContext::Update(const byte_t* buf, ui32_t buf_len) { - ASDCP_TEST_NULL(buf); + KM_TEST_NULL_L(buf); if ( m_Context.empty() || m_Context->m_Final ) return RESULT_INIT; @@ -433,12 +436,12 @@ HMACContext::Finalize() Result_t HMACContext::GetHMACValue(byte_t* buf) const { - ASDCP_TEST_NULL(buf); + KM_TEST_NULL_L(buf); if ( m_Context.empty() || ! m_Context->m_Final ) return RESULT_INIT; - memcpy(buf, m_Context->sha_value, HMAC_SIZE); + memcpy(buf, m_Context->m_SHAValue, HMAC_SIZE); return RESULT_OK; } @@ -447,12 +450,12 @@ HMACContext::GetHMACValue(byte_t* buf) const Result_t HMACContext::TestHMACValue(const byte_t* buf) const { - ASDCP_TEST_NULL(buf); + KM_TEST_NULL_L(buf); if ( m_Context.empty() || ! m_Context->m_Final ) return RESULT_INIT; - return ( memcmp(buf, m_Context->sha_value, HMAC_SIZE) == 0 ) ? RESULT_OK : RESULT_HMACFAIL; + return ( memcmp(buf, m_Context->m_SHAValue, HMAC_SIZE) == 0 ) ? RESULT_OK : RESULT_HMACFAIL; }