Install additional header file.
[asdcplib.git] / src / AS_DCP_AES.cpp
index 037e68d58fb509d368042d96d3d18d12cb46c397..dbaa3d541d383c4c7e43a514a8a15c75e7f5840e 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2006, John Hurst
+Copyright (c) 2004-2007, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assert.h>
 #include <AS_DCP.h>
 #include <KM_log.h>
+#include <KM_prng.h>
 using Kumu::DefaultLogSink;
 
 using namespace ASDCP;
@@ -43,14 +44,6 @@ const int KEY_SIZE_BITS = 128;
 #include <openssl/bn.h>
 #include <openssl/err.h>
 
-#if OPENSSL_VERSION_NUMBER < 0x0090804f
-# error OpenSSL version mismatch
-#endif
-
-#ifndef OPENSSL_VERSION_NUMBER
-#error OPENSSL_VERSION_NUMBER not defined
-#endif
-
 
 void
 print_ssl_error()
@@ -246,22 +239,31 @@ 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 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
 {
   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() {}
@@ -269,67 +271,9 @@ 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);
-
-    // 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);
+    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);
     Reset();
   }
 
@@ -347,24 +291,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[i];
 
-    SHA1_Update(&m_SHA, xor_buf, KeyLen);
+    SHA1_Update(&m_SHA, xor_buf, B_len);
   }
 
   //
@@ -380,22 +327,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);
+
+    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;
   }
 };
@@ -475,7 +430,7 @@ HMACContext::GetHMACValue(byte_t* buf) const
   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;
 }
 
@@ -489,7 +444,7 @@ HMACContext::TestHMACValue(const byte_t* buf) const
   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;
 }