diff options
| author | jhurst <jhurst@cinecert.com> | 2007-02-15 06:07:32 +0000 |
|---|---|---|
| committer | jhurst <> | 2007-02-15 06:07:32 +0000 |
| commit | 7470b55c9d987d8a6d4b47bb1925c4e6eaa80afe (patch) | |
| tree | cffc1d85ef40985c7a8215d30ae6b96ccc9ae440 /src | |
| parent | 2d0f4af2b7815eed9bdc1292f9059025eb2380d7 (diff) | |
final fixes to 429-6 HMAC
Diffstat (limited to 'src')
| -rwxr-xr-x | src/AS_DCP_AES.cpp | 75 | ||||
| -rwxr-xr-x | src/KM_prng.cpp | 65 | ||||
| -rwxr-xr-x | src/KM_prng.h | 3 | ||||
| -rwxr-xr-x | src/fips-186-rng-test.cpp | 2 |
4 files changed, 72 insertions, 73 deletions
diff --git a/src/AS_DCP_AES.cpp b/src/AS_DCP_AES.cpp index 037e68d..1146bb7 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-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() @@ -269,67 +262,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(); } diff --git a/src/KM_prng.cpp b/src/KM_prng.cpp index e710d9a..65c4656 100755 --- a/src/KM_prng.cpp +++ b/src/KM_prng.cpp @@ -36,6 +36,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assert.h> #include <openssl/aes.h> #include <openssl/sha.h> +#include <openssl/bn.h> using namespace Kumu; @@ -146,7 +147,7 @@ static h__RNG* s_RNG = 0; //------------------------------------------------------------------------------------------ // -// public interface +// Fortuna public interface Kumu::FortunaRNG::FortunaRNG() { @@ -190,6 +191,68 @@ Kumu::FortunaRNG::FillRandom(Kumu::ByteString& Buffer) return Buffer.Data(); } +//------------------------------------------------------------------------------------------ + +// +// FIPS 186-2 Sec. 3.1 as modified by Change 1, section entitled "General Purpose Random Number Generation" +void +Kumu::Gen_FIPS_186_Value(const byte_t* key, ui32_t key_size, byte_t* out_buf, ui32_t out_buf_len) +{ + byte_t sha_buf[SHA_DIGEST_LENGTH]; + const ui32_t key_buf_len = 64; + byte_t key_buf[key_buf_len]; + SHA_CTX SHA; + BN_CTX* ctx1 = BN_CTX_new(); // used by BN_* functions + assert(ctx1); + + // init key + memset(key_buf, 0, key_buf_len); + memcpy(key_buf, key, xmin<ui32_t>(key_buf_len, key_size)); + + // 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); + + for (;;) + { + // step c -- x = G(t,xkey) + SHA1_Init(&SHA); + SHA1_Update(&SHA, key_buf, key_buf_len); + ui32_t* buf_p = (ui32_t*)sha_buf; + *buf_p++ = KM_i32_BE(SHA.h0); + *buf_p++ = KM_i32_BE(SHA.h1); + *buf_p++ = KM_i32_BE(SHA.h2); + *buf_p++ = KM_i32_BE(SHA.h3); + *buf_p++ = KM_i32_BE(SHA.h4); + memcpy(out_buf, sha_buf, xmin<ui32_t>(out_buf_len, SHA_DIGEST_LENGTH)); + + if ( out_buf_len <= SHA_DIGEST_LENGTH ) + break; + + out_buf_len -= SHA_DIGEST_LENGTH; + out_buf += SHA_DIGEST_LENGTH; + + // step d ... + BIGNUM xkey1, xkey_buf, x0; + BN_init(&xkey1); BN_init(&xkey_buf); BN_init(&x0); + + BN_bin2bn(key_buf, SHA_DIGEST_LENGTH, &xkey1); + BN_bin2bn(sha_buf, SHA_DIGEST_LENGTH, &x0); + BN_add_word(&xkey1, 1); // xkey += 1 + BN_add(&xkey_buf, &xkey1, &x0); // xkey += x + BN_mod(&xkey1, &xkey_buf, &c_2powb, ctx1); // xkey = xkey mod (2^160) + + ui32_t bn_buf_len = BN_num_bytes(&xkey1); + assert(bn_buf_len < SHA_DIGEST_LENGTH+1); + memset(key_buf, 0, key_buf_len); + BN_bn2bin(&xkey1, key_buf); + } + + BN_CTX_free(ctx1); +} // // end KM_prng.cpp diff --git a/src/KM_prng.h b/src/KM_prng.h index e718475..b592988 100755 --- a/src/KM_prng.h +++ b/src/KM_prng.h @@ -48,7 +48,8 @@ namespace Kumu }; - void Gen_FIPS_186_Value(const byte_t* key_in /* 20 bytes */, byte_t* r_out /* 40 bytes */); + // key_len must be <= 64 (larger values will be truncated) + void Gen_FIPS_186_Value(const byte_t* key_in, ui32_t key_len, byte_t* buf, ui32_t buf_len); } // namespace Kumu diff --git a/src/fips-186-rng-test.cpp b/src/fips-186-rng-test.cpp index c26239b..887345a 100755 --- a/src/fips-186-rng-test.cpp +++ b/src/fips-186-rng-test.cpp @@ -74,7 +74,7 @@ main(int argc, const char** argv) return 3; } - Gen_FIPS_186_Value(XKey_buf, X_buf); + Gen_FIPS_186_Value(XKey_buf, SHA_DIGEST_LENGTH, X_buf, SHA_DIGEST_LENGTH*2); if ( memcmp(X_buf, X_test_buf, SHA_DIGEST_LENGTH*2) != 0 ) { |
