X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FAS_DCP_AES.cpp;h=379e8abe9e42deead11e1726f7603ecf3d3ccaf9;hb=9e269bd45830f54551722a65b0d7aa8f327e17dc;hp=fc10425a7d820e2d7bc5906c4a08d70f8b3b1184;hpb=bfedf725dac9d13f3a02fe69f45c302ab29d2b1e;p=asdcplib.git diff --git a/src/AS_DCP_AES.cpp b/src/AS_DCP_AES.cpp index fc10425..379e8ab 100755 --- a/src/AS_DCP_AES.cpp +++ b/src/AS_DCP_AES.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2006, John Hurst +Copyright (c) 2004-2009, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -33,17 +33,18 @@ 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; - #include #include #include #include + void print_ssl_error() { @@ -57,6 +58,7 @@ print_ssl_error() class ASDCP::AESEncContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -69,14 +71,15 @@ 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; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_encrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_encrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; @@ -92,7 +95,7 @@ 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; @@ -107,7 +110,7 @@ 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; @@ -122,8 +125,8 @@ 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 ); @@ -158,6 +161,7 @@ ASDCP::AESEncContext::EncryptBlock(const byte_t* pt_buf, byte_t* ct_buf, ui32_t class ASDCP::AESDecContext::h__AESContext : public AES_KEY { public: + Kumu::SymmetricKey m_KeyBuf; byte_t m_IVec[CBC_BLOCK_SIZE]; }; @@ -170,14 +174,15 @@ 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; m_Context = new h__AESContext; + m_Context->m_KeyBuf.Set(key); - if ( AES_set_decrypt_key(key, KEY_SIZE_BITS, m_Context) ) + if ( AES_set_decrypt_key(m_Context->m_KeyBuf.Value(), KEY_SIZE_BITS, m_Context) ) { print_ssl_error(); return RESULT_CRYPT_INIT; @@ -192,7 +197,7 @@ 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; @@ -206,8 +211,8 @@ 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 ); @@ -238,22 +243,20 @@ ASDCP::AESDecContext::DecryptBlock(const byte_t* ct_buf, byte_t* pt_buf, ui32_t //------------------------------------------------------------------------------------------ +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 opad[KeyLen] = { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c }; +static byte_t const ipad_const = 0x36; +static byte_t const opad_const = 0x5c; class HMACContext::h__HMACContext { SHA_CTX m_SHA; - 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() {} @@ -261,67 +264,12 @@ public: // SMPTE 429.6 MIC key generation void SetKey(const byte_t* key) { - // FIPS 186-2 Sec. 3.1 as modified by Change 1, section entitled "General Purpose Random Number Generation" - // - - static byte_t t[SHA_DIGEST_LENGTH] = { - 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, - 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, - 0xc3, 0xd2, 0xe1, 0xf0 - }; - - byte_t sha_buf0[SHA_DIGEST_LENGTH]; - byte_t sha_buf1[SHA_DIGEST_LENGTH]; - SHA_CTX SHA; - BN_CTX* ctx1 = BN_CTX_new(); // used by BN_* functions - assert(ctx1); - - // create the 2^160 constant - BIGNUM c_2powb, c_2, c_160; - BN_init(&c_2powb); BN_init(&c_2); BN_init(&c_160); - BN_set_word(&c_2, 2); - BN_set_word(&c_160, 160); - BN_exp(&c_2powb, &c_2, &c_160, ctx1); - - // ROUND 1 - // step a -- SMPTE 429.6 sets XSEED = 0, so no need to do anything for this step - // step b -- (key mod 2^160) is moot because the input value is only 128 bits in length - - // step c -- x = G(t,xkey) - SHA1_Init(&SHA); - SHA1_Update(&SHA, t, SHA_DIGEST_LENGTH); - SHA1_Update(&SHA, key, KeyLen); - SHA1_Final(sha_buf0, &SHA); - - // step d ... - BIGNUM xkey1, xkey2, x0; - BN_init(&xkey1); BN_init(&xkey2); BN_init(&x0); - - BN_bin2bn(key, KeyLen, &xkey1); - BN_bin2bn(sha_buf0, SHA_DIGEST_LENGTH, &x0); - BN_add_word(&xkey1, 1); // xkey += 1 - BN_add(&xkey2, &xkey1, &x0); // xkey += x - BN_mod(&xkey1, &xkey2, &c_2powb, ctx1); // xkey = xkey mod (2^160) - - // ROUND 2 - // step a -- SMPTE 429.6 sets XSEED = 0, so no need to do anything for this step - // step b -- (key mod 2^160) is moot because xkey1 is the result of the same operation - - byte_t bin_buf[SHA_DIGEST_LENGTH+1]; // we need xkey1 in bin form for use by SHA1_Update - ui32_t bin_buf_len = BN_num_bytes(&xkey1); - assert(bin_buf_len < SHA_DIGEST_LENGTH+1); - BN_bn2bin(&xkey1, bin_buf); + byte_t rng_buf[SHA_DIGEST_LENGTH*2]; + Kumu::Gen_FIPS_186_Value(key, KeyLen, rng_buf, SHA_DIGEST_LENGTH*2); - // step c -- x = G(t,xkey) - SHA1_Init(&SHA); - SHA1_Update(&SHA, t, SHA_DIGEST_LENGTH); - SHA1_Update(&SHA, bin_buf, bin_buf_len); - SHA1_Final(sha_buf1, &SHA); - - assert(memcmp(sha_buf1, sha_buf0, SHA_DIGEST_LENGTH) != 0); // are x0 and x1 different? - - BN_CTX_free(ctx1); - memcpy(m_key, sha_buf1, KeyLen); + // 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(); } @@ -339,24 +287,27 @@ public: SHA1_Update(&SHA, key_nonce, KeyLen); SHA1_Final(sha_buf, &SHA); memcpy(m_key, sha_buf, KeyLen); - Reset(); } + // void Reset() { - 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_const; - SHA1_Update(&m_SHA, xor_buf, KeyLen); + SHA1_Update(&m_SHA, xor_buf, B_len); } // @@ -372,22 +323,30 @@ public: void Finalize() { - // 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); - 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); + 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_const; + + SHA1_Update(&SHA, xor_buf, B_len); - SHA1_Final(sha_value, &SHA); + // 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; } }; @@ -406,7 +365,7 @@ HMACContext::~HMACContext() Result_t HMACContext::InitKey(const byte_t* key, LabelSet_t SetType) { - ASDCP_TEST_NULL(key); + KM_TEST_NULL_L(key); m_Context = new h__HMACContext; @@ -436,7 +395,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; @@ -462,12 +421,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; } @@ -476,12 +435,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; }